这些建议都不适合我。我对此没有什么要求:
- 导入应该能够多次运行,而不会在产品或功能值列表中复制功能
- 不应删除自定义值,即使它们具有相同的“大小”特征
- 无需处理语言或多商店(感谢数据源仅支持一种语言和一个商店)
这对我有用
/**
* 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');
留给我两个现成的特征值L 和XL 以及一个size=L 和size=custom 的产品
screenshot of product features
可能仍然存在错误,只是让这个工作正常:D