Обеспечение совместимости модулей для разных версий Magento
Сегодня я столкнулся со следующей проблемой: Модуль, который я разработал, очень хорошо работает в магазине версий Magento 1.7. Теперь мне нужно адаптировать его также для работы с магазином Magento 1.5.
Одна точка, в которой совместимость расходится, находится в моей коллекции, где я покидаю класс Mage_Core_Model_Resource_Db_Collection_Abstract
. Этот класс не существует в Magento 1.5, но у него есть некоторые приятные функции, такие как getMainTable().
Одна вещь, которую я мог бы сделать, это вместо этого использовать класс Varien_Data_Collection_Db
, который наследуется из в Mage_Core_Model_Resource_Db_Collection_Abstract
.
Это работает, но тогда я больше не могу использовать метод getMainTable() - даже не в магазине 1.7, где он действительно существует.
Как вы справляетесь с такими специфическими причудами версии? Кажется абсурдным писать пользовательский класс, который реализует материал, уже имеющийся в версии 1.7, и тем самым дублировать код в этой версии. С другой стороны, плохо не иметь этой функции и вместо этого использовать худшие привычки кодирования, такие как жесткое кодирование. Итак, есть ли какой-нибудь хороший подход при написании модулей Magento какие из них обратно совместимы?
4 answers
Вы можете создать промежуточный класс, который реализует все необходимые функции, и в зависимости от версии magento вызывать реализацию родителя или использовать свою собственную реализацию:
Model/Int.php
<?php
if (!version_compare(Mage::getVersion(), '1.7', '>=')) {
class N_M_Model_Int extends Mage_Core_Model_Resource_Db_Collection_Abstract
{
}
} else {
class N_M_Model_Int extends Varien_Data_Collection_Db
{
public function getMainTable()
{
// my implementation
}
}
}
?>
Model/Final.php
<?php
class N_M_Model_Final extends N_M_Model_Int
{
// common code between all the versions
}
?>
Возможно, это не тот точный ответ, который вы ищете, но я не могу представить, что многие люди разрабатывают расширения для более старых версий.
Просто обновите, это все равно неизбежно
Очевидным решением для клиента 1.5 является обновление до версии 1.7 (1.5 в любом случае ужасно сломанный релиз).
Но если вы должны
Если бы нам пришлось решать эту проблему, это был бы просто случай резервного копирования модуля с помощью дополнительного базового модуля для резервного копирования ядра функциональность, которая вам требуется. Затем, когда придет время для обновления, модуль зависимостей может быть просто удален/удален.
Недостатками является то, что вы потенциально можете в конечном итоге переопределить абстрактные классы просто для добавления/изменения одной функции. Время, затраченное на это, вполне может быть на уровне простого обновления магазина для начала.
С точки зрения обеспечения обратной совместимости расширений - это кажется странной практикой - поскольку вы идете на компромиссы для более новых версий. Расширения склонны стареть естественным образом, так что, скорее, они совместимы с задней частью; вы развиваетесь над этим, чтобы сделать его совместимым с передней частью.
Если вы когда-либо смотрели исходный код сторонних модулей; они, как правило, заполнены вызовами Mage::getVersion()
и условными операторами - все они совместимы с несколькими версиями. Это грязно, и этого следует избегать. Во всей реальности - у вас должны быть разные версии расширений для разных версий Magento. В противном случае вы столкнетесь с поддержкой расширения, которое имеет отклонения в методах классов и увеличение числа условных операторов.
Хотя вот хороший пример того, почему нет
Я понимаю вашу логику. Но что происходит в таких случаях, как 1.4.1
> 1.4.2
обновление и таблицы продаж EAV были удалены. Любые новые функции, выполняемые на основе этой таблицы, теперь являются плоскими, поэтому попытка резервного копирования - это гораздо больше хлопот, чем того стоит. Это может быть крайностью, и вы четко решите, сколько времени нужно вложить.
Последняя версия Magento навсегда останется движущейся целью, и ей будет предоставлен выбор между тем, чтобы новые модули работали со старыми магазинами - или старые модули работали с новыми магазинами. Я знаю, что мы предпочли бы сделать. Устаревание функций происходит медленно и изящно, и у вас есть достаточно времени, чтобы сделать их более новыми.
То, с чем вы столкнулись, довольно легко исправить. Начиная с версии 1.6 некоторые классы Mysql4 были перенесены в классы ресурсов, но обратная совместимость по-прежнему поддерживается, поскольку разработчики Magento сделали все необходимое.
Для классов Mage_Core_Model_Resource_Db_Collection_Abstract вместо этого используйте классы mage_core_model_mysql4_collection_abstract
Для классов Mage_Core_Model_Resource_Db_Abstract вместо этого используйте классы mage_core_model_mysql4_abstract
Если вы перейдете на эти классы Mysql4, вы обнаружите, что они пусты и просто правильно расширяют классы ресурсов
Надеюсь, это поможет вам
В дополнение к ответу Домен Вранкар, вы также можете сделать что-то вроде:
<?php
if (!version_compare(Mage::getVersion(), '1.7', '>=')) {
$code = "\nclass N_M_Model_Int extends Mage_Core_Model_Resource_Db_Collection_Abstract\n";
} else {
$code = "\nclass N_M_Model_Int extends Varien_Data_Collection_Db\n";
}
$code .= <<<FEED
{
//class implementation
} // END OF CLASS
FEED;
eval ( $code );
Не уверен, что кто-то предпочтет этот метод, но я видел, как награды SweetTooth делают это.