переопределение блока magento в нескольких модулях (и как игнорировать другие)
В Magento вы можете переопределить блок (или помощник, или модель и т.д.) из одного модуля в другой (наиболее распространенный из модуля Magento Adminhtml). Теперь у меня проблема в том, что я хочу переопределить блок, который уже был переопределен каким-либо другим расширением. Есть ли способ указать magento игнорировать тег <rewrite>
в какой-либо другой конфигурации модуля, аналогичной тегу <remove>
в обновлениях макета?
Вот конфигурация другого расширения:
<blocks>
<adminhtml>
<rewrite>
<catalog_product_grid>Symmetrics_DeliveryTime_Block_Adminhtml_Catalog_Product_Grid</catalog_product_grid>
</rewrite>
</adminhtml>
</blocks>
Здесь конфигурация моего расширения:
<blocks>
<adminhtml>
<rewrite>
<catalog_product_grid>Namespace_MyModule_Block_Adminhtml_Catalog_Product_Grid</catalog_product_grid>
</rewrite>
</adminhtml>
</blocks>
Я интегрировал функциональность блока из Symmetrics_DeliveryTime
в свой собственный блок, и теперь я хочу, чтобы magento игнорировал переопределение блока из этого модуля.
Есть ли какой-либо способ magento сделать это или это единственный способ прокомментировать конфигурацию (что я и сделал на данный момент), включая все хлопоты при обновлении этого модуля позже?
4 answers
Если вы установите для своего модуля значение "зависеть" от того, который также выполняет перезапись, ваша конфигурация будет прочитана последней, и перезапись должна сохраниться в соответствующем файле в приложении/etc/modules, который у вас должен быть:
<config>
<modules>
<Your_Module>
<active>true</active>
<codePool>local</codePool>
<depends>
<Other_Module/>
</depends>
</Your_Module>
<modules>
<config>
Я посмотрел загрузку класса, и не похоже, что есть чистое решение. Соответствующий код загрузки имени класса выглядит следующим образом:
if (isset($this->_classNameCache[$groupRootNode][$group][$class])) {
return $this->_classNameCache[$groupRootNode][$group][$class];
}
...
if (isset($config->rewrite->$class)) {
$className = (string)$config->rewrite->$class;
Так что, похоже, такой вещи, как переписывание-переписывание, не существует. Тот, который помещается в массив конфигурации, загружается, и после кэширования он просто возвращается по запросу. Я тоже не вижу простого способа взломать кэш. Вы можете попытаться получить приоритет для своего модуля (переименовав его в алфавитном порядке, я предположим), но это полный взлом и, скорее всего, позже таинственным образом потерпит неудачу. Это убивает возможности конфигурации.
Также неприятно: похоже, что Magento запрашивает эту сетку только в двух местах, в пределах Mage_Adminhtml_Block_Catalog_Product
(которые вы можете легко переопределить), но также и в Mage_Adminhtml_Catalog_ProductController
(о!). В зависимости от вашего варианта использования рассмотрите возможность переопределения блока продуктов каталога и замены функции _prepareLayout()
своей собственной. Если вы также хотите переопределить контроллер, вам потребуется создать свой собственный контроллер (который происходит от Mage_Adminhtml_Catalog_ProductController
) и определяет перезапись в вашей конфигурации, чтобы направить admin/catalog/product/grid
на ваше действие. Боль, но, по крайней мере, достигает своей цели.
Надеюсь, это поможет,
Джо
Вместо перезаписи catalog_product_grid, почему бы не расширить на Symmetrics_DeliveryTime_Block_Adminhtml_Catalog_Product_Grid? Таким образом, модуль Symmetrics сохранит все свои функциональные возможности, и вы сможете добавить свои.
Поэтому вместо:
<blocks>
<adminhtml>
<rewrite>
<catalog_product_grid>Symmetrics_DeliveryTime_Block_Adminhtml_Catalog_Product_Grid</catalog_product_grid>
</rewrite>
</adminhtml>
</blocks>
Сделайте это:
<blocks>
<adminhtml>
<rewrite>
<deliverytime_catalog_product_grid>Namespace_MyModule_Block_Adminhtml_Catalog_Product_Grid</deliverytime_catalog_product_grid>
</rewrite>
</adminhtml>
</blocks>
Конечно, чем было бы уместно указать в файле приложения/etc/modules.
Лучший способ преодолеть эту проблему, используя макет после или до наблюдателя.
App/code/local/My/Module/etc/config.xml
<config>
<adminhtml>
<events>
<core_block_abstract_prepare_layout_before>
<observers>
<mymodule>
<!-- Add column to catalog product grid -->
<class>mymodule/adminhtml_observer</class>
<method>onBlockHtmlBefore</method>
</mymodule>
</observers>
</core_block_abstract_prepare_layout_before>
</events>
</adminhtml>
Или может использовать событие: core_block_abstract_prepare_layout_ после.
И в наблюдателе:
class My_Module_Model_Adminhtml_Observer
{
public function onBlockHtmlBefore(Varien_Event_Observer $observer) {
$block = $observer->getBlock();
if (!isset($block)) return;
switch ($block->getType()) {
case 'adminhtml/catalog_product_grid': //or here you can put any other block
/*For example i am using Mage_Adminhtml_Block_Catalog_Product_Grid, and want to add a column*/
$block->addColumn('COLUMN_ID', array(
'header' => Mage::helper('mymodule')->__('COLUMN HEADER'),
'index' => 'COLUMN_ID',
));
break;
case 'adminhtml/catalog_product_edit_tabs':
/*Or i want to add new tab to admin product edit*/
/* @var $block Mage_Adminhtml_Block_Catalog_Product_Edit_Tabs */
$block->addTab('tab_name', array(
'label' => Mage::helper('catalog')->__('Tab Tilte'),
'content' => $block->getLayout()->createBlock('modulename/adminhtml_product_edit_tabname')->toHtml(),
'after' => 'inventory',
));
break;
}
}
}
При добавлении вкладки вы можете использовать вкладки редактирования продукта, чтобы добавить свои поля формы в этот модуль, используя ваш модуль.
Надеюсь, это будет кому-то полезно:)