Magento: метод saveAction перегрузки Adminhtml/Productcontroller не будет работать…?

Я хочу перегрузить метод saveAction из ядра/Mage/Adminhtml/controllers/Catalog/ProductController.php и это не сработает - я сейчас целый день искал и пробовал :(

Предыстория: я хочу изменить значение пользовательского атрибута перед сохранением продукта. Я узнал, что _initProductSave устанавливает атрибуты, и я думаю, что изменить их после init_ProductSave было бы неплохо (если кто-нибудь знает лучшее место, пожалуйста, дайте мне знать) ...

МОЖЕТ КТО-НИБУДЬ ПОМОГИТЕ МНЕ... :)

Версия Magento: Community Edition версии 1.7.0.1 Без расширений, тем не установлено, я только что установил эту версию совершенно пустой...

ВЕРСИЯ 1: перезапись контроллера путем копирования в локальную папку/папку Mage

Прежде всего, я попытался скопировать файл в папку app/code/local в правильной структуре, но это не сработает (я сделал это с помощью Varient.php для локальной тестовой системы и store.php для исправления ошибок). баг с ценой - у обоих работает...)

ВЕРСИЯ 2: перезапись контроллера расширением

Мое расширение выглядит так:

Структура файла:

code/local/MyOne/MyExtension/controllers/Catalog/ProductController.php 
code/local/MyOne/MyExtension/etc/config.xml 
etc/modules/MyOne_MyExtension.xml

Файлы выглядят следующим образом: MyOne_MyExtension.xml:

<?xml version="1.0" encoding="UTF-8"?>
<config>
    <modules>
        <MyOne_MyExtension>
            <active>true</active>
            <codePool>local</codePool>
        </MyOne_MyExtension>
    </modules>
</config>

code/local/MyOne/MyExtension/etc/config.xml:

<?xml version="1.0" encoding="UTF-8"?>
<config>
    <modules>
        <MyOne_MyExtension>
            <version>1.0.0</version>
        </MyOne_MyExtension>
    </modules>
    <admin>
        <routers>
            <adminhtml>
                <args>
                    <modules>
                        <MyOne_MyExtension before="Mage_Adminhtml">MyOne_MyExtension_Catalog_ProductController</MyOne_MyExtension>
                    </modules>
                </args>
            </adminhtml>
        </routers>
    </admin>
</config>

и последний, code/local/MyOne/MyExtension/controllers/Catalog/ProductController.php:

<?php
require_once 'Mage/Adminhtml/controllers/Catalog/ProductController.php';

class MyOne_MyExtension_Catalog_ProductController extends Mage_Adminhtml_Catalog_ProductController
{
    public function saveAction()
    {
        // do my stuff
        die('reached method');
        // after pressing on save, there should no be a white screen ...
    }
}
?>

Я столько гуглил и читал, ошибки не вижу...

Любая помощь будет действительно здорово !!!

Привет, Матиас


person matttrakker    schedule 01.07.2012    source источник


Ответы (2)


Примечание: Учитывая выбранный метод...

Mage_Adminhtml_Catalog_ProductController->_initProductSave()

... было бы лучше исключить использование наблюдателя с областью действия adminhtml, потребляющего событие catalog_product_save_before.


"Прежде всего я попытался скопировать файл в папку app/code/local в правильной структуре..."

Это нередкий подход разработчиков, но он никогда не сработает. Классы контроллера действий Magento не загружаются автозагрузчиком. Они явно загружаются по их реальному пути в файловой системе. Следовательно, так называемый «взлом пути включения» не применяется.

Ссылка Mage_Core_Controller_Varien_Router_Standard->getControllerFileName()< /а>.

Ваш второй подход - выполнение перезаписи с правильным пользовательским расширением - является правильным подходом. Все, что вам нужно, это понять, как Magento находит каталоги контроллеров действий и сопоставляет классы контроллеров действий с URL-адресом запроса.

