При расширении основных классов Magento, какую XML-структуру мне нужно изменить, чтобы мои изменения вступили в силу? - PullRequest
2 голосов
/ 06 декабря 2011

Я работаю с установкой Magento 1.3 (Community Edition) и пытаюсь расширить функциональность одного из базовых классов. Я изменил файл ядра непосредственно на сервере разработки и получил работающую там функциональность. Теперь, , следуя совету Алана Шторма , я возвращаю основные файлы обратно на склад и внедряю свои изменения в дереве /app/code/local. Я читал страницу Алана Шторма и руководство Джоша Пратта , но я не могу понять, как применить эти примеры к моему делу.

Суть вопроса в том, какую часть каркаса полноценного модуля Magento мне нужно реализовать для расширения основных классов / monkey-patch?

  • Нужно ли мне создавать собственное пространство имен?
  • Когда я называю классы, какие подчеркивания следует ожидать от синтаксически значимых?
  • Когда я пишу XML, какие теги соответствуют иерархии классов, а какие нет?
  • Какие другие части кода нужно будет изменить, чтобы воспользоваться моими изменениями, если таковые имеются?

По сути, я бы не хотел этого культивировать.

Подробности моего сценария: я пытаюсь изменить функциональность обзора продукта Magento. Код для этой функциональности живет в /app/code/core/Mage/Review/. Я добавляю дополнительный шаг к проверке на стороне сервера при отправке новых отзывов (в нашем магазине возникает проблема со спамом, поэтому я добавляю дополнительное поле формы, скрываю его от людей с помощью CSS и выкидываю отзывы, которые заполняют в этом поле формы, я делаю это таким образом, потому что CAPTCHA являются неоптимальным выбором пользовательского интерфейса). Я добавил код в метод /app/code/core/Mage/Review/controllers/ProductController.php Mage_Review_ProductController-> postAction () и метод /app/code/core/Mage/Review/Model/Review.php Mage_Review_Model_Review-> validate ().

Затем я изолировал добавленный код, поместил его в /app/code/local/Mage/Review/controllers/ProductController.php и /app/code/local/Mage/Review/Model/Review.php, использовал рекомендации "class My_Review_Foo extends Mage_Review_Foo" и "parent :: method" из учебных пособий Alan Storm. Это, как и ожидалось, сломало страницы продукта. Поэтому я работаю над /app/code/local/Mage/Review/etc/config.xml и пытаюсь выяснить, как заставить Magento использовать мои классы для расширения основных классов. К сожалению, я не могу сказать, что лежит в основе логики XML, поэтому я не могу понять, как создать правильный XML, чтобы сказать Magento - «использовать мои классы вместо базовых классов всякий раз, когда вы используете базовые классы . "

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

1 Ответ

6 голосов
/ 07 декабря 2011

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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...