Как По-Правильному Вносить Изменения В Движок Magento?

Модуль «Полностраничное кэширование» ускоряет Magento Community Edition в 30 раз!
Модуль «Удобное оформление заказа» (одностраничная покупка) включён в Российскую сборку.
#1 Дмитрий Федюк
  • Администратор
  • Иконка
  • Группа: Администраторы
  • Сообщений: 4994
  • Регистрация: 20.02.2010
  • ГородРоссия, Москва

22.03.2010 17:07

Как посредством самописного модуля изменить поведение системных объектов Magento?

Для начала прочтите вводную статью о модульности архитектуры Magento.
Во вводной статье была теория, теперь пора перейти к практике.
Статья предназначена для программистов.

Для примера рассмотрим конкретную задачу: изменение алгоритма формирования URL key при создании нового товарного раздела (категории) в административном интерфейсе Magento.

Что такое URL key?
Magento использует URL key для формирования адресов страниц товарных разделов (и собственно товаров, но это вне рамок темы).

В чём проблема с URL key в Magento?
Системный класс Mage_Catalog_Model_Category неправильно производит транслитерацию русских букв.
Если ваш товарный раздел называется "Суши", то Magento добавит в адрес страницы: "d-n-n-d".
Изображение

Несмертельный баг, но в качестве учебного примера пойдёт.

Как бы вы поступили, будь у вас другой движок?
Вы бы поиском по системным файлам нашли бы участок кода, который формирует URL key, и внесли бы в него правки.
Чем это плохо, я писал во введении.

В чём отличие подхода Magento?
В Magento можно написать свой модуль, подключить его к Magento и тем самым переопрелить поведение движка (в данном случае: исправить дефект).

Итак, переходим к воплощению замысла.
Для начала прочтите, как написать самый простой модуль Magento.

Теперь пошаговая инструкция, как патчить системный класс Mage_Catalog_Model_Category:

1) Создаю папку app/code/local/Fediuk/CorePatches
Этот модуль у меня для заплаток к ядру.

2) Создаю app/etc/modules/Fediuk_CorePatches.xml
Туда помещаю стандартный код:
<?xml version="1.0"?>
<config>
	<modules>
		<Fediuk_CorePatches>
			<active>true</active>
			<codePool>local</codePool>
		</Fediuk_CorePatches>
	</modules>
</config>


2) Создаю свой класс app/code/local/Fediuk/CorePatches/Model/Category.php: наследник от системного класса. Перекрываю нужный метод:


class Fediuk_CorePatches_Model_Category extends Mage_Catalog_Model_Category {
    public function formatUrlKey($str) {
        $urlKey = preg_replace('#[^0-9a-z]+#i', '-', Mage::helper('catalog/product_url')->format($str));
        $urlKey = strtolower($urlKey);
        $urlKey = trim($urlKey, '-');
        return $urlKey;
    }
}



3) Теперь говорю Magento, что вместо Mage_Catalog_Model_Category надо загружать Fediuk_CorePatches_Model_Category:
Для этого пишу такой конфиг для своего модуля:
app/code/local/Fediuk/CorePatches/etc/config.xml


<?xml version="1.0" encoding="utf-8"?>
<config>
	<modules>
		<Fediuk_CorePatches>
			<version>0.1.0</version>
		</Fediuk_CorePatches>
	</modules>
	<global>
		<models>
			<catalog>
				[b]<rewrite>[/b]
					<category>Fediuk_CorePatches_Model_Category</category>
				[b]</rewrite>[/b]
			</catalog>
		</models>
	</global>
</config>



Теперь очищаем кеш и любуемся результатом: слово "суши" будет транслитерироваться в ссылке как "sushi", а не как "d-n-n-d".

#2 roman
  • Продвинутый пользователь
  • PipPipPip
  • Группа: Пользователи
  • Сообщений: 79
  • Регистрация: 03.05.2010

07.05.2010 23:12

Вечер добрый!

Всё сделал по вашей инструкции, на все файлы выставил даже права доступа 777

Но выдало ошибку при нажатии в админки на пункт меню категории

class Fediuk_CorePatches_Model_Category extends Mage_Catalog_Model_Category { public function formatUrlKey($str) { $urlKey = preg_replace('#[^0-9a-z]+#i', '-', Mage::helper('catalog/product_url')->format($str)); $urlKey = strtolower($urlKey); $urlKey = trim($urlKey, '-'); return $urlKey; } }
Fatal error: Call to a member function setStoreId() on a non-object in /home/karliin/public_html/shop/app/code/core/Mage/Adminhtml/controllers/Catalog/CategoryController.php on line 52

