ZAKTUALIZOWANO W 20160310
Wniosek
Jest zawsze ustawiany za pośrednictwem updateTheme()
lub z kolekcji (przez DB), jeśli maszappState->getMode() == AppState::MODE_PRODUCTION
Odpowiedź
Aby odpowiedzieć na pytanie Jaki jest sposób na to, aby Magento ponownie załadował plik theme.xml, odpowiedź brzmi:
Ustaw stan aplikacji na developer
użycie SetEnv MAGE_MODE developer
w .htaccess
(lub odpowiednik nginx), a następnie zaloguj się do obszaru administratora (lub odśwież dowolną trasę administratora), aby uruchomićMagento\Theme\Model\Theme\Plugin\Registration::beforeDispatch()
.
Tabela motywów w bazie danych została zaktualizowana z powodu
\\Magento\Theme\Model\Theme\Plugin\Registration::updateThemeData()
\\...
$themeData->setParentId($parentTheme->getId());`.
\\...
Zobacz szczegóły poniżej.
Analiza
Wow, kod Magento 2 wydaje mi się naprawdę skomplikowany. Czy studiowałeś tę funkcję, beforeDispatch()
która wywołuje, updateThemeData()
ale tylkoif ($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);
}
}
Prawdopodobnie przeszedłeś przez ten kod.
beforeDispatch()
jest wywoływany tylko przez trasy administracyjne, a nie na trasach frontonu. Oto ślad:
#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))
Właściwie widzę beforeDispatch()
połączenia, updateThemeData()
które zawierają ten samorodek:
//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());
}
//...
Co wydaje się faktycznie (w końcu) odwoływać się do ścieżki XML konfiguracji, $themeData->getParentTheme()->getFullPath()
ale ta funkcja nadal używa $themeData->getParentTheme()
. Och, myślę, że logika brzmi: „ Jeśli aktualizuję zarejestrowany motyw, który ma ParentId w kolekcji (poprzez DB), to poszukaj ścieżki nadrzędnej w konfiguracji i zaktualizuj kolekcję ”.Więc może to jest to.
W przeciwnym razie mam całkowitą utratę tego, jak Magento\Theme\Model\Theme::getParentTheme()
implementuje getParentId()
deklarowane w interfejsie kompozycji. Na pewno to nie jest magia. Jak mówisz, musi pochodzić albo z DB poprzez kolekcję, albo ze ścieżki XML konfiguracji motywu (jeśli się zmieniło lub nie zostało jeszcze zdefiniowane), ale nie mogę znaleźć definicji getParentId()
. Może zawsze jest ustawiony przez updateTheme()
OR z kolekcji (przez DB), więc szkoda, jeśli masz appState->getMode() == AppState::MODE_PRODUCTION
.
Za przydatne uznałem zbieranie informacji od wewnątrz updateThemeData()
poprzez dodanie danych wyjściowych dziennika:
//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());
}
//...
Który zaloguje się do /var/log/debug.log
. Po ustawieniu stanu aplikacji na developer
Widzę, że identyfikator nadrzędny jest zawsze ustawiony na każdym odświeżeniu strony administratora, niezależnie od tego, czy został zmieniony theme.xml
czy nie. Ze stanem aplikacji production
funkcja nigdy nie jest uruchamiana, więc wnioskuję:
Zawsze jest ustawiane przez updateTheme()
OR z kolekcji (przez DB), więc szkoda, jeśli takappState->getMode() == AppState::MODE_PRODUCTION
Myślę, że prawdopodobnie wszyscy jesteście w developer
stanie aplikacji. Oczywiście default
stan aplikacji również się uruchomi updateThemeData()
. Podczas dalszego debugowania zapisałem pełną ścieżkę motywu dla motywu nadrzędnego Luma, który był frontend/Magento/blank
. Stolica M
mnie zaskoczyła, więc może warto na nią uważać.