ОНОВЛЕНО В 20160310
Висновок
Він завжди встановлюється через updateTheme()
або з колекції (через БД), якщо вашappState->getMode() == AppState::MODE_PRODUCTION
Відповідь
Щоб відповісти на питання Який спосіб змусити Magento перезавантажити файл theme.xml відповідь:
Щоб встановити статус додатка для developer
використання SetEnv MAGE_MODE developer
в .htaccess
(або Nginx еквівалент) , а потім увійти в адмінку (або оновити будь-адмін маршрут) , щоб викликати Magento\Theme\Model\Theme\Plugin\Registration::beforeDispatch()
.
Тема таблиці в базі даних оновлюється завдяки
\\Magento\Theme\Model\Theme\Plugin\Registration::updateThemeData()
\\...
$themeData->setParentId($parentTheme->getId());`.
\\...
Детальніше дивіться в аналізі нижче.
Аналіз
Нічого собі, код Magento 2 здається мені дуже складним. Ви вивчали цю функцію, beforeDispatch()
яка викликає, updateThemeData()
але тількиif ($this->appState->getMode() != AppState::MODE_PRODUCTION)
//namespace: namespace Magento\Theme\Model\Theme\Plugin;
//class: Registration
//file: app/code/Magento/Theme/Model/Theme/Plugin/Registration.php
/**
* Add new theme from filesystem and update existing
*
* @param AbstractAction $subject
* @param RequestInterface $request
*
* @return void
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function beforeDispatch(
AbstractAction $subject,
RequestInterface $request
) {
try {
if ($this->appState->getMode() != AppState::MODE_PRODUCTION) {
$this->themeRegistration->register();
$this->updateThemeData();
}
} catch (LocalizedException $e) {
$this->logger->critical($e);
}
}
Можливо, ви пройшли цей код.
beforeDispatch()
викликається тільки через адміністраторські маршрути, а не на передніх маршрутах. Ось слід:
#0 [internal function]: Magento\Theme\Model\Theme\Plugin\Registration->beforeDispatch(Object(Magento\Backend\Controller\Adminhtml\Dashboard\Index\Interceptor), Object(Magento\Framework\App\Request\Http))
#1 \magento2\lib\internal\Magento\Framework\Interception\Interceptor.php(122): call_user_func_array(Array, Array)
#2 \magento2\var\generation\Magento\Backend\Controller\Adminhtml\Dashboard\Index\Interceptor.php(39): Magento\Backend\Controller\Adminhtml\Dashboard\Index\Interceptor->___callPlugins('dispatch', Array, Array)
#3 \magento2\lib\internal\Magento\Framework\App\FrontController.php(55): Magento\Backend\Controller\Adminhtml\Dashboard\Index\Interceptor->dispatch(Object(Magento\Framework\App\Request\Http))
#4 [internal function]: Magento\Framework\App\FrontController->dispatch(Object(Magento\Framework\App\Request\Http))
#5 \magento2\lib\internal\Magento\Framework\Interception\Interceptor.php(74): call_user_func_array(Array, Array)
#6 \magento2\lib\internal\Magento\Framework\Interception\Chain\Chain.php(70): Magento\Framework\App\FrontController\Interceptor->___callParent('dispatch', Array)
#7 \magento2\lib\internal\Magento\Framework\Interception\Interceptor.php(136): Magento\Framework\Interception\Chain\Chain->invokeNext('Magento\\Framewo...', 'dispatch', Object(Magento\Framework\App\FrontController\Interceptor), Array, 'install')
#8 \magento2\lib\internal\Magento\Framework\Module\Plugin\DbStatusValidator.php(69): Magento\Framework\App\FrontController\Interceptor->Magento\Framework\Interception\{closure}(Object(Magento\Framework\App\Request\Http))
#9 [internal function]: Magento\Framework\Module\Plugin\DbStatusValidator->aroundDispatch(Object(Magento\Framework\App\FrontController\Interceptor), Object(Closure), Object(Magento\Framework\App\Request\Http))
#10 \magento2\lib\internal\Magento\Framework\Interception\Interceptor.php(141): call_user_func_array(Array, Array)
#11 \magento2\var\generation\Magento\Framework\App\FrontController\Interceptor.php(26): Magento\Framework\App\FrontController\Interceptor->___callPlugins('dispatch', Array, Array)
#12 \magento2\lib\internal\Magento\Framework\App\Http.php(115): Magento\Framework\App\FrontController\Interceptor->dispatch(Object(Magento\Framework\App\Request\Http))
#13 \magento2\lib\internal\Magento\Framework\App\Bootstrap.php(258): Magento\Framework\App\Http->launch()
#14 \magento2\index.php(39): Magento\Framework\App\Bootstrap->run(Object(Magento\Framework\App\Http))
Насправді я бачу beforeDispatch()
дзвінки, updateThemeData()
які містять цей самородок:
//namespace: namespace Magento\Theme\Model\Theme\Plugin;
//class: Registration
//file: app/code/Magento/Theme/Model/Theme/Plugin/Registration.php
//function: updateThemeData()
//...
if ($themeData->getParentTheme()) {
$parentTheme = $this->themeLoader->getThemeByFullPath(
$themeData->getParentTheme()->getFullPath()
);
$themeData->setParentId($parentTheme->getId());
}
//...
Що, здається, насправді (нарешті) посилається на конфігураційний шлях XML, $themeData->getParentTheme()->getFullPath()
але ця функція все ще використовується $themeData->getParentTheme()
. О, я думаю, що логіка полягає в тому, що " Якщо я оновлюю зареєстровану тему, яка має parentId у колекції (через БД), то шукаю батьківський шлях у конфігурації та оновлюю колекцію ".То, можливо, це все.
Інакше я переживаю повну втрату щодо того, як Magento\Theme\Model\Theme::getParentTheme()
реалізує, getParentId()
що оголошено в інтерфейсі теми. Звичайно, це не магія. Як ви кажете, він повинен надходити або з БД через колекцію, або з конфігураційного шляху XML теми (якщо він змінився або ще не визначений), але я не можу знайти визначення getParentId()
. Можливо, це завжди встановлено через updateTheme()
АБО з колекції (через БД), так шкода, якщо ваша appState->getMode() == AppState::MODE_PRODUCTION
.
Мені здалося корисним отримати інформацію зсередини updateThemeData()
, додавши деякий вихід журналу:
//namespace: namespace Magento\Theme\Model\Theme\Plugin;
//class: Registration
//file: app/code/Magento/Theme/Model/Theme/Plugin/Registration.php
//function: updateThemeData()
//...
if ($themeData->getParentTheme()) {
$parentTheme = $this->themeLoader->getThemeByFullPath(
$themeData->getParentTheme()->getFullPath()
);
$this->logger->addDebug("Theme parent full path ".$themeData->getParentTheme()->getFullPath());
$this->logger->addDebug("Theme parent new ID ".$parentTheme->getId()); $themeData->setParentId($parentTheme->getId());
}
//...
Який увійде в систему /var/log/debug.log
. Якщо стан програми встановлено на developer
Я можу бачити, що батьківський ідентифікатор завжди встановлений на кожній сторінці адміністратора, оновіть, змінили його theme.xml
чи ні. Зі станом production
програми функція ніколи не запускається, тому я роблю висновок:
Він завжди встановлюється через updateTheme()
АБО із колекції (через БД), настільки погано, якщо вашappState->getMode() == AppState::MODE_PRODUCTION
Я думаю, що ви, напевно, всі перебуваєте в developer
стані додатків. default
стан програми updateThemeData()
також, звичайно, запустить . У подальшій налагодженні я записав повний шлях до теми батьківської теми Luma, яка була frontend/Magento/blank
. Столиця M
мене здивувала, тож, можливо, на що слідкувати.