Обновите только один атрибут категории
Я пытаюсь ускорить процесс обновления описания и изображения категорий в нескольких сотнях категорий в 16 магазинах. Каждый просмотр магазина имеет свое описание и изображение категории.
Использование метода save() для объекта категории работает нормально, но довольно медленно.
Я пытался использовать
$_category->getResource()->saveAttribute( $_category, "description" );
Но это не работает для меня.
Есть ли какой-либо другой способ для более быстрого обновления атрибутов одной категории, может быть, что-то вроде
Mage::getSingleton('catalog/resource_product_action')
(я не смог найти ничего подобного для категорий)?
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);
Вы должны проверить выполненные SQL-запросы при сохранении категории, например, с помощью Отладки Magento или панели инструментов mgt
Оба показывают вам запущенные sql-запросы. Обычно magento обновляет только те атрибуты, которые вы изменили.