Modul für verschiedene Magento-Versionen kompatibel halten

7

Heute stoße ich auf folgendes Problem: Ein von mir entwickeltes Modul funktioniert sehr gut in einem Magento 1.7-Versionsspeicher. Jetzt muss ich es anpassen, um auch mit einem Magento 1.5 Store zu arbeiten.

Ein Punkt, an dem die Kompatibilität auseinanderfällt, ist in meiner Sammlung, wo ich die Klasse erweitere Mage_Core_Model_Resource_Db_Collection_Abstract. Diese Klasse existiert in Magento 1.5 nicht, hat aber einige nette Funktionen wie getMainTable (). Eine Sache, die ich tun könnte, ist, stattdessen die Klasse zu verwenden, Varien_Data_Collection_Dbdie von in geerbt wird Mage_Core_Model_Resource_Db_Collection_Abstract. Dies funktioniert, aber dann kann ich die Methode getMainTable () nicht mehr verwenden - auch nicht in dem 1.7-Speicher, in dem sie tatsächlich vorhanden ist.

Wie gehen Sie mit solchen versionenspezifischen Macken um? Es erscheint absurd, eine benutzerdefinierte Klasse zu schreiben, die das Zeug implementiert, das Version 1.7 bereits hat, und dadurch Code in dieser Version zu duplizieren. Andererseits ist es schlecht, die Funktion nicht zu haben und stattdessen schlechtere Codierungsgewohnheiten wie Hardcodierung zu verwenden. Gibt es also einen guten Ansatz beim Schreiben von Magento-Modulen, die abwärtskompatibel sind?

mpaepper
quelle

Antworten:

9

Sie können eine Zwischenklasse erstellen, die alle von Ihnen benötigten Funktionen implementiert, abhängig von der Version der Implementierung des übergeordneten Magento-Aufrufs, oder Ihre eigene Implementierung verwenden:

Modell / 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
  }
?>
Domen Vrankar
quelle
1
Das ist eine ziemlich elegante Lösung für ein hässliches Problem
Philwinkle
Schöne Lösung. Kleines Detail: version_compare sollte in der if-Bedingung nicht negiert werden, da diese Version tatsächlich die neueste ist. Außerdem sollte beachtet werden, dass dieser Code nicht auf Enterprise-Kompatibilität getestet wird.
Lucasmus
3

Dies ist vielleicht nicht die genaue Antwort, nach der Sie suchen, aber ich kann mir nicht vorstellen, dass viele Leute Erweiterungen für ältere Versionen entwickeln.

Einfach upgraden, es ist sowieso unvermeidlich

Die offensichtliche Lösung besteht darin, dass der 1.5-Kunde auf 1.7 aktualisiert ( 1.5 ist ohnehin eine schrecklich kaputte Version ).

Aber wenn du musst

Wenn wir uns darum kümmern müssten, müsste lediglich das Modul mit einem sekundären Basismodul gesichert werden, um die von Ihnen benötigten Kernfunktionen zurück zu portieren. Wenn dann die Zeit für ein Upgrade gekommen ist, kann das Abhängigkeitsmodul lediglich gelöscht / entfernt werden.

Die Nachteile sind, dass Sie möglicherweise abstrakte Klassen überschreiben können, nur um eine einzelne Funktion hinzuzufügen / zu ändern. Die dafür investierte Zeit könnte durchaus mit der anfänglichen Aufrüstung des Geschäfts vergleichbar sein.

In Bezug auf die Abwärtskompatibilität von Erweiterungen scheint dies eine seltsame Praxis zu sein, da Sie Kompromisse für neuere Versionen eingehen. Extensions altern in der Regel auf natürliche Weise, sodass sie eher rückwärtskompatibel sind. Sie entwickeln darauf, um es vorwärtskompatibel zu machen.

Wenn Sie sich jemals den Quellcode von Modulen von Drittanbietern angesehen haben; Sie sind in der Regel mit Mage::getVersion()Aufrufen und bedingten Anweisungen gefüllt - alle sind mit mehreren Versionen kompatibel. Es ist chaotisch und sollte vermieden werden. In Wirklichkeit sollten Sie verschiedene Versionen von Erweiterungen für verschiedene Versionen von Magento haben. Andernfalls werden Sie eine Erweiterung unterstützen, die Abweichungen in den Klassenmethoden und eine zunehmende Anzahl von bedingten Anweisungen aufweist.

Obwohl hier ein gutes Beispiel dafür ist, warum nicht

