Magento 2: Wie sollten Modulentwickler ihre eigenen Konfigurationsdateien lesen?

20

Szenario: Ich bin ein Magento 2-Modulentwickler. Ich möchte eine Konfigurationsdatei in erstellen app/etc. Ich möchte, dass diese Datei nach Bereich "abgegrenzt" wird

app/etc/my_file.xml
app/etc/frontend/my_file.xml
app/etc/adminhtml/my_file.xml

In Magento 1 würde ich einfach eine erstellen config.xmlund mich auf den Weg machen. Der Bereichsbereich wurde in der XML-Datei selbst festgelegt. Magento 2 geht dies jedoch ganz anders an

Welche Klassendateien sollte ich in Magento 2 zum Lesen dieser Konfigurationsdateien mit Gültigkeitsbereich erstellen? Aus der Magento 2-Quelle ist nicht klar, wie dies "richtig" gemacht wird. Der Kerncode verwendet mehrere Ansätze, und keiner von ihnen ist mit einer @apiMethode gekennzeichnet. Dies macht es schwierig zu wissen, wie mit dieser allgemeinen Modulentwickleraufgabe verfahren werden soll. Als sekundärer Nebeneffekt ist es auch schwierig zu wissen, wie ein Magento-Modulentwickler aus den Kernkonfigurationsdateien lesen sollte .

Einerseits scheint es "richtig" zu sein, ein Dateisystem-Leseobjekt zu erstellen. Zum Beispiel scheint Magento die import.xmlDatei wie folgt zu laden

#File: vendor/magento/module-import-export/Model/Import/Config/Reader.php
namespace Magento\ImportExport\Model\Import\Config;

class Reader extends \Magento\Framework\Config\Reader\Filesystem
{

    public function __construct(
        //...
        $fileName = 'import.xml',
        //...
    ) {
        parent::__construct(
            $fileResolver,
            $converter,
            $schemaLocator,
            $validationState,
            $fileName,
            $idAttributes,
            $domDocumentClass,
            $defaultScope
        );
    }
    //...
}        

Die Basisklasse Magento\Framework\Config\Reader\Filesystemscheint Code zum Auflösen des Bereichsbereichs zu haben.

Allerdings scheinen einige der Magento - Konfigurationsdateien , dieses Muster zu vermeiden. Zwar gibt es Lesegeräte für diese Dateien ( event.xmlin diesem Beispiel)

vendor/magento/framework/Event/Config/Reader.php

Es gibt auch "Scoped Data" -Klassen, die diese Reader verwenden.

#File: vendor/magento/framework/Event/Config/Data.php
class Data extends \Magento\Framework\Config\Data\Scoped
{
    public function __construct(
        \Magento\Framework\Event\Config\Reader $reader,
        //...
    ) {
        parent::__construct($reader, $configScope, $cache, $cacheId);
    }
}

Dies lässt den Anschein erwecken, dass die Leserklassen mit Gültigkeitsbereich das sind, was ein Modulentwickler erstellen sollte. Aber nicht alle Konfigurationsdateien haben Lesegeräte mit diesem Gültigkeitsbereich.

Gibt es einen klaren Weg für Magento 2-Modulentwickler? Oder ist dies nur etwas, was Magento 2-Modulentwickler auf ihre eigene Art angehen sollten, und das daraus resultierende Chaos / Nicht-Standard-Konfigurations-Laden sind nur die Kosten für das Geschäft?

Die offizielle Dokumentation deckt einige der verfügbaren Klassen gut ab, aber nichts, was mit der Tatsache vereinbar ist, dass es keine eindeutigen Richtlinien dafür gibt, welche konkrete Implementierung wir verwenden sollen, oder ob erwartet wird, dass jedes Modul entscheidet, wie dies zu tun ist besitzen.

Alan Storm
quelle
Ich denke, das kann helfen: magento.stackexchange.com/q/51915/146
Marius
Haben Sie diese PR von @vinai github.com/magento/magento2/pull/1410 gesehen ? Ich denke, wenn Sie keine speziellen Anforderungen haben, können Sie Ihre eigene Konfigurationsdatei nur mit virtuellen Typen rollen.
Kristof bei Fooman

Antworten:

4

Um einen neuen Konfigurationstyp zu erstellen, sollte der Modulentwickler eine Konfigurationstypklasse erstellen , die von den Konfigurationsclients verwendet wird.

Um diese Typklassen so einfach wie möglich zu gestalten, wurde das gesamte Verhalten beim Lesen von Konfigurationsdateien und beim Zwischenspeichern von Daten \Magento\Framework\Config\DataInterfacemit zwei wiederverwendbaren Implementierungen verschoben :

  • \Magento\Framework\Config\Data - für Konfigurationstypen, die nur sinnvoll sind, um in einem Bereich geladen zu werden (eav_attributes.xml nur in global)
  • \Magento\Framework\Config\Data\Scoped - für Konfigurationstypen, die in verschiedenen Bereichen geladen werden können (events.xml - global und pro Bereich)

