Российская сборка Magento способна обнаруживать такие конфликты.
При обнаружении такого конфликта Российская сборка Magento отображает администратору интернет-магазина сообщение «Системный класс перекрывают конфликтующие между собой классы».
Зачастую конфликт можно устранить изменением иерархии наследования.
Этот способ применим не всегда, но если применим, то, в отличие от других способов, позволяет сохранить функциональность конфликтующих модулей.
Этот способ уже многократно описывалась мной на форуме:
- Argento: как ускорить отображение витринного списка товаров посредством блочного кэширования?
- Как добавлять статьи в верхнее товарное меню при использовании модуля TemplateMela TM Custom Menu?
- Как добавлять статьи в верхнее товарное меню при использовании модуля TemplateMela Megnor AdvancedMenu?
- Почему у меня не работает шаблонизация TITLE?
Краткое описание способа:
Для устранения конфликта двойного переопределения системного класса Magento директивой rewrite сторонними модулями А и Б надо:
- изменить наследование конфликтного класса модуля Б, унаследовав его не от проблемного системного класса, а от конфликтого класса модуля А.
- гарантировать правильный порядок загрузки (модуль Б должен загружаться после модуля А) директивой depends (пример её применения можно найти в папке app/etc/modules)
Подробное описание способа:
Конфликтующие между собой классы переопределяют один и тот же системный класс Magento и, как правило, оба являются его наследниками.
Посмотрите, какие именно методы системного класса перекрывают конфликтующие между собой классы.
Если эти методы — разные (другими словами, конфликтующие классы не переопределяют один и тот же системный метод), то конфликта можно избежать, унаследовав один конфликтующий класс от другого, а для другого отменить директиву rewrite. Таким образом, первому классу не с кем будет конфликтовать, и в то же время он будет содержать в себе функциональность обоих ранее конфликтовавших классов.
Пошаговая инструкция:
- Найдите файлы с программным кодом конфликтующих классов по их именам, указанным в диагностическом сообщении.
- Узнайте классы-родители конфликтующих классов.
Например, если описание класса начинается так:
class Df_Adminhtml_Block_Sales_Order_Grid extends Mage_Adminhtml_Block_Sales_Order_Grid
то класс Mage_Adminhtml_Block_Sales_Order_Grid является родителем для класса Df_Adminhtml_Block_Sales_Order_Grid.
Более подробное описание смотрите в учебнике по PHP. - Сравните классы родители конфликтующих классов.
Описанный в данной статье способ разрешения конфликта применим только когда оба конфликтующих класса имеют одинаковый класс-родитель (в 95% случаев так и есть). - Сравните названия методов, описанных в конфликтующих классах.
Есть ли в конфликтующих классах одноимённые методы?
Описанный в данной статье способ разрешения конфликта применим только когда оба конфликтующих класса не имеют одноимённых методов с разной реализацией (на практике это обычно так в большей части случаев). - Определите, какой из конфликтующих классов станет новым родителем второго из конфликтующих классов.
Новым родителем можно выбрать любой из конфликтующих классов.
Например, в инструкции Как добавлять статьи в верхнее товарное меню при использовании модуля TemplateMela TM Custom Menu класс Df_Catalog_Block_Navigation стал новым родителем для класса TM_CustomMenu_Block_Navigation. - Смените прежнего родителя (который был общим для конфликтующих классов) на нового родителя (выбранного в предыдущем пункте).
Например, в инструкции Как добавлять статьи в верхнее товарное меню при использовании модуля TemplateMela TM Custom Menu это делается в пункте 2. - Утвердите порядок загрузки конфликтующих модулей посредством директивы depends таким образом, чтобы модуль нового родителя загружался раньше, чем модуль второго конфликтующего класса.
Например, в инструкции Как добавлять статьи в верхнее товарное меню при использовании модуля TemplateMela TM Custom Menu это делается в пункте 1.
**********
Данный пункт, начиная с версии 2.37.0.6, можно не выполнять, если выполнены оба следующих условия:
- Конфликтуют только 2 класса (2 модуля)
- После изменения иерархии наследования сыном стал тот класс, который был основным (активным, используемым системой) при конфликте.
В такой ситуации Российская сборка Magento «знает», что конфликтующие классы находятся в родственном отношении родитель-сын, и не считает такую ситуацию конфликтом, потому что класс-сын наследует программную реализацию класса-родителя.
**********
Удалите директиву rewrite нового родителя.
Директивы rewrite находятся в основном настроечном файле модуля: etc/config.xml.
Например, для модуля Df_Catalog основным настроечным файлом является файл app/code/local/Df/Catalog/etc/config.xml
Основной настроечный файл имеет формат XML.
Требуемую директивую rewrite в основном настроечном файле можно найти по следующему путю в иерархии тегов XML:
config/global/<тип класса>/<приставка системного переопределённого класса>/rewrite/<локальное имя системного переопределённого класса>
- <тип класса> — указан в диагностическом сообщении о конфликте классов.
это может быть один из 3-х типов: «block», «helper», «model». - <приставка системного переопределённого класса> — это то, что указано в качестве системного класса в диагностическом сообщении о конфликте классов до символа «/».
Например, если в качестве системного класса указано «adminhtml/sales_order_grid», то приставкой будет «adminhtml». - <локальное имя системного переопределённого класса> — это то, что указано в качестве системного класса в диагностическом сообщении о конфликте классов после символа «/».
Например, если в качестве системного класса указано «adminhtml/sales_order_grid», то локальным именем системного переопределённого класса «sales_order_grid».
Пример директивы rewrite:
<config> <global> <blocks> <catalog> <rewrite> <navigation>Df_Catalog_Block_Navigation</navigation> </rewrite> </catalog> </blocks> </global> </config>
Для удаления директивы rewrite надо удалить или закомментировать самый внутренний тег и его содержимое. В примере выше это
<navigation>Df_Catalog_Block_Navigation</navigation>
Magento кэширует настроечные файлы, поэтому после изменения настроечных файлов надо удалить кэш.
Также, надо учесть, что выполненные изменения пропадут (перетрутся) после обновления модуля.- Конфликтуют только 2 класса (2 модуля)