Обновите только один атрибут категории


Я пытаюсь ускорить процесс обновления описания и изображения категорий в нескольких сотнях категорий в 16 магазинах. Каждый просмотр магазина имеет свое описание и изображение категории.

Использование метода save() для объекта категории работает нормально, но довольно медленно.

Я пытался использовать

$_category->getResource()->saveAttribute( $_category, "description" );

Но это не работает для меня.

Есть ли какой-либо другой способ для более быстрого обновления атрибутов одной категории, может быть, что-то вроде

Mage::getSingleton('catalog/resource_product_action')

(я не смог найти ничего подобного для категорий)?

Author: Marc Harding, 2013-12-10

2 answers

Ваш исходный код должен работать; см.:

<?php

include 'app/Mage.php';
Mage::app();

$obj = new Varien_Object(array('entity_id' => 10,'description'=>'test','store_id'=>0));
$resource = Mage::getModel('catalog/category')->getResource();
/* @var $resource Mage_Catalog_Model_Resource_Category */

$resource->saveAttribute($obj,'description');

Итак, это основной подход к сохранению для одного атрибута за раз.

Возможно, вам захочется создать ресурс действий категории, например Mage_Catalog_Model_Resource_Category_Action (поместите его в локальный пул кодов, чтобы дети не плакали), однако, вам нужно будет настроить метод updateAttributes для сохранения различных областей хранения и значений атрибутов для каждой сущности - это отличается от ресурса действия каталога поведение.

<?php

/**
 * Catalog Category Mass processing resource model
 *
 * @category    Mage
 * @package     Mage_Catalog
 * @author      Ben Marks <[email protected]>
 */
class Mage_Catalog_Model_Resource_Category_Action extends Mage_Catalog_Model_Resource_Abstract
{
    /**
     * Initialize connection
     *
     */
    protected function _construct()
    {
        $resource = Mage::getSingleton('core/resource');
        $this->setType(Mage_Catalog_Model_Category::ENTITY) //note the change from the product action resource
            ->setConnection(
                $resource->getConnection('catalog_read'),
                $resource->getConnection('catalog_write')
            );
    }

    /**
     * Update entity attribute values individually by scope
     *
     * $dataArray = array(
     *     {attribute code} => array (
     *         array (
     *             'entity_id' => {category id},
     *             'value      => {value},
     *             'store_id'  => {store id}
     *         ),
     *         array (
     *             //...
     *         )
     *     )
     * );
     *
     * @param  array
     * @return Mage_Catalog_Model_Resource_Category_Action
     * @throws Exception
     */
    public function updateAttributes($dataArray)
    {
        $this->_getWriteAdapter()->beginTransaction();

        try {
            $i = 0;
            foreach ($dataArray as $code => $entities) {
                $attribute = $this->getAttribute($code);
                if (!$attribute->getAttributeId()) {
                    continue;
                }
                foreach ($entities as $entity) {
                    $object = new Varien_Object();
                    $object->setIdFieldName('entity_id')
                        ->setStoreId($entity['store_id']);

                    $object->setId($entity['entity_id']);
                    // collect data for save
                    $this->_saveAttributeValue($object, $attribute, $entity['value']);
                }
            }
            $this->_processAttributeValues();
            $this->_getWriteAdapter()->commit();
        } catch (Exception $e) {
            $this->_getWriteAdapter()->rollBack();
            throw $e;
        }

        return $this;
    }
}

Очевидно, что вам следует изменить структуру массива на то, что вам подходит. Тестовые данные и сценарий для вышеуказанного класса и метода приведены ниже и будут работать с образцами данных.

<?php

include 'app/Mage.php';
Mage::app();

$action = Mage::getResourceModel('catalog/category_action');

$test = array(
    'description' => array(
        array (
            'entity_id' => 10,      //Furniture category
            'value'     => 'ONE',
            'store_id'  => 1        //English store scope
        ),
        array (
            'entity_id' => 10,      //Furniture category
            'value'     => 'TWO',
            'store_id'  => 2        //German store scope
        ),
        array (
            'entity_id' => 22,      //Living Room category
            'value'     => 'THREE',
            'store_id'  => 3        //French store scope
        )
    ),
    'meta_keywords' => array(
        array (
            'entity_id' => 22,      //Living Room category
            'value'     => 'FOUR',
            'store_id'  => 1        //English store scope
        )
    )
);

$action->updateAttributes($test);
 1
Author: benmarks, 2013-12-11 14:48:58

Вы должны проверить выполненные SQL-запросы при сохранении категории, например, с помощью Отладки Magento или панели инструментов mgt

Оба показывают вам запущенные sql-запросы. Обычно magento обновляет только те атрибуты, которые вы изменили.

 1
Author: Fabian Blechschmidt, 2013-12-10 22:58:57