Jeder Konfigurationstyp sollte ein vorkonfiguriertes Config\DataInterfaceObjekt haben. Die Konfiguration kann entweder mit Virtual Type oder mit Vererbung erfolgen.

Obwohl Modulentwickler ihren Konfigurationstyp technisch von der Config\DataInterfaceImplementierung erben können , wird empfohlen, nicht von Kernklassen auszuweiten. Komposition immer besser anwenden.

Jetzt \Magento\Framework\Config\Dataund Data\Scopednur noch Caching durchführen und das Lesen der Konfiguration an delegieren \Magento\Framework\Config\ReaderInterface. ReaderInterfacesoll eine gültige Konfiguration im Format eines PHP-Arrays für den angeforderten Bereich bereitstellen (wenn die Konfiguration einen bestimmten Umfang hat). Mehrere Implementierungen ReaderInterfacesind möglich (zum Beispiel Lese Konfiguration von DB) aber Magento nur Schiffe eines generischen Leser: \Magento\Framework\Config\Reader\Filesystem.

\Magento\Framework\Config\Reader\Filesystem führt alle Operationen aus, die zum Lesen von Dateien aus dem modularen Dateisystem erforderlich sind: Dateien lesen, zusammenführen und validieren.

Jeder Config\DataInterfacesoll eine separat konfigurierte Instanz von haben Config\ReaderInterface. Wie jede Instanz im System kann ein bestimmter Reader entweder mit Virtual Type oder mit Vererbung konfiguriert werden. Magento-Dokumentation Beschreibt alle FilesystemAbhängigkeiten.

Jedes Element in dieser Kette ist optional (mit Ausnahme der Config Type Class selbst) und kann durch eine spezifischere Implementierung ersetzt werden.

Anton Kril
quelle
1

Offenbar hat die offizielle Dokumentation Antworten auf Ihre Frage.

KAndy
quelle
1
Vielen Dank für Ihre Antwort, aber ich bin nicht sicher, ob die Dokumentation meine Frage beantwortet. Es werden eine Reihe von Schnittstellen aufgelistet (was nützlich ist, +1 für das), die verfügbar sind, aber die Tatsache nicht in Einklang bringen, dass keine der konkreten Implementierungen dieser Schnittstellen ( Magento\Framework\Config\Dataund Magento\Framework\App\Config) nicht mit @api gekennzeichnet sind. Wenn ich nur diese Dokumentation behalten würde, würde ich davon ausgehen, dass es als Modulentwickler kein Standardsystem zum Erstellen und Lesen von Konfigurationsdateien gibt und dass ich tun kann, was ich will. Das scheint nicht richtig zu sein.
Alan Storm
Können Sie Fälle beschreiben, in denen Sie die Konfiguration für ein anderes Modul lesen müssen? Für mich ist der Konfigurationsleser eine private API des Moduls.
KAndy
Wenn ein Entwickler zu Magento Core beitragen wollte. Wenn ein Entwickler an mehreren Modulen arbeitet, die nicht alle von ihm gesteuert werden, und kein UML-Diagramm entwirren möchte, um einen Wert aus einer Konfigurationsdatei zu lesen. Siehe auch - die meisten anderen PHP-Frameworks mit einem Konfigurationssystem. Unabhängig davon, ob die Absicht des Magento 2 Kernteam besteht darin , dass die Modulkonfiguration ist eine private und individuelle pro Modul, das irgendwo erwähnt werden sollte.
Alan Storm
Außerdem - (geringfügig anders / tangential) der Abschnitt Systemkonfiguration im Backend von Magento - wird eine Funktion erstellt, die auf der Konfiguration eines vorhandenen Abschnitts basiert.
Alan Storm
2
Alle APIs, die nicht mit @api annotiert wurden, sind in dem Sinne privat, dass Sie, wenn Sie sie verwenden, für Probleme mit der Abwärtskompatibilität / API-Änderungen verantwortlich sind. \ Magento \ Framework \ Config \ ReaderInterface hat die Annotation \ @api.
KAndy
0

Zum Zeitpunkt des Schreibens scheint es keinen Standard zu geben, der das Lesen eines zusammengeführten Konfigurationsbaums in Magento 2 vorsieht. Jedes Modul implementiert seine eigenen Konfigurationsleseklassen, was bedeutet, dass jeder Entwickler selbst entscheiden muss, wie diese zusammengeführt werden sollen passieren. Während Magento hierfür einige Aktienklassen anbietet, ist die Verwendung dieser Klassen selbst im Kerncode inkonsistent.

Alan Storm
quelle