Одной из причин неправильной работы в Magento программной перестройки расчётных таблиц (переиндексации) является выполнение этой операции вне контекста административной части магазина.
Все программные операции, связанные с изменением товаров, надо выполнять
только в контексте административной части магазина.
В Российской сборке Magento для включения/выключения административного режима имеются методы
Df_Admin_Model_Mode::begin() и
Df_Admin_Model_Mode::end() и их краткие аналоги: функции
rm_admin_begin() и
rm_admin_end().
Метод
Df_Admin_Model_Mode::begin(), в частности, реализован так:
/** @return void */
public function begin() {
$this->_counter++;
if (1 === $this->_counter) {
$this->_currentStore = Mage::app()->getStore();
$this->_updateMode = Mage::app()->getUpdateMode();
/**
* Очень важный момент!
* Если Magento находится в режиме обновления,
* то Mage_Core_Model_App::getStore()
* всегда будет возвращать Mage_Core_Model_App::getDefaultStore(),
* даже для такого кода: Mage_Core_Model_App::getStore(999).
* Это приводит к весьма некорректному поведению системы в некоторых ситуациях,
* когда мы обновляем товарные разделы своим установочным скриптом:
* @see Mage_Catalog_Model_Resource_Abstract::_saveAttributeValue():
* $storeId = (int)Mage::app()->getStore($object->getStoreId())->getId();
* Этот код заведомо вернёт неправильный результат!
*/
Mage::app()->setUpdateMode(false);
Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);
}
}
Метод
Df_Admin_Model_Mode::end():
/** @return void */
public function end() {
df_assert_gt0($this->_counter);
$this->_counter--;
if (0 === $this->_counter) {
Mage::app()->setCurrentStore($this->_currentStore);
Mage::app()->setUpdateMode($this->_updateMode);
unset($this->_currentStore);
unset($this->_updateMode);
}
}