переопределение блока 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 сделать это или это единственный способ прокомментировать конфигурацию (что я и сделал на данный момент), включая все хлопоты при обновлении этого модуля позже?

Author: Uwe Mesecke, 2010-01-29

4 answers

Если вы установите для своего модуля значение "зависеть" от того, который также выполняет перезапись, ваша конфигурация будет прочитана последней, и перезапись должна сохраниться в соответствующем файле в приложении/etc/modules, который у вас должен быть:

<config>
  <modules>
    <Your_Module>
      <active>true</active>
      <codePool>local</codePool>
      <depends>
        <Other_Module/>
      </depends>
    </Your_Module>
  <modules>
<config>
 9
Author: Greg, 2010-01-29 20:22:33

Я посмотрел загрузку класса, и не похоже, что есть чистое решение. Соответствующий код загрузки имени класса выглядит следующим образом:

    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 на ваше действие. Боль, но, по крайней мере, достигает своей цели.

Надеюсь, это поможет,

Джо

 0
Author: Joseph Mastey, 2010-01-29 16:28:43

Вместо перезаписи 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.

 0
Author: ajpevers, 2013-06-19 17:22:57

Лучший способ преодолеть эту проблему, используя макет после или до наблюдателя.

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;
    }
  }
}

При добавлении вкладки вы можете использовать вкладки редактирования продукта, чтобы добавить свои поля формы в этот модуль, используя ваш модуль.

Надеюсь, это будет кому-то полезно:)

 0
Author: Kumar M, 2014-10-01 13:15:38