Magento 2: Как разработчики модулей должны читать свои собственные файлы конфигурации


20

Сценарий: я разработчик модуля Magento 2. Я хочу создать файл конфигурации в app/etc. Я хочу, чтобы этот файл был "областью видимости" по области

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

В Magento 1 я просто создаю config.xmlи буду в пути. Область видимости области произошла в самом файле XML. Тем не менее, Magento 2 подходит к этому совершенно по-другому

В Magento 2, какой файл (ы) класса я должен создать для чтения этих конфигурационных файлов. Из источника Magento 2 не ясно, каков «правильный» способ сделать это. Основной код использует несколько подходов, и ни один из них не помечен @apiметодом. Это затрудняет понимание того, как выполнить эту общую задачу разработчика модулей. Как побочный эффект, это также затрудняет понимание того, как разработчик модуля Magento должен читать из файлов конфигурации ядра.

С одной стороны, кажется, что «правильно» сделать объект чтения файловой системы. Например, Magento, кажется, загружает import.xmlфайл со следующим

#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\Filesystemкласс выглядит так, как будто у него есть код для разрешения области действия.

Однако некоторые файлы конфигурации Magento, похоже, избегают этого паттерна. Пока есть читатели для этих файлов ( event.xmlв этом примере)

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

Есть также классы «данных по областям», которые используют эти читатели.

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

Это создает впечатление, что классы чтения с областью видимости - это то, что должен создать разработчик модуля. Но не все файлы конфигурации имеют эти читатели с ограниченным доступом.

Существует ли четкий путь для разработчиков модулей Magento 2? Или это просто то, к чему разработчики модулей Magento 2 должны подходить по-своему, и получающаяся в результате хаос / нестандартная загрузка конфигурации - это просто стоимость ведения бизнеса?

Официальная документация , делает хорошую работу по покрытию некоторых из доступных классов, но ничего такого , что примиряет тот факт , что нет четких указаний , по которым конкретной реализация , мы предполагаем использование, или если ожидание каждый модуль решает , как сделать это на его собственный.


Я думаю, что это может помочь: magento.stackexchange.com/q/51915/146
Мариус

Вы видели этот пиар @vinai github.com/magento/magento2/pull/1410 ? Я думаю, что если у вас нет особых требований, вы можете свернуть свой собственный файл конфигурации только с виртуальными типами.
Кристоф на Fooman

Ответы:


4

Чтобы создать новый тип конфигурации, разработчик модуля должен создать класс типа конфигурации, который будет использоваться клиентами конфигурации.

Чтобы сделать эти классы типов максимально простыми, все поведение чтения конфигурационных файлов и данных кэширования было перенесено в \Magento\Framework\Config\DataInterfaceдве реализации многократного использования:

  • \Magento\Framework\Config\Data - для типов конфигурации, которые имеют смысл загружать только в одной области (eav_attributes.xml только в глобальном масштабе)
  • \Magento\Framework\Config\Data\Scoped - для типов конфигурации, которые могут быть загружены в разных областях (events.xml - глобальный и для каждой области)

Каждый тип конфигурации должен иметь предварительно настроенный Config\DataInterfaceобъект. Конфигурирование может быть выполнено либо с виртуальным типом, либо с наследованием.

Хотя разработчик модуля может технически наследовать тип конфигурации от Config\DataInterfaceреализации, рекомендуется не расширять базовые классы. Всегда лучше использовать композицию.

Сейчас \Magento\Framework\Config\Dataи Data\Scopedтолько делайте кеширование и делегируйте чтение конфигурации \Magento\Framework\Config\ReaderInterface. ReaderInterfaceПредполагается предоставить правильную конфигурацию в формате массива PHP для запрошенной области (если конфигурация ограничена). Несколько реализаций ReaderInterfaceвозможны (для конфигурации Пример чтения из БД) , но Magento поставляется только один общий читателя: \Magento\Framework\Config\Reader\Filesystem.

\Magento\Framework\Config\Reader\Filesystem выполняет все операции, необходимые для чтения файлов из модульной файловой системы: чтение файлов, объединение и проверка.

Каждый Config\DataInterfaceдолжен иметь отдельно настроенный экземпляр Config\ReaderInterface. Как и любой другой экземпляр в системе, конкретный читатель может быть настроен либо с виртуальным типом, либо с наследованием. Magento Documentation Описывает все Filesystemзависимости.

Каждый элемент в этой цепочке является необязательным (за исключением самого класса типов конфигурации) и может быть заменен более конкретной реализацией.


1

Похоже, в официальной документации есть ответы на ваш вопрос.


1
Спасибо, что ответили, но я не уверен, что документация действительно отвечает на мой вопрос. Он перечисляет количество доступных интерфейсов (что полезно, +1 за это), но не согласовывает тот факт, что ни одна из конкретных реализаций этих интерфейсов ( Magento\Framework\Config\Dataи Magento\Framework\App\Config) не помечена @api. Если бы я оставил только эту документацию, я бы исходил из предположения, что как разработчик модуля не существует стандартной системы для создания и чтения файлов конфигурации, и что я могу делать все, что захочу. Это не кажется правильным.
Алан Сторм

Можете ли вы описать случаи, когда вам нужно прочитать конфигурацию для какого-то другого модуля? Для меня конфигурация ридер является частным API модуля.
Канди

Если разработчик хотел внести свой вклад в ядро ​​Magento. Если разработчик работает с несколькими модулями, не всеми из которых они управляют, и не хочет распутывать UML-диаграмму, чтобы прочитать значение из файла конфигурации. Смотрите также - большинство других PHP-фреймворков с системой конфигурации. Независимо от того , если намерение основной команды Magento 2 является то , что конфигурация модуля является частным и обычая на модуль, который должен быть указан где - то.
Алан Сторм

Также также - (немного другой / тангенциальный) раздел «Конфигурация системы» в бэкенде Magento - создание функции на основе конфигурации существующего раздела.
Алан Сторм

2
Любой API, который не аннотирован @api, является частным в том смысле, что если вы его используете, то вы несете ответственность за проблемы обратной совместимости / API. \ Magento \ Framework \ Config \ ReaderInterface имеют аннотацию \ @api.
Канди

0

На момент написания этой статьи, похоже, не существовало стандарта считывания объединенного дерева конфигурации в Magento 2. Каждый модуль реализует свои собственные классы чтения конфигурации, что означает, что каждый разработчик должен сам решать, как они хотят это объединение. произойдет. Хотя Magento предлагает для этого некоторые классы акций, даже среди базового кода использование этих классов противоречиво.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.