【问题标题】:Update Product Features via PHP in Prestashop在 Prestashop 中通过 PHP 更新产品功能
【发布时间】:2015-07-01 05:24:58
【问题描述】:

我想在我自己的课程中更改自定义功能(产品功能)(Artikeleigenschaften)的值。

更改产品值非常简单:

$productObj = new Product($produktId);
$productObj->setFieldsToUpdate(array('ean13'));
$productObj->ean13 = "johndoo";
$productObj->save();

但是有没有类似的方法来改变产品特性?

【问题讨论】:

    标签: php prestashop product


    【解决方案1】:

    这些建议都不适合我。我对此没有什么要求:

    1. 导入应该能够多次运行,而不会在产品或功能值列表中复制功能
    2. 不应删除自定义值,即使它们具有相同的“大小”特征
    3. 无需处理语言或多商店(感谢数据源仅支持一种语言和一个商店)

    这对我有用

        /**
         * Add or customize feature value to product feature and assign it to product
         *
         * Creates the feature and the value if they dont exists already
         */
        private function _upsertFeatureValueToProduct($product, $featureName, $featureValue, $custom = false)
        {
            $id_lang = null;
    
            // this creates the feature if required and always returns the id_feature
            $id_feature = (int) \Feature::addFeatureImport($featureName);
    
            if ($custom) {
                // create or find a custom value
                $id_feature_value = (int) \FeatureValue::addFeatureValueImport($id_feature, $featureValue, $product->id, $id_lang, $custom);
                // change the existing value to new
                $feature_value = new \FeatureValue($id_feature_value);
                // in all languages (source only gives one language data)
                $feature_value->value = array_fill_keys(\Language::getIDs(false), $featureValue);
                $feature_value->update();
                // assign the feature to the product (not strictly required if this was a update but doesn't hurt)
                Product::addFeatureProductImport($product->id, $id_feature, $id_feature_value);
            } else {
                // non custom values. we first need to add the value and then assign it
                // prestashop uses lang to find the existing feature. use the default language
                $id_lang = \Configuration::get('PS_LANG_DEFAULT');
    
                // add or get the feature id for this value
                $id_feature_value = (int) \FeatureValue::addFeatureValueImport($id_feature, $featureValue, null, $id_lang, $custom);
    
                // NOTE: product can have the same feature multiple times. But in this case we only get one value from source and want to update the feature
                // so before adding the featurevalue delete existing feature assignments
                $this->_deleteProductFeatureValueAssignments($product->id, $id_feature);
    
                // assign the feature to the product
                Product::addFeatureProductImport($product->id, $id_feature, $id_feature_value);
            }
            // required? doesn't hurt :)
            \Feature::cleanPositions();
        }
    
        /**
         * Delete product feature value assingments
         *
         * There is no api for this.. idea stolen from
         *
    https://github.com/PrestaShop/PrestaShop/blob/2c059b93062ce25bbde22355982e651215544e81/classes/Product.php#L2673
         *
         * TODO: open feature request, and remove this when prestashop has an api for this.
         */
        private function _deleteProductFeatureValueAssignments($id_product, $id_feature)
        {
            $sql = '
            DELETE fp
            FROM `' . _DB_PREFIX_ . 'feature_product` fp
            LEFT JOIN `' . _DB_PREFIX_ . 'feature_value` fv
                ON fv.`id_feature_value` = fp.`id_feature_value`
            WHERE
                fp.`id_product` = ' . (int) $id_product .
                ' AND fp.`id_feature` = ' . (int) $id_feature .
                ' AND `custom`=0
            ';
    
            return \Db::getInstance()->execute($sql);
        }
    

    现在我可以整天调用它,而不会在功能或产品中得到重复值

    $this->_upsertFeatureValueToProduct($product, 'size', 'L');
    $this->_upsertFeatureValueToProduct($product, 'size', 'XL');
    $this->_upsertFeatureValueToProduct($product, 'size', 'custom', true); // one custom size just for fun
    $this->_upsertFeatureValueToProduct($product, 'size', 'L');
    
    

    留给我两个现成的特征值LXL 以及一个size=L 和size=custom 的产品

    screenshot of product features

    可能仍然存在错误,只是让这个工作正常:D

    【讨论】:

      【解决方案2】:
      Product::addFeatureProductImport($productObjc->id, $id_feature, $id_feature_value); 
      

      这会将功能及其价值分配给产品。但是我们需要特征和值的 id。下面的代码对我有用。

        $feature = new Feature();
                  $feature->name = [
                      $lang_id => "string"
                  ];
                  $feature->position = Feature::getHigherPosition() + 1;
                  $feature->add();
                  $featurevalue = new FeatureValue;
                  $featurevalue->id_feature = $feature->id;
                  $featurevalue->value = [
                      $lang_id => "string"
                 ];
                  $featurevalue->add();
      $product->addFeatureProductImport($product->id, $feature->id, $featurevalue->id);
      

      【讨论】:

        【解决方案3】:

        我基于 ImportControlloer 创建了这个函数。将此函数添加到 Product.php 覆盖并使用它

         /**
         * Adds a feature value to a Product. If You want to have feature selected from dropdown leave $custom to false.
         * @param int|$id_product
         * @param int|$id_feature_group
         * @param string|$feature_value
         * @param bool|true $custom
         * @param int|$id_lang
         * @return bool
         */
        public static function setFeatureValueToProduct($id_product, $id_feature_group, $feature_value, $custom = false, $id_lang)
        {
            $group_feature_obj = Feature::getFeature($id_lang, $id_feature_group);
        
            if ($group_feature_obj){
                $feature_name = $group_feature_obj['name'];
                $feature_value = $feature_value ? trim($feature_value) : '';
                $position = false;
        
                if (!empty($feature_name) && !empty($feature_value)) {
                    $id_feature = (int)FeatureCore::addFeatureImport($feature_name, $position);
        
                    $id_feature_value = (int)FeatureValue::addFeatureValueImport($id_feature, $feature_value, $id_product, $id_lang, $custom);
                    if (Product::addFeatureProductImport($id_product, $id_feature, $id_feature_value)){
                        Feature::cleanPositions();
                        return true;
                    } else {
                        return;
                    }
                }
            } else {
                return;
            }
        }
        

        使用示例:

        Product::setFeatureValue(1597, 15,  'Dracarys', false, 1); 
        

        它将下拉值“Dracarys”上传到 ID 为 1597 的产品和 ID 为 15 的组功能中。如果您想使其自定义值(未预定义),只需将第 4 个参数设置为 true。

        

        【讨论】:

          【解决方案4】:

          这是我的解决方案: 要更新产品功能,您必须更新数据库中的 2 个表: ps_feature_valueps_feature_value_lang

          这样做:

          $id_feature_value = (int)FeatureValue::addFeatureValueImport
          ( 
            (int)$feature['id_feature'],
            $newFeatureValue,
            (int)$produktId,
            $this->context->language->id,
            1 // $custom
          );
          Product::addFeatureProductImport(
              $produktId, (int)$feature['id_feature'], $id_feature_value
          );
          

          要使用非自定义值更新功能,请使用:

          $arr = FeatureValue::getFeatureValueLang($id_dropdown);
          foreach ( $arr AS $item)
              if ($item['id_lang'] == $this->context->language->id)
              {
                  $feature_val_name = $item['value'] ;
              }
          
          $id_feature_value = (int)FeatureValue::addFeatureValueImport
          ( 
             (int)$feature['id_feature'],
             $feature_val_name,
             $product->id,
             $this->context->language->id, 
             false 
          );
          $product->addFeatureProductImport( $product->id , (int)$feature['id_feature'], $id_feature_value );
          

          【讨论】:

            【解决方案5】:

            嗯,我从来没有尝试过这样做,但你可以试试这个:

            Product::addFeatureProductImport($productObjc->id, $id_feature, $id_feature_value); 
            

            【讨论】:

            • 这是解决方案的一部分。正如我再次回答的那样,您也必须使用FeatureValue::addFeatureValueImport()
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2014-09-12
            • 2014-01-17
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多