Храните конкретные связанные, продаваемые или перекрестно продаваемые товары в Magento


Magento по умолчанию хранит связанные, продаваемые и перекрестно продаваемые продукты в общем объеме. Есть ли расширение для их хранения в области магазина? Есть ли у кого-нибудь опыт реализации этой функции?

Author: Sander Mangel, 2015-09-07

2 answers

Сохранение отношения выполняется в Mage_Adminhtml_Catalog_ProductController. Вы можете отследить его с помощью метода saveAction до метода _initProductSave, где вокруг линии 640 он задан в объекте продукта.

В классе Mage_Catalog_Model_Product метод _afterSave в строке 540 называется метод Mage_Catalog_Model_Product_Link::saveProductRelations, который вызывает Mage_Catalog_Model_Resource_Product_Link::saveProductLinks с аргументом $product, $data и $typeId это фактически сохраняется в базе данных, что происходит в строке 99.

Теперь, со всем этим обратным отслеживанием, мы действительно можем что-то сделать, чтобы решить твой вопрос.

Чтобы сделать это правильно, напишите свой собственный модуль, учебник по которому вы можете найти здесь Tutsplus.com.

Вам также понадобится сценарий установки. Ознакомьтесь с этим учебником Inchoo об этом.

Итак, сначала давайте добавим столбец в таблицу catalog_product_link, в которой на самом деле хранятся данные (спасибо @magepsycho за эту диаграмму)

$installer = $this;
$connection = $installer->getConnection();

$installer->startSetup();

$installer->getConnection()
    ->addColumn($installer->getTable('catalog/product_link'),
    'store_id',
    array(
        'type' => Varien_Db_Ddl_Table::TYPE_INT,
        'nullable' => false,
        'default' => 0,
        'comment' => 'Store ID'
    )
);

$installer->endSetup();

Теперь мы перепишем модель ресурсов, фактически сохранив данные, чтобы также включить хранилище Идентификатор.

Добавьте следующее в свои модули config.xml в узле global.

<models>
    <catalog_resource>
        <rewrite>
            <product_link>[Namespace]_[Module]_Model_Resource_Catalog_Product_Link</product_link>
        </rewrite>
    </catalog_resource>
</models>

Со следующим содержанием

class [Namespace]_[Module]_Model_Resource_Catalog_Product_Link extends Mage_Catalog_Model_Resource_Product_Link
{


    /**
     * Save Product Links process
     *
     * @param Mage_Catalog_Model_Product $product
     * @param array $data
     * @param int $typeId
     * @return Mage_Catalog_Model_Resource_Product_Link
     */
    public function saveProductLinks($product, $data, $typeId)
    {
        if (!is_array($data)) {
            $data = array();
        }

        $attributes = $this->getAttributesByType($typeId);
        $adapter    = $this->_getWriteAdapter();

        $bind   = array(
            ':product_id'    => (int)$product->getId(),
            ':link_type_id'  => (int)$typeId
        );
        $select = $adapter->select()
            ->from($this->getMainTable(), array('linked_product_id', 'link_id'))
            ->where('product_id = :product_id')
            ->where('link_type_id = :link_type_id');

        $links   = $adapter->fetchPairs($select, $bind);

        $deleteIds = array();
        foreach($links as $linkedProductId => $linkId) {
            if (!isset($data[$linkedProductId])) {
                $deleteIds[] = (int)$linkId;
            }
        }
        if (!empty($deleteIds)) {
            $adapter->delete($this->getMainTable(), array(
                'link_id IN (?)' => $deleteIds,
            ));
        }

        foreach ($data as $linkedProductId => $linkInfo) {
            $linkId = null;
            if (isset($links[$linkedProductId])) {
                $linkId = $links[$linkedProductId];
                unset($links[$linkedProductId]);
            } else {

                /**
                 * The actual change in the code
                 */

                $storeId = (int)$this->getRequest()->getParam('store');

                $bind = array(
                    'product_id'        => $product->getId(),
                    'linked_product_id' => $linkedProductId,
                    'link_type_id'      => $typeId,
                    'store_id'          => $storeId
                );
                $adapter->insert($this->getMainTable(), $bind);
                $linkId = $adapter->lastInsertId($this->getMainTable());
            }

            foreach ($attributes as $attributeInfo) {
                $attributeTable = $this->getAttributeTypeTable($attributeInfo['type']);
                if ($attributeTable) {
                    if (isset($linkInfo[$attributeInfo['code']])) {
                        $value = $this->_prepareAttributeValue($attributeInfo['type'],
                            $linkInfo[$attributeInfo['code']]);
                        $bind = array(
                            'product_link_attribute_id' => $attributeInfo['id'],
                            'link_id'                   => $linkId,
                            'value'                     => $value
                        );
                        $adapter->insertOnDuplicate($attributeTable, $bind, array('value'));
                    } else {
                        $adapter->delete($attributeTable, array(
                            'link_id = ?'                   => $linkId,
                            'product_link_attribute_id = ?' => $attributeInfo['id']
                        ));
                    }
                }
            }
        }

        return $this;
    }
}

Я буду честен, это не для "очистки", чтобы получить данные post в модели ресурсов, но таким образом вам не нужно переписывать все вышеперечисленные классы и методы, чтобы принять дополнительную переменную $storeId.

Теперь для получения нужной коллекции в сетке при редактировании продукта. В этом случае вам нужно будет переписать следующее блоки

  • Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Related
  • Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Upsell
  • Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Crosssell

И измените метод _prepareCollection, чтобы добавить фильтр идентификатора хранилища в полученную коллекцию вокруг строки 99. Который выглядел бы примерно так

$collection = Mage::getModel('catalog/product_link')->use[...]Links()
            ->getProductCollection()
            ->setProduct($this->_getProduct())
            ->addAttributeToSelect('*')
            ->addAttributeToFilter('store_id', $this->getRequest()->getParam('store_id'));

ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: это непроверенный код. Что должно сработать, но может потребоваться некоторая настройка здесь и там.

 6
Author: Sander Mangel, 2016-01-15 19:28:31

Как видно из структуры таблицы для связанных продуктов (связанных, повышающих и перекрестных продаж), ясно, что идентификатора store_id нет. enter image description here

Итак, первым шагом будет добавление поля store_id в таблицу. Затем вам нужно подготовить идентификаторы связанных продуктов при отображении и сохранении продуктов в соответствии с представлением магазина.

Возможно, потребуется много настроек, просто приблизительная идея для начала.

 7
Author: MagePsycho, 2016-01-15 18:21:26