Поточний склад - 1 при запуску скриптів оновлення


15

Будь-яка ідея, чому Mage::app()->getStore()повертає вигляд магазину з id 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

Примітка: не забувайте, що область зберігання адміністратора не встановлена, поки не відбудеться диспетчеризація і не Mage_Adminhtml_Controller_Actionвиконає контролер, який розширює (див. adminhtml_controller_action_predispatch_startПодію та пов’язаного з цим спостерігача Mage_Adminhtml_Controller_Action::preDispatch()).

Мені цікаво бізнес-логіка мати цю «особливість».

Ви не єдиний; з цього приводу ми можемо ніколи не дізнатися, якщо Моше чи Діма не захочуть обговорити.

Сценарії налаштування виконуються на початку ініціалізації програми. Проект цього, мабуть, пов'язаний з тим, що до моменту виконання решти стека необхідні міграції та інші роботи будуть "виконані" - це означає, що система була готова використовувати відразу ж під час встановлення модуля або оновлено. Мені цікаво, чи спочатку архітектори думали, що буде потреба у більш ініціалізованій системі. Я припускаю, що, хоча значна частина коду припускає, що наявний екземпляр магазину, _getDefaultStore()логіка гарантує наявність екземпляра магазину.

Повні параметри обсягу доступні в 1.4.0.0 і вище за допомогою сценаріїв налаштування даних.


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());

Інакше іноді після виконання сценарію оновлення відвідувачі будуть переадресовані на сторінку адміністратора, а не на фронтенд.


Оновлення:

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

Сценарії оновлення викликаються методом глибше в core ( 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визначається.

В даний час я не можу зрозуміти, де визначено припущений запасний варіант.


О, але для адміністратора є вигляд завантажуваного магазину. погляньте в core_storeтаблицю. Є запис із ід 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()повертає магазин із id 1 у скриптах оновлення.
Маріус

о ... так ... справді є сховище адміністратора в базі даних.
bukart

1
Хм ... Я знав стек, але тепер, коли я бачив це у вашій відповіді, він мене вдарив. Оновлення повинні працювати якось "без громадянства". Але для того, щоб запустити щось, вам потрібен магазин. Звідси значення для магазину за замовчуванням. Тепер єдине, що не має сенсу: Чому цей магазин за замовчуванням не є 0(адміністратором) і це перегляд магазину, який легко можна видалити з інтерфейсу адміністратора? +1 для відкриття очей. Якщо я не отримаю іншої чіткої відповіді на це, я прийму це.
Маріус

гм ... хороше запитання ... можливо, після обіду я подивлюсь ... цікаво ^^
bukart

Станом на 1.9.3.6, схоже, Mage::app()->getCurrentStore();це не визначено і дає фатальну помилку при виклику . Натомість я отримав ідентифікатор за допомогою $currentStoreId = Mage::app()->getStore()->getId();.
Eric Seastrand

2

Отже, основна відповідь полягає в тому, що він насправді потрапляє в третій, якщо ..... почекай що :(

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

Для мене це повертає true для Mage::isInstalled()і false, для $this->getUpdateMode()яких звучить неправильно. Але це відбувається лише при першому хіті getStore.

Отже, виявляється, що він налаштовує магазин до встановлення режиму оновлення, тоді, коли він повертається в сценарій настройки, він використовує виклик магазину за замовчуванням, який використовує наступний код:

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

Значення self::DISTRO_STORE_IDдорівнює 1 Я думаю, тому що це щось потребує, і це не було налаштування для нас у адміністративному магазині :(

Тож у мене фактично є система, яка не зберігається з id 1, і сценарій оновлення, здається, працює добре. Якщо ми додаємо таблиці / атрибути, це нормально, і навіть при додаванні конкретного блоку cms для сайту це також працює, але ми отримуємо весь ідентифікатор магазину та спеціально встановлюємо їх під час збереження конкретних даних для зберігання.


Я викопав те саме. Що я не розумію, це "Magento, чому ти не використовуєш адміністратор-магазин для оновлень?". Це здається більш розумним. Боюся думати, що станеться, якщо я видалю магазин із ідентифікатором 1.
Маріус

Ніхто не був би божевільний, щоб видалити магазин за замовчуванням;)
Девід Маннерс

Тепер, коли я це знаю, я не буду божевільний, але факт, що це можливо ... ну ... ніколи не довіряйте користувачеві.
Маріус

Один наш прем'єр-міністр запитав мене, чи зможе він прибрати старі магазини минулого тижня. Я думаю, що я відповів "Що найгірше, що може трапитися" .... І ще більше дивно в нашій теперішній програмі проекту немає магазину з ідентифікатором 1 :( в таблиці, core_storeале сценарії налаштування працюють
Девід Маннерс

1
додавання cms-блоку слід виконати в сценарії оновлення даних (не встановлення), де область зберігання не заблокована в Mage_Core_Model_App :: DISTRO_STORE_CODE; Більш загально, сценарії встановлення використовуються для зміни структури даних (і вони мають заблоковану область зберігання), тоді як оновлення даних використовується для зміни вмісту даних (а область зберігання може бути змінена під час сценарію)
Алессандро Рончі,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.