于20160310更新
结论
updateTheme()
如果您的计算机始终通过或从集合(通过DB)中进行设置,appState->getMode() == AppState::MODE_PRODUCTION
回答
为了回答这个问题,让Magento重新加载theme.xml文件的方法是什么:
将应用程序状态设置为developer
using 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()
。哦,我认为逻辑是“ 如果我要更新一个在集合中具有parentId的注册主题(通过DB),然后在配置中查找父路径并更新集合 ”。也许就是这样。
否则,我完全不知道如何Magento\Theme\Model\Theme::getParentTheme()
实现getParentId()
主题界面中声明的内容。当然,这不是魔术。正如您所说,它需要来自数据库,也可以来自集合,也可以来自主题的config XML路径(如果它已更改或尚未定义),但是我找不到的定义getParentId()
。也许总是通过updateTheme()
集合中的OR(通过DB)进行设置,如果您使用,那就太糟糕了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
无论是否进行了更改,我都能看到始终在每次管理页面刷新时都设置父ID theme.xml
。对于应用程序状态,production
该功能永远不会运行,因此我得出结论:
它总是通过updateTheme()
集合中的OR 设置(通过DB),如果您的appState->getMode() == AppState::MODE_PRODUCTION
我认为您可能都处于developer
应用程序状态。default
应用程序状态updateThemeData()
当然也会触发。在进一步的调试中,我记录了Luma父主题为的主题完整路径frontend/Magento/blank
。首都M
使我感到惊讶,所以也许需要提防。