ОБНОВЛЕНО В 20160310
Вывод
Он всегда устанавливается через updateTheme()
или из коллекции (через БД), если вашappState->getMode() == AppState::MODE_PRODUCTION
Ответ
Чтобы ответить на вопрос, как заставить Magento перезагрузить файл theme.xml, ответ:
Установите состояние приложения на developer
использование SetEnv MAGE_MODE developer
in .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()
. О, я думаю, что логика такова: « Если я обновляю зарегистрированную тему, у которой есть родительский идентификатор в коллекции (через БД), тогда найдите родительский путь в конфигурации и обновите коллекцию ».Так что, возможно, это оно и есть.
Иначе я в полной растерянности относительно того, как 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
удивила меня, так что, может быть, на что-то стоит обратить внимание.