Magento1.9.3.3 可配置产品样本错误
Magento1.9.3.3 Configurable Product Swatch bug
我们刚刚将网站从 Magento 1.9.1.1 升级到 Magento 1.9.3.3。
不幸的是,我们的网站坏了,所以我调查了这个问题。
错误通知如下。
Fatal error: Uncaught Error: Call to undefined method
Mage_ConfigurableSwatches_Helper_Mediafallback::attachProductChildrenAttributeMapping() 在
/var/www/html/source/app/code/core/Mage/ConfigurableSwatches/Model/Observer.php:59 堆栈跟踪:#0 /var/www/html/source/app/code/core/Mage/Core/Model/App.php(1358): Mage_ConfigurableSwatches_Model_Observer-productListCollectionLoadAfter(对象(Varien_Event_Observer)) #1 /var/www/html/source/app/code/core/Mage/Core/Model/App.php(1337): Mage_Core_Model_App-_callObserverMethod(对象(Mage_ConfigurableSwatches_Model_Observer), 'productListColl...', 对象(Varien_Event_Observer)) #2 /var/www/html/source/app/Mage.php(448): Mage_Core_Model_App-dispatchEvent('catalog_block_p...', 数组) #3 /var/www/html/source/app/code/core/Mage/Catalog/Block/Product/List.php(160): Mage::dispatchEvent('catalog_block_p...', Array) #4 /var/www/html/source/app/code/core/Mage/Core/Block/Abstract.php(922): Mage_Catalog_Block_Product_Li in
/var/www/html/source/app/code/core/Mage/ConfigurableSwatches/Model/Observer.php 第 59 行
该代码块如下
public function productListCollectionLoadAfter(Varien_Event_Observer $observer)
{
if (!Mage::helper('configurableswatches')->isEnabled()) { // check if functionality disabled
return; // exit without loading swatch functionality
}
/* @var $mediaHelper Mage_ConfigurableSwatches_Helper_Mediafallback */
$mediaHelper = Mage::helper('configurableswatches/mediafallback');
/** @var $priceHelper Mage_ConfigurableSwatches_Helper_List_Price */
$priceHelper = Mage::helper('configurableswatches/list_price');
/* @var $collection Mage_Catalog_Model_Resource_Product_Collection */
$collection = $observer->getCollection();
if ($collection
instanceof Mage_ConfigurableSwatches_Model_Resource_Catalog_Product_Type_Configurable_Product_Collection) {
// avoid recursion
return;
}
$products = $collection->getItems();
$mediaHelper->attachChildrenProducts($products, $collection->getStoreId());
$mediaHelper->attachProductChildrenAttributeMapping($products, $collection->getStoreId());
if ($priceHelper->isEnabled()) {
$priceHelper->attachConfigurableProductChildrenPricesMapping($products, $collection->getStoreId());
}
$mediaHelper->attachGallerySetToCollection($products, $collection->getStoreId());
/* @var $product Mage_Catalog_Model_Product */
foreach ($products as $product) {
$mediaHelper->groupMediaGalleryImages($product);
Mage::helper('configurableswatches/productimg')
->indexProductImages($product, $product->getListSwatchAttrValues());
}
}
老版块(Magento1.9.1.0)在后面。
public function productListCollectionLoadAfter(Varien_Event_Observer $observer)
{
if (!Mage::helper('configurableswatches')->isEnabled()) { // check if functionality disabled
return; // exit without loading swatch functionality
}
/* @var $helper Mage_ConfigurableSwatches_Helper_Mediafallback */
$helper = Mage::helper('configurableswatches/mediafallback');
/* @var $collection Mage_Catalog_Model_Resource_Product_Collection */
$collection = $observer->getCollection();
if ($collection
instanceof Mage_ConfigurableSwatches_Model_Resource_Catalog_Product_Type_Configurable_Product_Collection) {
// avoid recursion
return;
}
$products = $collection->getItems();
$helper->attachChildrenProducts($products, $collection->getStoreId());
$helper->attachConfigurableProductChildrenAttributeMapping($products, $collection->getStoreId());
$helper->attachGallerySetToCollection($products, $collection->getStoreId());
/* @var $product Mage_Catalog_Model_Product */
foreach ($products as $product) {
$helper->groupMediaGalleryImages($product);
Mage::helper('configurableswatches/productimg')
->indexProductImages($product, $product->getListSwatchAttrValues());
}
}
为了解决网站损坏的问题,我在 System/Catalog/Configurable Swatches/General 设置中禁用了色样设置。
然后,我们的网站被检索了。但是,当然,颜色样本功能不再起作用了。
为了确定这个问题是否是核心错误,我在本地服务器上安装了原始的 Magento 1.9.3.3。但是,同样的问题。
有什么解决办法吗?
在 catalog.xml 文件的 catalog_product_view 部分添加 js
<action method="addJs"><script>varien/product_options.js</script></action>
为了解决这个问题,我们检查了整个自定义模块。
app\code\local\Mage\ConfigurableSwatches\Helper\Mediafallback.php
旧开发人员创建了这个自定义模块,因此新版 Magento 的 Mediafallback.php 无法正常工作。
这是正确的原始核心 php 文件。
app\code\core\Mage\ConfigurableSwatches\Helper\Mediafallback.php
public function attachProductChildrenAttributeMapping(array $parentProducts, $storeId, $onlyListAttributes = false)
{
/** @var $listSwatchAttr Mage_Eav_Model_Attribute */
$listSwatchAttr = Mage::helper('configurableswatches/productlist')->getSwatchAttribute();
$swatchAttributeIds = array();
if (!$onlyListAttributes) {
$swatchAttributeIds = Mage::helper('configurableswatches')->getSwatchAttributeIds();
}
if ($listSwatchAttr->getId()) {
$swatchAttributeIds[] = $listSwatchAttr->getId();
}
if (empty($swatchAttributeIds)) {
return;
}
$parentProductIds = array();
/* @var $parentProduct Mage_Catalog_Model_Product */
foreach ($parentProducts as $parentProduct) {
$parentProductIds[] = $parentProduct->getId();
}
$configAttributes = Mage::getResourceModel('configurableswatches/catalog_product_attribute_super_collection')
->addParentProductsFilter($parentProductIds)
->attachEavAttributes()
->addFieldToFilter('eav_attributes.attribute_id', array('in' => $swatchAttributeIds))
->setStoreId($storeId)
;
$optionLabels = array();
foreach ($configAttributes as $attribute) {
$optionLabels += $attribute->getOptionLabels();
}
// normalize to all lower case before we start using them
$optionLabels = array_map(function ($value) {
return array_map('Mage_ConfigurableSwatches_Helper_Data::normalizeKey', $value);
}, $optionLabels);
foreach ($parentProducts as $parentProduct) {
$mapping = array();
$listSwatchValues = array();
$listSwatchStockValues = array();
/* @var $attribute Mage_Catalog_Model_Product_Type_Configurable_Attribute */
foreach ($configAttributes as $attribute) {
/* @var $childProduct Mage_Catalog_Model_Product */
if (!is_array($parentProduct->getChildrenProducts())) {
continue;
}
foreach ($parentProduct->getChildrenProducts() as $childProduct) {
// product has no value for attribute or not available, we can't process it
$isInStock = $childProduct->getStockItem()->getIsInStock();
if (!$childProduct->hasData($attribute->getAttributeCode())
|| (!$isInStock && !Mage::helper('cataloginventory')->isShowOutOfStock())) {
continue;
}
$optionId = $childProduct->getData($attribute->getAttributeCode());
// if we don't have a default label, skip it
if (!isset($optionLabels[$optionId][0])) {
continue;
}
// using default value as key unless store-specific label is present
$optionLabel = $optionLabels[$optionId][0];
if (isset($optionLabels[$optionId][$storeId])) {
$optionLabel = $optionLabels[$optionId][$storeId];
}
// initialize arrays if not present
if (!isset($mapping[$optionLabel])) {
$mapping[$optionLabel] = array(
'product_ids' => array(),
);
}
$mapping[$optionLabel]['product_ids'][] = $childProduct->getId();
$mapping[$optionLabel]['label'] = $optionLabel;
$mapping[$optionLabel]['default_label'] = $optionLabels[$optionId][0];
$mapping[$optionLabel]['labels'] = $optionLabels[$optionId];
if ($attribute->getAttributeId() == $listSwatchAttr->getAttributeId()
&& !in_array($mapping[$optionLabel]['label'], $listSwatchValues)
) {
$listSwatchValues[$optionId] = $mapping[$optionLabel]['label'];
$listSwatchStockValues[$optionId] = $isInStock;
}
} // end looping child products
} // end looping attributes
foreach ($mapping as $key => $value) {
$mapping[$key]['product_ids'] = array_unique($mapping[$key]['product_ids']);
}
if (count($listSwatchValues)) {
$listSwatchValues = array_replace(array_intersect_key($optionLabels, $listSwatchValues),
$listSwatchValues);
}
$parentProduct->setChildAttributeLabelMapping($mapping)
->setListSwatchAttrValues($listSwatchValues)
->setListSwatchAttrStockValues($listSwatchStockValues);
} // end looping parent products
}
此外,这些文章可能对我们的解决方案有所帮助。
https://magento.stackexchange.com/questions/45948/how-to-use-magento-1-9-1-0-configurable-swatches-in-default-package-theme-or-a
https://magento.stackexchange.com/questions/142404/configurable-swatches-not-working-after-1-9-3-upgrade
我们刚刚将网站从 Magento 1.9.1.1 升级到 Magento 1.9.3.3。
不幸的是,我们的网站坏了,所以我调查了这个问题。 错误通知如下。
Fatal error: Uncaught Error: Call to undefined method
Mage_ConfigurableSwatches_Helper_Mediafallback::attachProductChildrenAttributeMapping() 在 /var/www/html/source/app/code/core/Mage/ConfigurableSwatches/Model/Observer.php:59 堆栈跟踪:#0 /var/www/html/source/app/code/core/Mage/Core/Model/App.php(1358): Mage_ConfigurableSwatches_Model_Observer-productListCollectionLoadAfter(对象(Varien_Event_Observer)) #1 /var/www/html/source/app/code/core/Mage/Core/Model/App.php(1337): Mage_Core_Model_App-_callObserverMethod(对象(Mage_ConfigurableSwatches_Model_Observer), 'productListColl...', 对象(Varien_Event_Observer)) #2 /var/www/html/source/app/Mage.php(448): Mage_Core_Model_App-dispatchEvent('catalog_block_p...', 数组) #3 /var/www/html/source/app/code/core/Mage/Catalog/Block/Product/List.php(160): Mage::dispatchEvent('catalog_block_p...', Array) #4 /var/www/html/source/app/code/core/Mage/Core/Block/Abstract.php(922): Mage_Catalog_Block_Product_Li in /var/www/html/source/app/code/core/Mage/ConfigurableSwatches/Model/Observer.php 第 59 行
该代码块如下
public function productListCollectionLoadAfter(Varien_Event_Observer $observer)
{
if (!Mage::helper('configurableswatches')->isEnabled()) { // check if functionality disabled
return; // exit without loading swatch functionality
}
/* @var $mediaHelper Mage_ConfigurableSwatches_Helper_Mediafallback */
$mediaHelper = Mage::helper('configurableswatches/mediafallback');
/** @var $priceHelper Mage_ConfigurableSwatches_Helper_List_Price */
$priceHelper = Mage::helper('configurableswatches/list_price');
/* @var $collection Mage_Catalog_Model_Resource_Product_Collection */
$collection = $observer->getCollection();
if ($collection
instanceof Mage_ConfigurableSwatches_Model_Resource_Catalog_Product_Type_Configurable_Product_Collection) {
// avoid recursion
return;
}
$products = $collection->getItems();
$mediaHelper->attachChildrenProducts($products, $collection->getStoreId());
$mediaHelper->attachProductChildrenAttributeMapping($products, $collection->getStoreId());
if ($priceHelper->isEnabled()) {
$priceHelper->attachConfigurableProductChildrenPricesMapping($products, $collection->getStoreId());
}
$mediaHelper->attachGallerySetToCollection($products, $collection->getStoreId());
/* @var $product Mage_Catalog_Model_Product */
foreach ($products as $product) {
$mediaHelper->groupMediaGalleryImages($product);
Mage::helper('configurableswatches/productimg')
->indexProductImages($product, $product->getListSwatchAttrValues());
}
}
老版块(Magento1.9.1.0)在后面。
public function productListCollectionLoadAfter(Varien_Event_Observer $observer)
{
if (!Mage::helper('configurableswatches')->isEnabled()) { // check if functionality disabled
return; // exit without loading swatch functionality
}
/* @var $helper Mage_ConfigurableSwatches_Helper_Mediafallback */
$helper = Mage::helper('configurableswatches/mediafallback');
/* @var $collection Mage_Catalog_Model_Resource_Product_Collection */
$collection = $observer->getCollection();
if ($collection
instanceof Mage_ConfigurableSwatches_Model_Resource_Catalog_Product_Type_Configurable_Product_Collection) {
// avoid recursion
return;
}
$products = $collection->getItems();
$helper->attachChildrenProducts($products, $collection->getStoreId());
$helper->attachConfigurableProductChildrenAttributeMapping($products, $collection->getStoreId());
$helper->attachGallerySetToCollection($products, $collection->getStoreId());
/* @var $product Mage_Catalog_Model_Product */
foreach ($products as $product) {
$helper->groupMediaGalleryImages($product);
Mage::helper('configurableswatches/productimg')
->indexProductImages($product, $product->getListSwatchAttrValues());
}
}
为了解决网站损坏的问题,我在 System/Catalog/Configurable Swatches/General 设置中禁用了色样设置。
然后,我们的网站被检索了。但是,当然,颜色样本功能不再起作用了。
为了确定这个问题是否是核心错误,我在本地服务器上安装了原始的 Magento 1.9.3.3。但是,同样的问题。
有什么解决办法吗?
在 catalog.xml 文件的 catalog_product_view 部分添加 js
<action method="addJs"><script>varien/product_options.js</script></action>
为了解决这个问题,我们检查了整个自定义模块。
app\code\local\Mage\ConfigurableSwatches\Helper\Mediafallback.php
旧开发人员创建了这个自定义模块,因此新版 Magento 的 Mediafallback.php 无法正常工作。 这是正确的原始核心 php 文件。
app\code\core\Mage\ConfigurableSwatches\Helper\Mediafallback.php
public function attachProductChildrenAttributeMapping(array $parentProducts, $storeId, $onlyListAttributes = false)
{
/** @var $listSwatchAttr Mage_Eav_Model_Attribute */
$listSwatchAttr = Mage::helper('configurableswatches/productlist')->getSwatchAttribute();
$swatchAttributeIds = array();
if (!$onlyListAttributes) {
$swatchAttributeIds = Mage::helper('configurableswatches')->getSwatchAttributeIds();
}
if ($listSwatchAttr->getId()) {
$swatchAttributeIds[] = $listSwatchAttr->getId();
}
if (empty($swatchAttributeIds)) {
return;
}
$parentProductIds = array();
/* @var $parentProduct Mage_Catalog_Model_Product */
foreach ($parentProducts as $parentProduct) {
$parentProductIds[] = $parentProduct->getId();
}
$configAttributes = Mage::getResourceModel('configurableswatches/catalog_product_attribute_super_collection')
->addParentProductsFilter($parentProductIds)
->attachEavAttributes()
->addFieldToFilter('eav_attributes.attribute_id', array('in' => $swatchAttributeIds))
->setStoreId($storeId)
;
$optionLabels = array();
foreach ($configAttributes as $attribute) {
$optionLabels += $attribute->getOptionLabels();
}
// normalize to all lower case before we start using them
$optionLabels = array_map(function ($value) {
return array_map('Mage_ConfigurableSwatches_Helper_Data::normalizeKey', $value);
}, $optionLabels);
foreach ($parentProducts as $parentProduct) {
$mapping = array();
$listSwatchValues = array();
$listSwatchStockValues = array();
/* @var $attribute Mage_Catalog_Model_Product_Type_Configurable_Attribute */
foreach ($configAttributes as $attribute) {
/* @var $childProduct Mage_Catalog_Model_Product */
if (!is_array($parentProduct->getChildrenProducts())) {
continue;
}
foreach ($parentProduct->getChildrenProducts() as $childProduct) {
// product has no value for attribute or not available, we can't process it
$isInStock = $childProduct->getStockItem()->getIsInStock();
if (!$childProduct->hasData($attribute->getAttributeCode())
|| (!$isInStock && !Mage::helper('cataloginventory')->isShowOutOfStock())) {
continue;
}
$optionId = $childProduct->getData($attribute->getAttributeCode());
// if we don't have a default label, skip it
if (!isset($optionLabels[$optionId][0])) {
continue;
}
// using default value as key unless store-specific label is present
$optionLabel = $optionLabels[$optionId][0];
if (isset($optionLabels[$optionId][$storeId])) {
$optionLabel = $optionLabels[$optionId][$storeId];
}
// initialize arrays if not present
if (!isset($mapping[$optionLabel])) {
$mapping[$optionLabel] = array(
'product_ids' => array(),
);
}
$mapping[$optionLabel]['product_ids'][] = $childProduct->getId();
$mapping[$optionLabel]['label'] = $optionLabel;
$mapping[$optionLabel]['default_label'] = $optionLabels[$optionId][0];
$mapping[$optionLabel]['labels'] = $optionLabels[$optionId];
if ($attribute->getAttributeId() == $listSwatchAttr->getAttributeId()
&& !in_array($mapping[$optionLabel]['label'], $listSwatchValues)
) {
$listSwatchValues[$optionId] = $mapping[$optionLabel]['label'];
$listSwatchStockValues[$optionId] = $isInStock;
}
} // end looping child products
} // end looping attributes
foreach ($mapping as $key => $value) {
$mapping[$key]['product_ids'] = array_unique($mapping[$key]['product_ids']);
}
if (count($listSwatchValues)) {
$listSwatchValues = array_replace(array_intersect_key($optionLabels, $listSwatchValues),
$listSwatchValues);
}
$parentProduct->setChildAttributeLabelMapping($mapping)
->setListSwatchAttrValues($listSwatchValues)
->setListSwatchAttrStockValues($listSwatchStockValues);
} // end looping parent products
}
此外,这些文章可能对我们的解决方案有所帮助。
https://magento.stackexchange.com/questions/45948/how-to-use-magento-1-9-1-0-configurable-swatches-in-default-package-theme-or-a https://magento.stackexchange.com/questions/142404/configurable-swatches-not-working-after-1-9-3-upgrade