Даже не менял Вашу фамилию, в знак уважения =)

#3 Дмитрий Федюк
  • Администратор
  • Иконка
  • Группа: Администраторы
  • Сообщений: 4994
  • Регистрация: 20.02.2010
  • ГородРоссия, Москва

08.05.2010 11:47

1) Кеш Magento обновили?
2) Виден ли модуль активным в административной части Magento?
3) Действительно ли системный класс перекрылся? Добавите Mage::log (__FILE__); в новый метод formatUrlKey и проверьте, что он вызывается.

#4 roman
  • Продвинутый пользователь
  • PipPipPip
  • Группа: Пользователи
  • Сообщений: 79
  • Регистрация: 03.05.2010

08.05.2010 13:26

Просмотр сообщенияДмитрий Федюк (08.05.2010 11:47) писал:

1) Кеш Magento обновили?
2) Виден ли модуль активным в административной части Magento?
3) Действительно ли системный класс перекрылся? Добавите Mage::log (__FILE__); в новый метод formatUrlKey и проверьте, что он вызывается.


Кеш обновлял несколько раз.

Fediuk_CorePatches модуль включен и стоит в списке первым.

Может мне скинуть файлы, которые я делал по Вашей инструкции.

Или Вы скиньте правильный вариант, мне кажется в моих файлах есть ошибка.

Ну и как вариант может опять виноваты права доступа на сервере, хотя я везде без проблем выставил 777(на все созданные папки и файлы).

Жду ответ

#5 GG
  • Группа: Гости

08.05.2010 14:03

Перед
class Fediuk_CorePatches_Model_Category extends Mage_Catalog_Model_Category {
....

в файле app/code/local/Fediuk/CorePatches/Model/Category.php добавьте <?php, вот так
<?php
class Fediuk_CorePatches_Model_Category extends Mage_Catalog_Model_Category {
.....


#6 roman
  • Продвинутый пользователь
  • PipPipPip
  • Группа: Пользователи
  • Сообщений: 79
  • Регистрация: 03.05.2010

08.05.2010 14:20

В списке модулей поностью пропал модуль Fediuk'a

Соответственно названия категорий тоже нормальными не становятся.

Кеш обновлял, пробовал вносить новую категорию - результат отрицательный d-d-d

Может скинете файлы уже готовые, чтобы просто их закинуть на сервер - буду очень признателен :)

Мой код в файле Category.php
<?php
class Fediuk_CorePatches_Model_Category extends Mage_Catalog_Model_Category {


