ACTUALIZADO EN 20160310
Conclusión
Siempre se establece a través de updateTheme()
o desde la colección (a través de DB) si suappState->getMode() == AppState::MODE_PRODUCTION
Responder
Para responder la pregunta ¿Cuál es la forma de hacer que Magento vuelva a cargar el archivo theme.xml? La respuesta es:
Establezca el estado de la aplicación en developer
usar SetEnv MAGE_MODE developer
in .htaccess
(o nginx equivalente) y luego inicie sesión en el área de administración (o actualice cualquier ruta de administración) para activar Magento\Theme\Model\Theme\Plugin\Registration::beforeDispatch()
.
La tabla de temas en la base de datos se actualiza debido a
\\Magento\Theme\Model\Theme\Plugin\Registration::updateThemeData()
\\...
$themeData->setParentId($parentTheme->getId());`.
\\...
Vea el análisis a continuación para más detalles.
Análisis
Wow, el código de Magento 2 me parece realmente complejo. ¿Has estudiado esta función beforeDispatch()
que llama updateThemeData()
pero soloif ($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);
}
}
Probablemente hayas leído este código.
beforeDispatch()
se llama solo a través de rutas de administrador y no en rutas de front-end. Aquí hay un rastro:
#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))
En realidad, veo beforeDispatch()
llamadas updateThemeData()
que contienen esta pepita:
//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());
}
//...
Lo que parece referirse realmente (finalmente) a una ruta XML de configuración, $themeData->getParentTheme()->getFullPath()
pero esa función aún se usa $themeData->getParentTheme()
. Oh, creo que la lógica es ' Si estoy actualizando un tema registrado que tiene un parentId en la colección (a través de la base de datos), busque una ruta principal en la configuración y actualice la colección '.Entonces tal vez esto es todo.
De lo contrario, estoy completamente perdido en cuanto a cómo se Magento\Theme\Model\Theme::getParentTheme()
implementa lo getParentId()
que se declara en la interfaz del tema. Seguramente no es magia. Como usted dice, debe provenir de la base de datos a través de la colección o de la ruta XML de configuración del tema (si cambió o aún no está definida), pero no puedo encontrar una definición de getParentId()
. Tal vez siempre se establece a través de updateTheme()
OR de la colección (a través de DB), por lo que es muy malo si su appState->getMode() == AppState::MODE_PRODUCTION
.
Me resultó útil obtener información desde adentro updateThemeData()
agregando algunos resultados de registro:
//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());
}
//...
Que se registrará en /var/log/debug.log
. Con el estado de la aplicación configurado en developer
Puedo ver que la ID principal siempre se establece en cada actualización de la página de administración, ya sea que se haya cambiado theme.xml
o no. Con el estado de production
la aplicación, la función nunca se ejecuta, así que concluyo:
Siempre se establece a través de updateTheme()
OR desde la colección (a través de DB), por lo que es muy malo si suappState->getMode() == AppState::MODE_PRODUCTION
Creo que probablemente todos estén en developer
estado de aplicación. default
el estado de la aplicación también se activará, updateThemeData()
por supuesto. En la depuración adicional, registré la ruta completa del tema para el tema principal de Luma que era frontend/Magento/blank
. La capital M
me sorprendió, así que tal vez algo a tener en cuenta.