В своем config.xml модуль Mage_Adminhtml настраивает маршрутизатор администратора, который отвечает за соответствие всем запросам, связанным с администрированием:

<admin>
    <routers>
        <adminhtml>
            <use>admin</use>
            <args>
                <module>Mage_Adminhtml</module>
                <frontName>admin</frontName>
            </args>
        </adminhtml>
    </routers>
</admin>

Предыдущий фрагмент конфигурации делает две вещи: узел <frontName /> добавляет маршрут модуля, а узел <module /> вместе с зарегистрированным значением Mage_Adminhtml <codePool /> («ядро») устанавливает каталог, в котором можно найти класс контроллера действий, в данном случае /[basepath]/app/code/core/Mage/Adminhtml/controllers/.

Контроллер действий модуля переписывает работу, добавляя другие подходящие каталоги к существующему маршруту модуля. Это все разбирается из конфигурации:

<admin>
    <routers>
        <adminhtml>
            <args>
                <modules>
                    <MyOne_MyExtension before="Mage_Adminhtml">MyOne_MyExtension_Catalog_ProductController</MyOne_MyExtension>
                </modules>
            </args>
        </adminhtml>
    </routers>
</admin>

Как видно, приведенная выше конфигурация просто добавляет или добавляет к узлу admin/routers/adminhtml/args/ при компиляции XML конфигурации. То, как это интерпретируется и используется для сопоставления запросов, очень похоже на «нормальный» процесс сопоставления контроллеров. В приведенном выше примере модуль MyOne_MyExtension эффективно добавляет каталог в список каталогов для модуля Adminhtml. Предполагая, что он находится в local codePool, приведенный выше пример указывает на каталог

/[basepath]/app/code/local/MyOne/MyExtension/controllers/Catalog/ProductController/

Это сработало бы, если бы в

/[basepath]/app/code/local/MyOne/MyExtension/controllers/Catalog/ProductController/Catalog/ProductController.php

который содержал метод _initProductSave() в классе с именем

MyOne_MyExtension_Catalog_ProductController_Catalog_ProductController

Надеюсь, этого объяснения достаточно, чтобы увидеть, что перезапись контроллера на основе конфигурации работает на уровне каталога, а не путем указания определенного класса (именно так работает перезапись блока, помощника и модели). Поскольку эта конфигурация добавляет каталог, она не должна приводить к перезаписи, поскольку ее можно использовать для простого добавления новых действий для данного модуля. В конечном счете, перезапись контроллера действия происходит только в том случае, если какой-либо другой класс контроллера соответствует до «исходного» класса контроллера.

person benmarks    schedule 01.07.2012
comment
Этот тоже правильный... :) БОЛЬШОЕ СПАСИБО!!! (Спас мой день ;)) @benmarks: решение Даниэля также является результатом вашего очень хорошего объяснения, верно? - person matttrakker; 01.07.2012
comment
и, конечно, я читал о лучшей практике с наблюдателем, я тоже завтра протестирую :) - person matttrakker; 01.07.2012

Поскольку Magento нужно знать только имя модуля, чтобы найти путь к соответствующему контроллеру,

Изменять:

<MyOne_MyExtension before="Mage_Adminhtml">MyOne_MyExtension_Catalog_ProductController</MyOne_MyExtension>

to:

<MyOne_MyExtension before="Mage_Adminhtml">MyOne_MyExtension</MyOne_MyExtension>
person Daniel Sloof    schedule 01.07.2012
comment
Проверено - это решение работает ... Полное объяснение того, что я сделал неправильно, приведено ниже. Спасибо большое за вашу помощь ! - person matttrakker; 01.07.2012
comment
В данном случае код правильный, но объяснение неверное. - person benmarks; 01.07.2012
comment
это правильно, судя по коду, работает, судя по объяснению, ваш ответ правильный :) [извините, Даниэль;)] - person matttrakker; 02.07.2012