Текущее хранилище равно 1 при запуске сценариев обновления

15

Любая идея, почему Mage::app()->getStore()возвращает представление магазина с идентификатором 1, когда внутри сценариев обновления, независимо от представления магазина, в котором я запускаю сценарий обновления (даже администратор)?
Я имею в виду, я знаю, где код, который делает это. В Mage_Core_Model_App::getStore()этом есть:

    if (!Mage::isInstalled() || $this->getUpdateMode()) {
        return $this->_getDefaultStore();
    }

и _getDefaultStoreвыглядит так:

   if (empty($this->_store)) {
        $this->_store = Mage::getModel('core/store')
            ->setId(self::DISTRO_STORE_ID)
            ->setCode(self::DISTRO_STORE_CODE);
    }
    return $this->_store;

$this->_store всегда пуст при достижении метода выше.

Я получаю тот же результат, даже если я добавлю это в верхней части сценария обновления:

Mage::app()->setCurrentStore(Mage::getModel('core/store')->load(Mage_Core_Model_App::ADMIN_STORE_ID));

Меня интересует бизнес-логика наличия этой «функции».

Мариус
источник
Я думал, что сценарии обновления всегда выполняются в области внешнего интерфейса. Часто я советую сценариям обновления явно использовать хранилище администратора для следующих строк.
Bukart
@bukart. Я попытался явно сказать сценарию обновления, чтобы запустить представление хранилища администратора, но я получаю тот же результат. Смотрите мои последние 3 строки в вопросе.
Мариус
Я попытался ответить на ваш вопрос ниже
Bukart

Ответы:

5

NB: не забывайте, что область хранилища администратора не устанавливается, пока не произойдет диспетчеризация и не Mage_Adminhtml_Controller_Actionвыполнится расширение контроллера (см.adminhtml_controller_action_predispatch_start Событие и связанный с ним наблюдатель в Mage_Adminhtml_Controller_Action::preDispatch()).

Меня интересует бизнес-логика наличия этой «функции».

Вы не единственный; Тем не менее, мы можем никогда не узнать, если Моше или Дима не хочет обсуждать.

Сценарии установки выполняются на ранней стадии инициализации приложения. Вероятно, это связано с тем, что к тому времени, когда остальная часть стека будет выполнена, необходимые «миграции» и другая работа будут «выполнены», что означает, что система была готова к использованию сразу же, даже при установке модуля. или модернизированный. Мне интересно, думали ли когда-нибудь первоначальные архитекторы о необходимости более инициализированной системы. Я предполагаю это, тогда как большая часть кода предполагает наличие доступного экземпляра хранилища, _getDefaultStore()логика гарантирует наличие экземпляра хранилища.

Полные настройки доступны в версии 1.4.0.0 и выше через скрипты настройки данных.

benmarks
источник
3

Хорошо, чтобы использовать хранилище администратора в ваших скриптах обновления, просто используйте

Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);

Ваш подход Mage::app()->setCurrentStore(Mage::getModel('core/store')->load(Mage_Core_Model_App::ADMIN_STORE_ID)); не может быть успешным, потому что нет реально загружаемого магазина для администратора

Часто я использую такой шаблон:

// remembering old current store
$currentStore = Mage::app()->getCurrentStore();

// switching to admin store
Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);

// switching back to old current store
Mage::app()->setCurrentStore($currentStore->getStoreId());

В противном случае иногда после выполнения скрипта обновления ваши посетители будут перенаправлены на страницу администратора, а не на внешний интерфейс.


Обновить:

Я неверно истолковал вопрос ниже, поэтому вот новая попытка объяснить ^^

Сценарии обновления вызываются из более глубокого метода в ядре ( Mage_Core_Model_Resource_Setup::_modifyResourceDb(...))

Здесь я попытался перечислить стек

  • Mage_Core_Model_App::run($params)

  • Mage_Core_Model_App::_initModules()

  • Mage_Core_Model_Resource_Setup::applyAllUpdates()

  • Mage_Core_Model_Resource_Setup::applyUpdates()

  • Mage_Core_Model_Resource_Setup::_upgradeResourceDb($oldVersion, $newVersion)

  • Mage_Core_Model_Resource_Setup::_modifyResourceDb($actionType, $fromVersion, $toVersion)

и теперь взглянем на Mage_Core_model_App::run($params):

