Magento 2: Cómo deberían los desarrolladores de módulos leer sus propios archivos de configuración

20

Escenario: Soy un desarrollador de módulos de Magento 2. Quiero crear un archivo de configuración en app/etc. Quiero que este archivo tenga "ámbito" por área

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

En Magento 1, simplemente crearía ay seguiría config.xmlmi camino. El alcance del área ocurrió en el archivo XML en sí. Sin embargo, Magento 2 aborda esto de manera muy diferente

En Magento 2, ¿qué archivo (s) de clase debo crear para leer estos archivos de configuración de ámbito. No está claro por la fuente de Magento 2 cuál es la forma "correcta" de hacer esto. El código central adopta múltiples enfoques, y ninguno de ellos está marcado con un @apimétodo. Esto dificulta saber cómo proceder con esta tarea común de desarrollador de módulos. Como efecto secundario secundario, también hace que sea difícil saber cómo debe leer un desarrollador de módulos de Magento de los archivos de configuración principales.

Por un lado, parece que "lo correcto" es crear un objeto lector de sistema de archivos. Por ejemplo, Magento parece cargar el import.xmlarchivo con lo siguiente

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

Magento\Framework\Config\Reader\FilesystemParece que la clase base tiene código para resolver el alcance del área.

Sin embargo, algunos de los archivos de configuración de Magento parecen evitar este patrón. Si bien hay lectores para estos archivos ( event.xmlen este ejemplo)

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

También hay clases de "datos con alcance" que utilizan estos lectores.

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

Esto hace que parezca que las clases de lectores con alcance son lo que un desarrollador de módulos debería crear. Pero no todos los archivos de configuración tienen estos lectores de ámbito.

¿Existe un camino claro para que sigan los desarrolladores de módulos de Magento 2? ¿O es esto algo que los desarrolladores de módulos de Magento 2 deberían abordar a su manera, y el caos resultante / carga de configuración no estándar es solo el costo de hacer negocios?

La documentación oficial hace un buen trabajo al cubrir algunas de las clases disponibles, pero nada que concilie el hecho de que no hay una guía clara sobre qué implementación concreta se supone que debemos usar, o si la expectativa es que cada módulo decida cómo hacer esto en su propio.

Alan Storm
fuente
Creo que esto puede ayudar: magento.stackexchange.com/q/51915/146
Marius
¿Has visto este PR por @vinai github.com/magento/magento2/pull/1410 ? Creo que si no tiene requisitos especiales, puede rodar su propio archivo de configuración con solo tipos virtuales.
Kristof en Fooman el

Respuestas:

4

Para crear un nuevo tipo de configuración, el desarrollador del módulo debe crear una clase de tipo de configuración que será utilizada por los clientes de la configuración.

Para hacer que estas clases de tipos sean lo más simples posible, todo el comportamiento de lectura de archivos de configuración y almacenamiento en caché de datos se movió a \Magento\Framework\Config\DataInterfacedos implementaciones reutilizables:

  • \Magento\Framework\Config\Data - para tipos de configuración que solo tienen sentido cargarse en un ámbito (eav_attributes.xml solo en global)
  • \Magento\Framework\Config\Data\Scoped - para tipos de configuración que pueden cargarse en diferentes ámbitos (events.xml - global y por área)

Se supone que cada tipo de configuración tiene un Config\DataInterfaceobjeto preconfigurado . La configuración se puede hacer con Tipo virtual o con herencia.

Aunque el desarrollador de módulos técnicamente puede heredar su tipo de configuración de la Config\DataInterfaceimplementación, se recomienda no extender desde las clases principales. Siempre es mejor usar composición.

Ahora \Magento\Framework\Config\Datay Data\Scopedsolo haga el almacenamiento en caché y delegue la lectura de configuración a \Magento\Framework\Config\ReaderInterface. ReaderInterfacese supone que proporciona una configuración válida en formato de matriz PHP para el alcance solicitado (si la configuración tiene un alcance). Múltiples implementaciones de ReaderInterfaceson posibles (por ejemplo de configuración de lectura desde DB) pero Magento solamente buques un lector genérico: \Magento\Framework\Config\Reader\Filesystem.

\Magento\Framework\Config\Reader\Filesystem realiza todas las operaciones necesarias para leer archivos del sistema de archivos modular: leer archivos, fusionar y validar.

Cada Config\DataInterfacese supone que tiene instancia configurada por separado de Config\ReaderInterface. Como cualquier instancia en el sistema, el lector específico se puede configurar con Tipo virtual o con herencia. Documentación de Magento Describe todas las Filesystemdependencias.

Cada elemento de esta cadena es opcional (excepto la clase de tipo de configuración en sí) y se puede sustituir por una implementación más específica.

Anton Kril
fuente
1

Parece que la documentación oficial tiene respuestas a su pregunta.

Kandy
fuente
1
Gracias por responder, pero no estoy seguro de que la documentación responda mi pregunta. Enumera una serie de interfaces (que es útil, +1 para eso) que están disponibles, pero no concilia el hecho de que ninguna de las implementaciones concretas de esas interfaces ( Magento\Framework\Config\Datay Magento\Framework\App\Config) no están marcadas con @api. Si me quedara solo con esa documentación, asumiría que, como desarrollador de módulos, no existe un sistema estándar para crear y leer archivos de configuración, y que puedo hacer lo que quiera. Eso no parece correcto.
Alan Storm
¿Puede describir casos en los que necesita leer la configuración de algún otro módulo? Para mí, el lector de configuración es una API privada del módulo.
KAndy
Si un desarrollador quisiera contribuir al núcleo de Magento. Si un desarrollador trabaja en varios módulos, no todos controlan, y no quiere desenredar un gráfico UML para leer un valor de un archivo de configuración. Ver también: la mayoría de los otros frameworks PHP con un sistema de configuración. De todos modos, si la intención del equipo central de Magento 2 es que la configuración del módulo sea privada y personalizada por módulo, eso debería indicarse en alguna parte.
Alan Storm
También también - (ligeramente diferente / tangencial) la sección Configuración del sistema en el backend de Magento - construyendo una función basada en la configuración de una sección existente.
Alan Storm
2
Cualquier API que no esté anotada con @api es privada en el sentido de que si la usa, usted es responsable de los problemas de compatibilidad con versiones anteriores / cambios de API. \ Magento \ Framework \ Config \ ReaderInterface tiene una anotación \ @api.
KAndy
0

Al momento de escribir esto, no parece que haya un estándar para leer un árbol de configuración combinado en Magento 2. Cada módulo implementa sus propias clases de lectura de configuración, lo que significa que depende de cada desarrollador decidir cómo quieren esta fusión. a suceder Si bien Magento ofrece algunas clases de acciones para hacer esto, incluso entre el código central el uso de estas clases es inconsistente.

Alan Storm
fuente