CẬP NHẬT TẠI 20160310
Phần kết luận
Nó luôn được đặt qua updateTheme()
hoặc từ bộ sưu tập (thông qua DB) nếuappState->getMode() == AppState::MODE_PRODUCTION
Câu trả lời
Để trả lời câu hỏi Cách nào để Magento tải lại tệp theme.xml , câu trả lời là:
Đặt trạng thái ứng dụng thành developer
sử dụng SetEnv MAGE_MODE developer
trong .htaccess
(hoặc nginx tương đương) và sau đó đăng nhập vào khu vực quản trị (hoặc làm mới bất kỳ tuyến quản trị nào) để kích hoạt Magento\Theme\Model\Theme\Plugin\Registration::beforeDispatch()
.
Bảng chủ đề trong cơ sở dữ liệu được cập nhật do
\\Magento\Theme\Model\Theme\Plugin\Registration::updateThemeData()
\\...
$themeData->setParentId($parentTheme->getId());`.
\\...
Xem phân tích dưới đây để biết chi tiết.
Phân tích
Wow mã Magento 2 có vẻ thực sự phức tạp đối với tôi. Bạn đã nghiên cứu chức năng này beforeDispatch()
mà gọi updateThemeData()
nhưng chỉ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);
}
}
Có lẽ bạn đã được thông qua mã này.
beforeDispatch()
chỉ được gọi thông qua các tuyến quản trị và không phải trên các tuyến đầu. Đây là một dấu vết:
#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))
Trên thực tế tôi thấy beforeDispatch()
các cuộc gọi updateThemeData()
có chứa nugget này:
//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());
}
//...
Có vẻ như thực sự (cuối cùng) đề cập đến một đường dẫn XML cấu hình $themeData->getParentTheme()->getFullPath()
nhưng chức năng đó vẫn sử dụng $themeData->getParentTheme()
. Ồ tôi nghĩ logic là ' Nếu tôi đang cập nhật một chủ đề đã đăng ký có cha mẹ trong bộ sưu tập (thông qua DB) thì hãy tìm đường dẫn cha mẹ trong cấu hình và cập nhật bộ sưu tập '.Vì vậy, có lẽ đây là nó.
Mặt khác, tôi hoàn toàn mất khả năng Magento\Theme\Model\Theme::getParentTheme()
thực hiện getParentId()
khai báo trong giao diện chủ đề. Chắc chắn đó không phải là phép thuật. Như bạn nói, nó cần đến từ DB thông qua bộ sưu tập hoặc từ đường dẫn XML cấu hình của chủ đề (nếu nó đã thay đổi hoặc chưa được xác định) nhưng tôi không thể tìm thấy định nghĩa getParentId()
. Có thể nó luôn được đặt qua updateTheme()
OR từ bộ sưu tập (qua DB) nên quá tệ nếu bạn appState->getMode() == AppState::MODE_PRODUCTION
.
Tôi thấy nó hữu ích để lượm lặt thông tin từ bên trong updateThemeData()
bằng cách thêm một số đầu ra nhật ký:
//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());
}
//...
Mà sẽ đăng nhập /var/log/debug.log
. Với trạng thái ứng dụng được đặt thành developer
tôi có thể thấy ID cha luôn được đặt trên mỗi lần làm mới trang quản trị cho dù nó có được thay đổi theme.xml
hay không. Với trạng thái ứng dụng production
, hàm không bao giờ chạy được nên tôi kết luận:
Nó luôn được đặt qua updateTheme()
OR từ bộ sưu tập (qua DB) nên quá tệ nếuappState->getMode() == AppState::MODE_PRODUCTION
Tôi nghĩ rằng bạn có thể là tất cả trong developer
trạng thái ứng dụng. default
Tất nhiên, trạng thái ứng dụng sẽ kích hoạt updateThemeData()
. Trong phần gỡ lỗi tiếp theo, tôi đã ghi lại đường dẫn đầy đủ của chủ đề cho chủ đề chính của Luma frontend/Magento/blank
. Thủ đô M
làm tôi ngạc nhiên vì vậy có lẽ một cái gì đó để coi chừng.