public function run($params)
{
    $options = isset($params['options']) ? $params['options'] : array();
    $this->baseInit($options);
    Mage::register('application_params', $params);

    if ($this->_cache->processRequest()) {
        $this->getResponse()->sendResponse();
    } else {
        $this->_initModules();
        $this->loadAreaPart(Mage_Core_Model_App_Area::AREA_GLOBAL, Mage_Core_Model_App_Area::PART_EVENTS);

        if ($this->_config->isLocalConfigLoaded()) {
            $scopeCode = isset($params['scope_code']) ? $params['scope_code'] : '';
            $scopeType = isset($params['scope_type']) ? $params['scope_type'] : 'store';
            $this->_initCurrentStore($scopeCode, $scopeType);
            $this->_initRequest();
            Mage_Core_Model_Resource_Setup::applyAllDataUpdates();
        }

        $this->getFrontController()->dispatch();
    }
    return $this;
}

метод _initModules()вызывается до $scopeCodeи $scopeTypeопределяется.

В настоящее время я не могу понять, где определяется предполагаемый запасной вариант.

bukart
источник
О, но есть загружаемое представление магазина для администратора. взгляните в core_storeтаблицу. Есть запись с id 0. Также, если вы попробуете это, var_dump(Mage::getModel('core/store')->load(Mage_Core_Model_App::ADMIN_STORE_ID))вы получите действительный экземпляр магазина администратора. Также пытался, Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);но я получаю тот же результат. Но мой вопрос был не о том, как установить хранилище администратора в сценариях обновления. Я спрашивал, почему Mage::app()->getStore()возвращает магазин с идентификатором 1 в скриптах обновления.
Мариус
о ... верно ... в базе данных действительно есть админ-магазин.
Bukart
1
Хм ... Я знал стек, но теперь, когда я увидел его в вашем ответе, он ударил меня. Обновления должны запускаться как-то «без сохранения состояния». Но для того, чтобы что-то запустить, нужен магазин. Отсюда значение по умолчанию для магазина. Теперь единственное, что не имеет смысла: почему это хранилище по умолчанию не 0(admin) и является представлением хранилища, которое можно легко удалить из интерфейса администратора? +1 за то, что открыл глаза. Если я не получу другого четкого ответа на этот вопрос, я приму это.
Мариус
Ммм ... хороший вопрос ... может быть, после обеда я посмотрю ... интересно ^^
Bukart
По состоянию на 1.9.3.6, Mage::app()->getCurrentStore();не представляется определенным и выдает фатальную ошибку при вызове. Вместо этого я получил идентификатор с помощью $currentStoreId = Mage::app()->getStore()->getId();.
Эрик Сеастранд
2

Таким образом, основной ответ заключается в том, что он на самом деле попадает в 3-й, если ..... подождите, что :(

if (!isset($id) || ''===$id || $id === true) {
    $id = $this->_currentStore;
}

Для меня это возвращает истину Mage::isInstalled()и ложь, $this->getUpdateMode()что звучит неправильно. Но это происходит только при первом попадании getStore.

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

$this->_store = Mage::getModel('core/store')
    ->setId(self::DISTRO_STORE_ID)
    ->setCode(self::DISTRO_STORE_CODE);

Значение self::DISTRO_STORE_ID1, я думаю, потому что это нужно что-то и не было настроено для нас в магазине администратора :(

Так что на самом деле у меня есть система, в которой нет хранилища с идентификатором 1, и скрипт обновления, кажется, работает хорошо. Если мы добавляем таблицы / атрибуты, это нормально, и даже при добавлении блока cms для конкретного сайта это тоже работает, но мы получаем все идентификаторы хранилища и специально устанавливаем их при сохранении данных конкретного хранилища.

Дэвид Мэннерс
источник
Я откопал то же самое. Что я не понимаю, так это «Magento, почему вы не используете админ-магазин для обновлений?». Это кажется более разумным. Я боюсь думать, что произойдет, если я удалю магазин с идентификатором 1.
Мариус
Никто не будет настолько сумасшедшим, чтобы удалить магазин по умолчанию;)
Дэвид Мэннерс
Теперь, когда я это знаю, я не сойду с ума, но факт, что это возможно ... ну ... никогда не доверяй пользователю.
Мариус
Один из наших менеджеров спросил меня, может ли он убрать старые магазины на прошлой неделе. Я думаю, что ответил «Что хуже всего может случиться» .... и еще более странно в нашей текущей настройке проекта, у нас нет магазина с идентификатором 1 :( в таблице, core_storeно сценарии установки работают
Дэвид Мэннерс,
1
добавление блока cms следует выполнять в сценарии обновления данных (не устанавливать), где область хранилища не привязана к Mage_Core_Model_App :: DISTRO_STORE_CODE; в общем, сценарии установки используются для изменения структуры данных (и блокировки области хранилища), а обновление данных - для изменения содержимого данных (а область хранилища может быть изменена во время сценария)
Алессандро Рончи,