Magento 2: Como os desenvolvedores de módulos devem ler seus próprios arquivos de configuração

20

Cenário: Sou desenvolvedor do módulo Magento 2. Eu quero criar um arquivo de configuração no app/etc. Quero que este arquivo tenha "escopo" por área

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

No Magento 1, eu apenas criava um config.xmle estava a caminho. O escopo da área aconteceu no próprio arquivo XML. No entanto, o Magento 2 aborda isso de maneira muito diferente

No Magento 2, quais arquivos de classe devo criar para ler esses arquivos de configuração com escopo definido. Não está claro pela fonte do Magento 2 qual é a maneira "certa" de fazer isso. O código principal usa várias abordagens e nenhuma delas é marcada com um @apimétodo. Isso dificulta saber como proceder com esta tarefa comum de desenvolvedor de módulo. Como efeito colateral secundário, também torna difícil saber como um desenvolvedor de módulo Magento deve ler os arquivos de configuração principais.

Por um lado, parece que "a coisa certa" a fazer é criar um objeto leitor de sistema de arquivos. Por exemplo, o Magento parece carregar o import.xmlarquivo com as seguintes

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

A Magento\Framework\Config\Reader\Filesystemclasse base parece ter código para resolver o escopo da área.

No entanto, alguns dos arquivos de configuração do Magento parecem evitar esse padrão. Embora existam leitores para esses arquivos ( event.xmlneste exemplo)

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

Há também classes de "dados com escopo" que usam esses leitores.

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

Isso faz parecer que as classes de leitores com escopo definido são o que um desenvolvedor de módulos deve criar. Mas nem todos os arquivos de configuração possuem esses leitores com escopo.

Existe um caminho claro para os desenvolvedores do módulo Magento 2 seguirem? Ou isso é algo que os desenvolvedores do módulo Magento 2 devem abordar à sua maneira, e o caos resultante / carregamento de configuração não-padrão é apenas o custo de fazer negócios?

A documentação oficial faz um bom trabalho ao cobrir algumas das classes disponíveis, mas nada que concilie o fato de que não há uma orientação clara sobre qual implementação concreta devemos usar, ou se a expectativa é de que todo módulo decida como fazer isso por conta própria. próprio.

Alan Storm
fonte
Eu acho que isso pode ajudar: magento.stackexchange.com/q/51915/146
Marius
Você já viu esse PR por @vinai github.com/magento/magento2/pull/1410 ? Eu acho que se você não tiver requisitos especiais, poderá rolar seu próprio arquivo de configuração apenas com tipos virtuais.
Kristof at Fooman

Respostas:

4

Para criar um novo tipo de configuração, o desenvolvedor do módulo deve criar uma classe de tipo de configuração que será usada pelos clientes de configuração.

Para tornar essas classes de tipos o mais simples possível, todo o comportamento de ler arquivos de configuração e dados em cache foi movido para \Magento\Framework\Config\DataInterfaceduas implementações reutilizáveis:

  • \Magento\Framework\Config\Data - para tipos de configuração que só fazem sentido serem carregados em um escopo (eav_attributes.xml apenas em global)
  • \Magento\Framework\Config\Data\Scoped - para tipos de configuração que podem ser carregados em escopos diferentes (events.xml - global e por área)

Todo tipo de configuração deve ter um Config\DataInterfaceobjeto pré-configurado . A configuração pode ser feita com Tipo Virtual ou com herança.

Embora o desenvolvedor do módulo possa herdar tecnicamente seu tipo de configuração da Config\DataInterfaceimplementação, é recomendável não se estender das classes principais. Sempre melhor usar composição.

Agora \Magento\Framework\Config\Datae Data\Scopedsó fazem cache e delegado leitura de configuração para \Magento\Framework\Config\ReaderInterface. ReaderInterfacedeve fornecer configuração válida no formato da matriz PHP para o escopo solicitado (se a configuração tiver escopo definido). Várias implementações ReaderInterfacesão possíveis (por exemplo de configuração de leitura do DB), mas Magento única navios um leitor genérico: \Magento\Framework\Config\Reader\Filesystem.

\Magento\Framework\Config\Reader\Filesystem faz todas as operações necessárias para ler arquivos do sistema de arquivos modular: ler arquivos, mesclar e validar.

Todo mundo Config\DataInterfacedeve ter uma instância configurada separadamente de Config\ReaderInterface. Como qualquer instância do sistema, um leitor específico pode ser configurado com o Tipo virtual ou com herança. Documentação Magento Descreve todas as Filesystemdependências.

Cada elemento nesta cadeia é opcional (exceto a própria Classe de tipo de configuração) e pode ser substituído por uma implementação mais específica.

Anton Kril
fonte
1

Parece que a documentação oficial tem respostas para sua pergunta.

KAndy
fonte
11
Obrigado por responder, mas não tenho certeza de que a documentação responda minha pergunta. Ele lista várias interfaces (que são úteis, +1 para isso) que estão disponíveis, mas não reconcilia o fato de que nenhuma das implementações concretas dessas interfaces ( Magento\Framework\Config\Datae Magento\Framework\App\Config) não está marcada com @api. Se restasse apenas essa documentação, eu assumiria que, como desenvolvedor de módulos, não existe um sistema padrão para criar e ler arquivos de configuração e que eu posso fazer o que quiser. Isso não parece certo.
Alan Storm
Você pode descrever casos em que precisa ler a configuração de algum outro módulo? Para mim, o leitor de configuração é uma API privada do módulo.
Kandy
Se um desenvolvedor quisesse contribuir com o núcleo do Magento. Se um desenvolvedor trabalha em vários módulos, nem todos eles controlam, e não deseja desembaraçar um gráfico UML para ler um valor de um arquivo de configuração. Veja também - a maioria das outras estruturas PHP com um sistema de configuração. Independentemente disso, se a intenção da equipe principal do Magento 2 é que a configuração do módulo seja privada e personalizada por módulo, isso deve ser declarado em algum lugar.
Alan Storm
Também - (ligeiramente diferente / tangencial) a seção Configuração do sistema no back-end do Magento - construindo um recurso com base na configuração de uma seção existente.
Alan Storm
2
Qualquer API que não seja anotada com @api é privada no sentido de que, se você a usar, será responsável pela compatibilidade com versões anteriores / a API mudará os problemas. \ Magento \ Framework \ Config \ ReaderInterface possui anotação \ @api.
Kandy
0

No momento, este artigo não parece ser o padrão para ler uma árvore de configuração mesclada no Magento 2. Cada módulo implementa suas próprias classes de leitura de configuração, o que significa que cada desenvolvedor decide como deseja essa mesclagem. acontecer. Enquanto o Magento oferece algumas classes de ações para fazer isso, mesmo entre o código principal, o uso dessas classes é inconsistente.

Alan Storm
fonte