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