Magento 2: Comment les développeurs de modules devraient-ils lire leurs propres fichiers de configuration

20

Scénario: je suis développeur de modules Magento 2. Je souhaite créer un fichier de configuration dans app/etc. Je souhaite que ce fichier soit "délimité" par zone

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

Dans Magento 1, je venais juste d'en créer un config.xmlet j'étais en route. La délimitation de la zone s'est produite dans le fichier XML lui-même. Cependant, Magento 2 aborde cela très différemment

Dans Magento 2, quel (s) fichier (s) de classe dois-je créer pour lire ces fichiers de configuration étendus. La source Magento 2 ne précise pas quelle est la "bonne" façon de procéder. Le code principal adopte plusieurs approches, et aucune d'entre elles n'est marquée par une @apiméthode. Cela rend difficile de savoir comment procéder avec cette tâche commune de développeur de module. En tant qu'effet secondaire, il est également difficile de savoir comment un développeur de module Magento doit lire les fichiers de configuration principaux.

D'une part, il semble que "la bonne" chose à faire est de créer un objet lecteur de système de fichiers. Par exemple, Magento semble charger le import.xmlfichier avec les éléments suivants

#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
        );
    }
    //...
}        

La Magento\Framework\Config\Reader\Filesystemclasse de base semble avoir du code pour résoudre l'étendue de la zone.

Cependant, certains fichiers de configuration de Magento semblent éviter ce modèle. Bien qu'il existe des lecteurs pour ces fichiers ( event.xmldans cet exemple)

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

Il existe également des classes de «données de portée» qui utilisent ces lecteurs.

#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);
    }
}

Cela donne l'impression que les classes de lecture étendues sont ce qu'un développeur de module devrait créer. Mais tous les fichiers de configuration n'ont pas ces lecteurs de portée.

Y a-t-il un chemin clair à suivre pour les développeurs de modules Magento 2? Ou est-ce juste quelque chose que les développeurs de modules de Magento 2 devraient aborder à leur manière, et le chaos / chargement de configuration non standard qui en résulte n'est que le coût de faire des affaires?

La documentation officielle couvre bien certaines des classes disponibles, mais rien qui concilie le fait qu'il n'y a pas de directives claires sur l'implémentation concrète que nous supposons utiliser, ou si l'attente est que chaque module décide comment le faire sur son posséder.

Alan Storm
la source
Je pense que cela peut aider: magento.stackexchange.com/q/51915/146
Marius
Avez-vous vu ce PR par @vinai github.com/magento/magento2/pull/1410 ? Je pense que si vous n'avez pas d'exigences particulières, vous pouvez rouler votre propre fichier de configuration avec uniquement des types virtuels.
Kristof à Fooman

Réponses:

4

Pour créer un nouveau type de configuration, le développeur de module doit créer une classe de type de configuration qui sera utilisée par les clients de configuration.

Pour rendre ces classes de type aussi simples que possible, tous les comportements de lecture des fichiers de configuration et de mise en cache des données ont été déplacés vers \Magento\Framework\Config\DataInterfacedeux implémentations réutilisables:

  • \Magento\Framework\Config\Data - pour les types de configuration qui n'ont de sens que d'être chargés dans une seule étendue (eav_attributes.xml uniquement dans le global)
  • \Magento\Framework\Config\Data\Scoped - pour les types de configuration pouvant être chargés sur différentes étendues (events.xml - global et par zone)

Chaque type de configuration est censé avoir un Config\DataInterfaceobjet préconfiguré . La configuration peut être effectuée soit avec Virtual Type, soit avec héritage.

Bien que le développeur de modules puisse hériter techniquement de son type de configuration de l' Config\DataInterfaceimplémentation, il est recommandé de ne pas étendre à partir des classes principales. Toujours mieux utiliser la composition.

Désormais \Magento\Framework\Config\Data, Data\Scopedne faites que la mise en cache et déléguez la lecture de la configuration à \Magento\Framework\Config\ReaderInterface. ReaderInterfaceest censé fournir une configuration valide au format du tableau PHP pour la portée demandée (si la configuration est étendue). Plusieurs implémentations de ReaderInterfacesont possibles (par exemple la configuration de lecture de DB) , mais Magento seulement un lecteur générique navires: \Magento\Framework\Config\Reader\Filesystem.

\Magento\Framework\Config\Reader\Filesystem effectue toutes les opérations nécessaires à la lecture de fichiers à partir d'un système de fichiers modulaire: lire des fichiers, fusionner et valider.

Chacun Config\DataInterfaceest censé avoir une instance de Config\ReaderInterface. Comme toute instance du système, un lecteur spécifique peut être configuré soit avec Virtual Type, soit avec héritage. Documentation Magento Décrit toutes les Filesystemdépendances.

Chaque élément de cette chaîne est facultatif (à l'exception de la classe de type de configuration elle-même) et peut être remplacé par une implémentation plus spécifique.

Anton Kril
la source
1

On dirait que la documentation officielle a des réponses à votre question.

KAndy
la source
1
Merci d'avoir répondu, mais je ne suis pas sûr que la documentation réponde à ma question. Il répertorie un certain nombre d'interfaces (ce qui est utile, +1 pour cela) qui sont disponibles, mais ne concilie pas le fait qu'aucune des implémentations concrètes de ces interfaces ( Magento\Framework\Config\Dataet Magento\Framework\App\Config) n'est marquée avec @api. S'il ne me restait que cette documentation, je serais dans l'hypothèse qu'en tant que développeur de module, il n'y a pas de système standard pour créer et lire les fichiers de configuration, et que je peux faire ce que je veux. Cela ne semble pas correct.
Alan Storm
Pouvez-vous décrire des cas où vous devez lire la configuration d'un autre module? Pour moi, le lecteur de configuration est une API privée du module.
KAndy
Si un développeur voulait contribuer au cœur de Magento. Si un développeur travaille sur plusieurs modules, qu'il ne contrôle pas tous, et ne souhaite pas démêler un graphique UML pour lire une valeur à partir d'un fichier de configuration. Voir aussi - la plupart des autres frameworks PHP avec un système de configuration. Quoi qu'il en soit, si l'intention de l'équipe principale de Magento 2 est que la configuration des modules soit privée et personnalisée par module, cela devrait être indiqué quelque part.
Alan Storm
Aussi - (légèrement différente / tangentielle) la section Configuration système dans le backend de Magento - construction d'une fonctionnalité basée sur la configuration d'une section existante.
Alan Storm
2
Toute API qui n'est pas annotée avec @api est privée en ce sens que si vous l'utilisez, vous êtes responsable des problèmes de compatibilité ascendante / de modification de l'API. \ Magento \ Framework \ Config \ ReaderInterface ont une annotation \ @api.
KAndy
0

Au moment de la rédaction de ce document, il ne semble pas y avoir de norme pour lire une arborescence de configuration fusionnée dans Magento 2. Chaque module implémente ses propres classes de lecture de configuration, ce qui signifie qu'il appartient à chaque développeur de décider comment il souhaite cette fusion. se passer. Bien que Magento propose certaines classes de stock pour ce faire, même parmi le code de base, l'utilisation de ces classes est incohérente.

Alan Storm
la source