Как переопределить / переписать класс блока в Magento 1?

12

Примечание. Это задание является каноническим вопросом, который полностью объясняет, как работает перезапись блока, и может использоваться как дублирующая цель для более конкретных вопросов «Как переопределить блок X» или «Почему моя перезапись не работает».

Смотрите также: Поиск канонических вопросов о переопределениях Magento 1

Допустим, я должен внести изменения в класс базового блока в пользовательском модуле (изменить методы или добавить методы). Как мне это сделать, шаг за шагом?

Фабиан Шменглер
источник

Ответы:

23

Каждый блок или группа блоков объявляется в config.xmlфайле такого модуля (внутри <global>тега).
Вот пример из каталога модуля

    <blocks><!-- marks definition of a block group -->
        <catalog><!-- unique alias for blocks in the module -->
            <class>Mage_Catalog_Block</class><!-- class prefix for all blocks -->
        </catalog>
    </blocks>

Это означает, что для создания экземпляра блока можно использовать псевдоним, catalog/class_name_hereгде class_name_hereнаходится остальная часть пути к классу, начиная с префикса.
Это означает catalog/class_name_here, что по умолчанию будет отображаться на Mage_Catalog_Block_Class_Name_Here.

Чтобы переписать блок, вам нужно создать модуль, который зависит от модуля, который вы пытаетесь изменить ( Magento_Catalog) в моем примере.
И вам нужно добавить это в config.xmlпод <global>тегом.

<blocks>
    <catalog><!-- alias of the block group you are rewriting -->
        <rewrite><!-- reserved tag: specify that you are rewriting something -->
             <class_name_here>YourNamespace_YourModule_Block_Your_New_Class_Here</class_name_here> <!-- tag: the rest of the alias of the class you are rewriting. value: the name of your class that rewrites the core class -->
        </rewrite>
    </catalog>
</blocks>

Затем создайте класс YourNamespace_YourModule_Block_Your_New_Class_Here(следуя структуре папок ZF) и заставьте этот класс расширить исходный класс.

class YourNamespace_YourModule_Block_Your_New_Class_Here extends Mage_Catalog_Block_Class_Name_Here
{
    //your awesome code here
}

Когда вы закончите, отключите компиляцию и включите ее снова (при необходимости) и очистите кеш.

Это не будет работать для абстрактных блоков.
Это работает только для классов, которые создаются.

пример

Предположим, что вы хотите переписать файл app \ code \ core \ Mage \ Catalog \ Block \ Product \ View \ Options \ Type \ Select.php, который имеет класс Mage_Catalog_Block_Product_View_Options_Type_Selectв вашем собственном модуле Marius_Test .

Тогда вам понадобится эта запись в вашем config.xml:

<blocks>
    <catalog>
        <rewrite>
            <product_view_options_type_select>Marius_Test_Block_Catalog_Block_Product_View_Options_Type_Select</product_view_options_type_select>
        </rewrite>
    </catalog>
</blocks>

app \ code \ local \ Marius \ Test \ Block \ Catalog \ Product \ View \ Options \ Type \ Select.php :

class Marius_Test_Block_Catalog_Product_View_Options_Type_Select extends Mage_Catalog_Block_Product_View_Options_Type_Select
{
    //your awesome code here
}
Мариус
источник
Не работает. Я пытаюсь перезаписать класс Mage_Catalog_Block_Product_View_Options_Type_Selectв app \ code \ local \ WR \ EPO \ Block \ Catalog \ Block \ Product \ View \ Options \ Type \ Select.php . Я попробовал это так: codepen.io/anon/pen/WYOqBr
черный
И если это не сработает, вы думаете, что мой ответ неверен, поэтому вы его отрицаете, вместо того, чтобы думать, что, возможно, вы делаете что-то не так. В любом случае ... замените это <Mage_Catalog_Block_Product_View_Options_Type_Select> WR_EPO_Block_Catalog_Block_Product_View_Options_Type_Select </Mage_Catalog_Block_Product_View_Options_Type_Select>на <product_view_options_type_select>WR_EPO_Block_Catalog_Block_Product_View_Options_Type_Select</product_view_options_type_select>и убедитесь, что внутри нет пробеловproduct_view_options_type_select
Мариус
Я понизил голос, потому что ваш ответ не был точным, и хотя я следовал ему шаг за шагом, не дал правильного результата. Вы написали, что мы должны использовать имя класса, поэтому я использовал его, и это не сработало. Мы должны использовать product_view_options_type_selectвместо реального имени класса Mage_Catalog_Block_Product_View_Options_Type_Select. Если вы измените свой ответ соответственно, я буду голосовать.
черный
Если вы читаете это шаг за шагом, вы пропустили шаг. Тот, где я объясняю, что такое псевдоним класса. Если вы просто скопируете вставку и замените ее, вы получите ее. 17 человек поняли. Я думаю, что я объяснил это правильно
Мариус
Да, но хороший пример отсутствует, поэтому мы можем быть уверены, что правильно поняли вашу теорию
Black
4

Для моей точки зрения переопределить и переписать эти две разные вещи,

Override:

Когда мы используем механизм отката дизайна, мы делаем переопределение

Перепишите:

Когда мы переписываем базовые классы magento в нашем классе, мы делаем переписывание.

1) Пример переопределения:

Если мне нужно переопределить app/code/core/Mage/Catalog/Block/Product/List.phpфайл, то я копирую в свой локальный модуль с тем же путем, как показано нижеapp/code/local/Mage/Catalog/Block/Product/List.php

Это не предложено magento, но вы можете сделать это.

2) Пример переписывания:

Если я хочу переписать этот класс блоков, Mage_Adminhtml_Block_Sales_Order_Createя пишу код в моем модуле config.xml, как показано ниже

    <global>
        <blocks>
            <adminhtml>
                <rewrite>

                    <sales_order_create>Trimantra_Smallchanges_Block_Adminhtml_Sales_Order_Create</sales_order_create>
                </rewrite>
            </adminhtml>
        </blocks>
    </global>

И в моем классе Trimantra_Smallchanges_Block_Adminhtml_Sales_Order_Create

Я кодирую как ниже

class Trimantra_Smallchanges_Block_Adminhtml_Sales_Order_Create extends Mage_Adminhtml_Block_Sales_Order_Create {
      My Function Or funcions That I want to Rewrite..
}
Муртуза Забуавала
источник
2

Здесь важно добавить, что переписывание блоков (как и всех других переписываний модулей Magento) подразумевает более высокие усилия по обслуживанию и, следовательно, должно рассматриваться как последний шанс расширить функциональность после манипулирования конфигурацией, событий и настройки темы.

Потенциальная проблема 1. Переписанный шаблон не будет обновляться, когда вы или другой сопровождающий обновите исходные файлы Magento. Означает, что исправление или улучшение безопасности не будут применены к вашему коду. То же относится и к другим переписанным классам, включая блоки, но зависит от того, сколько было выполнено перезаписи (см. Ниже).

Потенциальная проблема 2. Может показаться, что перезаписанный блок (или другой класс) перезаписан другим расширением, которое вы или другой сопровождающий попытаетесь установить. Тогда вам придется разрешить этот конфликт.

Альтернатива 1: используйте события, то есть копайтесь в коде, который вы собираетесь переписать, и проверьте, есть ли события, которые могут быть использованы для достижения желаемой функциональности.

Альтернатива 2: переписать смарт, т. Е. Осмотреться: возможно, проверьте место, где создается экземпляр класса, который вы собираетесь переписать, и проверьте, можете ли вы повлиять на то, какой класс выбирается через конфигурацию или события; может быть, есть класс, который позволяет вам переопределить метод с 3 строками, чтобы заменить имя класса вместо копирования метода с 30 строками из исходного класса в переписанный.

Антон Борицкий
источник