Ich verstehe deine Logik. Aber was in Fällen wie dem 1.4.1> 1.4.2Upgrade und den EAV-Verkaufstabellen passiert, wurde gelöscht. Alle neueren Funktionen, die auf der Grundlage dieser Tabelle ausgeführt werden, sind jetzt flach. Der Versuch, dies zurück zu portieren, ist also weitaus mühsamer als es sich lohnt. Dies kann extrem sein und Sie werden eindeutig beurteilen, wie viel Zeit Sie investieren müssen.

Die neueste Version von Magento wird für immer ein bewegliches Ziel sein und die Wahl haben, ob neue Module mit älteren Geschäften funktionieren sollen oder ältere Module mit neueren Geschäften. Ich weiß, was wir lieber machen würden. Die Ablehnung von Funktionen ist langsam und elegant, und Sie haben genügend Zeit, um sie neuer zu machen.

Ben Lessani - Sonassi
quelle
1
Das Schreiben eines abwärtskompatiblen Codes ist normalerweise viel einfacher, als einen Kunden davon zu überzeugen, zu einer neueren Version seines / here-Shops zu wechseln. Sie haben meistens Probleme, dass sie bereits Erweiterungen von Drittanbietern haben, die mit einer neueren Version von Magento nicht sofort funktionieren, sodass sie sich nicht bereit fühlen, ein Upgrade durchzuführen. Außerdem ist das Backporting nicht so komplex wie das Entwickeln von Neuem. Daher ist das Backportieren einiger Funktionen aus späteren Magento-Versionen immer eine Option. Mit ihm können Sie Code für die neueste Magento-Version schreiben und gleichzeitig die Kompatibilität beibehalten.
Domen Vrankar
Ich verstehe deine Logik. Aber was in Fällen wie dem 1.4.1> 1.4.2Upgrade und den EAV-Verkaufstabellen passiert, wurde gelöscht. Alle neueren Funktionen, die auf der Grundlage dieser Tabelle ausgeführt werden, sind jetzt flach. Der Versuch, dies zurück zu portieren, ist daher weitaus mühsamer als es sich lohnt. Die neueste Version von Magento wird für immer ein bewegliches Ziel sein und die Wahl haben, ob neue Module mit älteren Geschäften funktionieren sollen oder ältere Module mit neueren Geschäften. Ich weiß, was wir lieber machen würden. Die Ablehnung von Funktionen ist langsam und anmutig.
Ben Lessani - Sonassi
Ich stimme Ihnen zu und ich würde sagen, dass wir beide Recht haben :) Es hängt davon ab, wie umfangreich die Änderungen an einem bestimmten Teil von Magento waren und welche Art von Modul Sie schreiben - Erweiterung der Kernfunktionalität oder Schreiben Ihrer eigenen Funktionalität nur lose beeinflusst durch Änderungen an Magento. Am Ende hängt es von der Situation und der Höhe der erforderlichen Investitionen ab :)
Domen Vrankar
Meine 2 Cent: Ich habe einen Kunden, der speziell auf 1.5 feststeckt, weil er eine Erweiterung verwendet, um eine Verbindung zu seiner Verkaufsstelle herzustellen. Ich würde sie gerne auf die neueste Version aktualisieren lassen, aber aufgrund dieser einen Erweiterung können sie dies nicht. Leider wird es immer solche Szenarien geben, so dass es nicht so einfach ist, sie zu aktualisieren
CCBlackburn
1

Was Sie sehen, ist ziemlich einfach zu beheben. Ab 1.6 wurden einige Mysql4-Klassen in Ressourcenklassen verschoben, aber die Abwärtskompatibilität wird weiterhin unterstützt, da Magento-Entwickler die erforderlichen Maßnahmen ergriffen haben.

Verwenden Sie für Mage_Core_Model_Resource_Db_Collection_Abstract-Klassen stattdessen Mage_Core_Model_Mysql4_Collection_Abstract

Verwenden Sie für Mage_Core_Model_Resource_Db_Abstract-Klassen stattdessen Mage_Core_Model_Mysql4_Abstract

Wenn Sie zu diesen Mysql4-Klassen gehen, werden Sie feststellen, dass sie leer sind und nur die Ressourcenklassen ordnungsgemäß erweitern

Hoffe das hilft dir weiter

youngi
quelle
0

Zusätzlich zu Domen Vrankars Antwort können Sie auch Folgendes tun:

<?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 );

Ich bin mir nicht sicher, ob jemand diese Methode bevorzugen würde, aber ich habe gesehen, wie SweetTooth Rewards dies tat.

Erfan
quelle