    public function formatUrlKey($str) {

        $urlKey = preg_replace('#[^0-9a-z]+#i', '-', Mage::helper('catalog/product_url')->format($str));

        $urlKey = strtolower($urlKey);

        $urlKey = trim($urlKey, '-');

        return $urlKey;

    }

}
?>


#7 _GG_
  • Новичок
  • Pip
  • Группа: Пользователи
  • Сообщений: 1
  • Регистрация: 08.05.2010

08.05.2010 14:34

Нужно добавить только <?php без ?> в конце файла

#8 roman
  • Продвинутый пользователь
  • PipPipPip
  • Группа: Пользователи
  • Сообщений: 79
  • Регистрация: 03.05.2010

08.05.2010 14:51

Просмотр сообщения_GG_ (08.05.2010 14:34) писал:

Нужно добавить только <?php без ?> в конце файла


Убрал - ничего не поменялось.

Он почему то в списке модулей отсутсвует.

Скиньте пожалуйста в rar архиве собственные файлы - я закину к себе на сервер.

Также посмотрю код и сделаю анализ своих ошибок.

#9 Дмитрий Федюк
  • Администратор
  • Иконка
  • Группа: Администраторы
  • Сообщений: 4994
  • Регистрация: 20.02.2010
  • ГородРоссия, Москва

08.05.2010 16:15

Magento: исправляем транслитерацию названий товарных категорий (готовый модуль)

#10 holyfreak
  • Продвинутый пользователь
  • PipPipPip
  • Группа: Пользователи
  • Сообщений: 41
  • Регистрация: 21.07.2010

17.08.2010 10:39

при добавлении <?php все стало нормально работать урлу переводит отлично!

#11 Faradey
  • Новичок
  • Pip
  • Группа: Пользователи
  • Сообщений: 8
  • Регистрация: 29.03.2011
  • ГородОдесса

29.03.2011 17:51

А подскажите как можно переопределить вот этот блок Mage_Adminhtml_Block_Sales_Order_Shipment_Create который находиться вот здесь app\code\core\Mage\Adminhtml\Block\Sales\Order\Shipment\Create.php ??? на примере даже на вашего модуля

Благодарю

#12 Дмитрий Федюк
  • Администратор
  • Иконка
  • Группа: Администраторы
  • Сообщений: 4994
  • Регистрация: 20.02.2010
  • ГородРоссия, Москва

29.03.2011 17:54

Для блоков можно использовать тег
<rewrite></rewrite>
точно так же, как и для моделей.
Рекомендую скачать какой-либо модуль из Magento Connect и посмотреть его устройство.

#13 Faradey
  • Новичок
  • Pip
  • Группа: Пользователи
  • Сообщений: 8
  • Регистрация: 29.03.2011
  • ГородОдесса

29.03.2011 17:55

Просмотр сообщенияДмитрий Федюк (29.03.2011 17:54) писал:

Для блоков можно использовать тег
<rewrite></rewrite>
точно так же, как и для моделей.
Рекомендую скачать какой-либо модуль из Magento Connect и посмотреть его устройство.


то есть вот так ????

<adminhtml>
<block>
<sales>
<order>
<shipment>
<rewrite>
</rewrite>
</shipment>
</order>
</sales>
</block>
</adminhtml>

#14 Дмитрий Федюк
  • Администратор
  • Иконка
  • Группа: Администраторы
  • Сообщений: 4994
  • Регистрация: 20.02.2010
  • ГородРоссия, Москва

29.03.2011 17:57

Да.

#15 Faradey
  • Новичок
  • Pip
  • Группа: Пользователи
  • Сообщений: 8
  • Регистрация: 29.03.2011
  • ГородОдесса

29.03.2011 17:59

извините, но еще пол вопроса
и это все должно находиться в <global></global> ???

#16 Дмитрий Федюк
  • Администратор
  • Иконка
  • Группа: Администраторы
  • Сообщений: 4994
  • Регистрация: 20.02.2010
  • ГородРоссия, Москва

29.03.2011 18:01

Да.

#17 Faradey
  • Новичок
  • Pip
  • Группа: Пользователи
  • Сообщений: 8
  • Регистрация: 29.03.2011
  • ГородОдесса

30.03.2011 13:34

Просмотр сообщенияFaradey (29.03.2011 17:55) писал:

то есть вот так ????

<adminhtml>
<block>
<sales>
<order>
<shipment>
<rewrite>
</rewrite>
</shipment>
</order>
</sales>
</block>
</adminhtml>

<adminhtml>
            <block>
                <sales>
                    <order>
                        <shipment>
                            <rewrite>
<create>Mycompany_MyModule_Block_Sales_Order_Shipment_Create</create>
</rewrite>
                        </shipment>
                    </order>
                </sales>
            </block>
        </adminhtml>

я папки повторил как в оригинальном блоке
все таки так не работает
Как можно отслеживать переопределение??? Если возможно вообще???

#18 Дмитрий Федюк
  • Администратор
  • Иконка
  • Группа: Администраторы
  • Сообщений: 4994
  • Регистрация: 20.02.2010
  • ГородРоссия, Москва

30.03.2011 13:45

Нет, не так. Вы точно уже выполнили мою рекомендацию?

#19 Faradey
  • Новичок
  • Pip
  • Группа: Пользователи
  • Сообщений: 8
  • Регистрация: 29.03.2011
  • ГородОдесса

30.03.2011 14:21

Просмотр сообщенияДмитрий Федюк (30.03.2011 13:45) писал:

Нет, не так. Вы точно уже выполнили мою рекомендацию?


Какую именно Вашу рекомендацию??
вот полный конфиг моего модуля.

<?xml version="1.0"?>
<config>
    <modules>
        <Infomodus_Upslabel>
            <version>0.1.0</version>
        </Infomodus_Upslabel>
    </modules>
    <frontend>
        <routers>
            <upslabel>
                <use>standard</use>
                <args>
                    <module>Infomodus_Upslabel</module>
                    <frontName>upslabel</frontName>
                </args>
            </upslabel>
        </routers>
        <layout>
            <updates>
                <upslabel>
                    <file>upslabel.xml</file>
                </upslabel>
            </updates>
        </layout>
    </frontend>
    <admin>
        <routers>
            <upslabel>
                <use>admin</use>
                <args>
                    <module>Infomodus_Upslabel</module>
                    <frontName>upslabel</frontName>
                </args>
            </upslabel>
        </routers>
    </admin>
    <adminhtml>
        <menu>
            <upslabel module="upslabel">
                <title>Upslabel</title>
                <sort_order>71</sort_order>
                <children>
                    <items module="upslabel">
                        <title>Manage Items</title>
                        <sort_order>0</sort_order>
                        <action>upslabel/adminhtml_upslabel</action>
                    </items>
                </children>
            </upslabel>
        </menu>
        <acl>
            <resources>
                <all>
                    <title>Allow Everything</title>
                </all>
                <admin>
                    <children>
                        <system>
                            <children>
                                <config>
                                    <children>
                                        <upslabel>
                                            <title>UPS Label</title>
                                        </upslabel>
                                    </children>
                                </config>
                            </children>
                        </system>
                        <general>
                            <children>
                                <upslabel translate="title">
                                    <title>UPS Label</title>
                                    <sort_order>40</sort_order>
                                </upslabel>
                            </children>
                        </general>
                        <Infomodus_Upslabel>
                            <title>Upslabel Module</title>
                            <sort_order>10</sort_order>
                        </Infomodus_Upslabel>
                    </children>
                </admin>
            </resources>
        </acl>
        <layout>
            <updates>
                <upslabel>
                    <file>upslabel.xml</file>
                </upslabel>
            </updates>
        </layout>
    </adminhtml>
    <global>
        <models>
            <upslabel>
                <class>Infomodus_Upslabel_Model</class>
                <resourceModel>upslabel_mysql4</resourceModel>
            </upslabel>
            <upslabel_mysql4>
                <class>Infomodus_Upslabel_Model_Mysql4</class>
                <entities>
                    <upslabel>
                        <table>upslabel</table>
                    </upslabel>
                </entities>
            </upslabel_mysql4>
        </models>
        <resources>
            <upslabel_setup>
                <setup>
                    <module>Infomodus_Upslabel</module>
                </setup>
                <connection>
                    <use>core_setup</use>
                </connection>
            </upslabel_setup>
            <upslabel_write>
                <connection>
                    <use>core_write</use>
                </connection>
            </upslabel_write>
            <upslabel_read>
                <connection>
                    <use>core_read</use>
                </connection>
            </upslabel_read>
        </resources>
        <blocks>
            <upslabel>
                <class>Infomodus_Upslabel_Block</class>
            </upslabel>
        </blocks>
        <helpers>
            <upslabel>
                <class>Infomodus_Upslabel_Helper</class>
            </upslabel>
        </helpers>
        <adminhtml>
            <block>
                <sales>
                    <order>
                        <shipment>
                            <rewrite>
                                <create>Infomodus_Upslabel_Block_Sales_Order_Shipment_Create</create>
                                </rewrite>
                        </shipment>
                    </order>
                </sales>
            </block>
        </adminhtml>
    </global>
</config>


если что здесь не так, можете пожалуйста указать в какой строке??? Блин уже неделю бьюсь об эту стену, а модуль уже нужно сдать заказчику вчера еще :( Я конечно могу напрямую его исправить или через local сделать, но мне нужно чтобы это был полноценный модуль.

#20 Дмитрий Федюк
  • Администратор
  • Иконка
  • Группа: Администраторы
  • Сообщений: 4994
  • Регистрация: 20.02.2010
  • ГородРоссия, Москва

30.03.2011 14:23

Вы процитировали моё сообщение, но перешли ли вы по ссылке? Рекомендация, очевидно, именно там.

#21 Faradey
  • Новичок
  • Pip
  • Группа: Пользователи
  • Сообщений: 8
  • Регистрация: 29.03.2011
  • ГородОдесса

30.03.2011 15:10

Просмотр сообщенияДмитрий Федюк (30.03.2011 14:23) писал:

Вы процитировали моё сообщение, но перешли ли вы по ссылке? Рекомендация, очевидно, именно там.


хорошо, подскажите какой именно лучше всего скачать модуль для этой цели ???

#22 Дмитрий Федюк
  • Администратор
  • Иконка
  • Группа: Администраторы
  • Сообщений: 4994
  • Регистрация: 20.02.2010
  • ГородРоссия, Москва

30.03.2011 15:14

Один из самых сложных среди доступных бесплатно и с открытым исходным кодом - AW Blog.
Изучая его программный код - можно многому научиться.

#23 Faradey
  • Новичок
  • Pip
  • Группа: Пользователи
  • Сообщений: 8
  • Регистрация: 29.03.2011
  • ГородОдесса

30.03.2011 15:20

Просмотр сообщенияДмитрий Федюк (30.03.2011 15:14) писал:

Один из самых сложных среди доступных бесплатно и с открытым исходным кодом - AW Blog.
Изучая его программный код - можно многому научиться.


Спасибо, буду его копать.

#24 Faradey
  • Новичок
  • Pip
  • Группа: Пользователи
  • Сообщений: 8
  • Регистрация: 29.03.2011
  • ГородОдесса

31.03.2011 13:36

Дмитрий, я Вам премного благодарен! Спасибо за Ваше терпение. Вот то что мне нужно было
http://www.cervic.info/2011/03/pereopredelenie-blokov-block-v-magento/ 

Может еще кому поможет.
Ага спасибо за исправление, только вот я Вашу ссылку показал как есть. :(

#25 redwert
  • Новичок
  • Pip
  • Группа: Пользователи
  • Сообщений: 7
  • Регистрация: 26.03.2010

22.07.2011 21:08

Здравствуйте, я пытаюсь заменить файл Links.php в Mage/Checkout/Block
Создал свой модуль с помощью modulecreator. Сделал все как по инструкии, но ничего не происходит. Помогите пожплуйста.
Вот мой config.xml
<?xml version="1.0"?>
<config>
        <modules>
                <My_Toplinks>
                        <version>0.1.0</version>
                </My_Toplinks>
        </modules>
        <global>
                <block>
                        <Checkout>
								<rewrite>
                                       <links>My_Toplinks_Block_Links</links>
								</rewrite>
						</Checkout>
                </block>
        </global>
</config>


Вот собственно сам links.php из My/Toplinks/Block
    <?php
	class My_Toplinks_Block_Links extends Mage_Checkout_Block_Links
    {
		public function addCheckoutLink()
    {
        if (!$this->helper('checkout')->canOnepageCheckout() || Mage::helper('checkout/cart')->getItemsCount() < 1) {
    return $this;
} 

        $parentBlock = $this->getParentBlock();
        if ($parentBlock && Mage::helper('core')->isModuleOutputEnabled('Mage_Checkout')) {
            $text = $this->__('Checkout');
            $parentBlock->addLink($text, 'checkout', $text, true, array(), 60, null, 'class="top-link-checkout"');
        }
        return $this;
    }
	}




#26 Дмитрий Федюк
  • Администратор
  • Иконка
  • Группа: Администраторы
  • Сообщений: 4994
  • Регистрация: 20.02.2010
  • ГородРоссия, Москва

22.07.2011 21:10

Описали ли вы ваш модуль в app/etc/modules?

#27 redwert
  • Новичок
  • Pip
  • Группа: Пользователи
  • Сообщений: 7
  • Регистрация: 26.03.2010

22.07.2011 21:18

Да, вот содержимое:
<?xml version="1.0"?>
<config>
    <modules>
        <My_Toplinks>
            <active>true</active>
            <codePool>local</codePool>
        </My_Toplinks>
    </modules>
</config> 


#28 Дмитрий Федюк
  • Администратор
  • Иконка
  • Группа: Администраторы
  • Сообщений: 4994
  • Регистрация: 20.02.2010
  • ГородРоссия, Москва

22.07.2011 21:20

Виден ли ваш модуль в административном разделе System -> Configuration -> Advanced?

#29 redwert
  • Новичок
  • Pip
  • Группа: Пользователи
  • Сообщений: 7
  • Регистрация: 26.03.2010

22.07.2011 21:21

Просмотр сообщенияДмитрий Федюк (22.07.2011 21:20) писал:

Виден ли ваш модуль в административном разделе System -> Configuration -> Advanced?

Да, в админке модуль виден и включен.
Кеш на сайте также обновил

#30 Дмитрий Федюк
  • Администратор
  • Иконка
  • Группа: Администраторы
  • Сообщений: 4994
  • Регистрация: 20.02.2010
  • ГородРоссия, Москва

22.07.2011 21:30

Попробуйте отключить кеш и написать тег checkout внутри тега block маленькими муквами.

#31 redwert
  • Новичок
  • Pip
  • Группа: Пользователи
  • Сообщений: 7
  • Регистрация: 26.03.2010

22.07.2011 21:45

Исправил, но все равно не хочет работать. Я уже все пересмотрел по несколько раз - не пойму в чем дело

#32 Дмитрий Федюк
  • Администратор
  • Иконка
  • Группа: Администраторы
  • Сообщений: 4994
  • Регистрация: 20.02.2010
  • ГородРоссия, Москва

22.07.2011 21:51

Надо писать blocks, а не block.

#33 redwert
  • Новичок
  • Pip
  • Группа: Пользователи
  • Сообщений: 7
  • Регистрация: 26.03.2010

22.07.2011 21:55

Респект, Дмитрий, большое спасибо. Все заработало)))

Поделиться темой: