Magento это все о конфигурации.Самый базовый функциональный модуль не будет содержать ничего, кроме конфигурационного XML, который добавляет или заменяет существующий конфигурационный XML.Тем не менее, большинство потребностей разработки требуют реализации конфигурации, которая добавляет дискретные новые функциональные возможности в систему и / или изменяет существующие функциональные возможности.
Существует два способа переписать блок (что соответствует «представлению» в MVC), вспомогательныйи модели классов, и они работают либо из-за порядка следования пути (установленного в классе-концентраторе Mage
и используемого Varien_Autoload
), либо - более уместно - посредством переписываний на основе конфигурации, которые оцениваются в методе Mage_Core_Model_Config::getGroupedClassName()
,Ниже приведены инструкции по перезаписи, основанные на переписывании Mage_Review_Model_Review
.
По замыслу (в качестве средства защиты) ни один из этих подходов не работает для контроллеров;в конечном итоге определения класса контроллера защищены от автоматической загрузки.Далее следует пояснение о том, как переписать классы контроллера действий с использованием устаревших средств (с 1.3.0 по 1.6.1.1 в настоящее время). Обратите внимание, что до Magento CE 1.3.0 способ переписать функциональность в классах контроллера действий был через конфигурационный XML.
Чтобы переписать определения контроллера, нужно понимать, как классы контроллера вызываются в Magentoи это происходит через классы маршрутизатора.Ядро Magento имеет четыре класса маршрутизаторов.Маршрутизаторы находятся между классом FrontController (Mage_Core_Controller_Front
) и отвечают за сопоставление запроса и изменение тела ответа.FrontController будет перебирать каждый класс, и каждый класс будет оцениваться, чтобы определить, должен ли он обрабатывать текущий запрос.Часто это вопрос конфигурации + соглашение о пути к файлу.По сути, Magento сопоставляет имя фронта с исходным каталогом, а затем сопоставляет остальную часть запроса с путем и файлом в этом каталоге.Например, буквальный путь к странице продукта в приложении может быть http://demo.magentocommerce.com/review/product/list/id/51/. В этой структуре URL review - это frontName (узел из конфигурации), и онотображается на app/code/core/Mage/Review/controllers/
.Оттуда product отображается на путь и имя файла в этом каталоге, то есть ProductController.php
, и оттуда разрешенный класс проверяется на list Action метод,Увидеть?review + product + list - это frontName, путь к классу контроллера и метод "разрешение параметров".Все, что после этого передается как параметр запроса (например, id = 51 ).
Начиная с CE 1.3.0, можно просто добавить свой класс контроллера действий в список каталогов, в которыхмаршрутизатор проверит разрешаемые пути (см. Mage_Core_Controller_Varien_Router_Standard::collectRoutes()
для получения дополнительной информации).Как это работает, типично для Magento: через config XML!Кстати, этот метод работает как для добавления новых путей к классам контроллера, так и для перезаписи контроллера.
Для модуля перезаписи контроллера потребуются как минимум три файла:
- файл объявления модуля (файл, оканчивающийся на
.xml
в каталоге app/etc/modules/
) - a
config.xml
в каталоге etc
модуля - файл контроллера с тем же разрешением пути, что и длякласс, который переписывается .В случае пути к классу «product» из вышеприведенного примера файл должен иметь имя
ProductController.php
и располагаться в верхней части добавляемого каталога контроллеров, иначе он не будет соответствовать параметрам разрешения класса.Кроме того, переписываемое действие должно совпадать с оригиналом по той же причине.
Файл декларации будет содержать следующее:
<?xml version="1.0" ?>
<config>
<modules>
<Example_Extension>
<active>true</true>
<codePool>local</codePool> <!-- or community -->
</Example_Extension>
</modules>
</config>
На основании вышеуказанного <Example_Extension>
и <codePool>
узлов, приложение будет пытаться загрузить app/code/local/Example/Extension/etc/config.xml
.В этом файле, если кто-то пытается переписать класс ProductController модуля Review, потребуется следующее:
<?xml version="1.0" ?>
<config>
<frontend>
<routers>
<review>
<args>
<modules>
<some_unique_node before="Mage_Review">Example_Extension</some_unique_node>
<!--
This will map to the controllers directory under the
app/code/local/Example/Extension/ directory. Had this
value been "Example_Extension_Rewrites", the mapping
would be to the
app/code/local/Example/Extension/controllers/Rewrites/
directory. That is just how controller class paths are
evaluated: with a "controllers" directory after two levels
of folders.
-->
</modules>
</args>
</review>
</routers>
</frontend>
</config>
Из-за атрибута before="Mage_Review"
каталог контроллеров модуля Example_Extension будет добавлен перед основным каталогом контроллера модуля обзора. Поэтому, если параметры контроллера и разрешения действия совпадают в модуле Example_Extension, будет использоваться его класс. Если нет, сценарий по умолчанию будет разыгран.
Наконец, оставшийся файл для создания - это сам класс контроллера действий. Если намерение состоит в том, чтобы наследовать от основной функциональности, то имеет смысл расширяться от базового класса. Однако для того, чтобы PHP мог загрузить определение для базового класса, на базовый класс нужно ссылаться напрямую, поскольку у PHP нет способа найти определение через автозагрузчик, как уже упоминалось. Это означает добавление require_once
перед переписанным определением класса.
<?php
require_once 'Mage'.DS.'Review'.DS.'controllers'.DS.'ProductController.php';
class Example_Extension_ProductController extends Mage_Review_ProductController
{
//rewritten and/or new method(s)
}
Как и в случае с блочными, вспомогательными и модельными классами в Magento, приложение ожидает, что у классов будет определенное имя, которое будет связано с их расположением в файловой системе.
Относительно модели (и блочного и вспомогательного) класс переписывается: нужно только добавить необходимый XML-код конфигурации и определение класса. Учитывая приведенные здесь примеры, перезапись Mage_Review_Model_Review
потребует добавления в файл config.xml для Example_Extension:
<config>
<!-- ... -->
<global>
<models>
<review>
<rewrite>
<review>Example_Extension_Model_Review</review>
</rewrite>
</review>
</models>
</global>
</config>
Исходя из этого, Mage::getModel('review/review')
(или Mage::getSingleton('review/review')
) будет внутренне сопоставляться с именем класса, данным в узле <rewrite>
, и будет возвращать переписанный экземпляр класса. Из-за того, как работает автозагрузчик (см. Varien_Autoload
в lib/Varien/Autoload.php
), определение этого класса должно быть расположено в Example/Extension/Model/Review.php
и должно находиться в codePool, указанном в файле объявления Example_Extension.
Надеюсь, это поможет. Для получения дополнительной информации, не стесняйтесь просматривать другие сообщения на SO, а также Magento U.