Magento 2: Bagaimana Seharusnya Pengembang Modul Membaca File Konfigurasi Mereka Sendiri

20

Skenario: Saya seorang pengembang modul Magento 2. Saya ingin membuat file konfigurasi di app/etc. Saya ingin file ini "dibatasi" berdasarkan area

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

Di Magento 1 saya baru saja membuat config.xmldan berada di jalan saya. Pelingkupan area terjadi di file XML itu sendiri. Namun, Magento 2 melakukan pendekatan yang sangat berbeda

Di Magento 2, file kelas apa yang harus saya buat untuk membaca file konfigurasi tercakup ini. Tidak jelas dari sumber Magento 2 apa "cara yang tepat" untuk melakukan ini. Kode inti mengambil banyak pendekatan, dan tidak ada satupun yang ditandai dengan @apimetode. Ini membuatnya sulit untuk mengetahui bagaimana melanjutkan dengan tugas pengembang modul umum ini. Sebagai efek samping sekunder, juga menyulitkan untuk mengetahui bagaimana pengembang modul Magento harus membaca dari file konfigurasi inti.

Di satu sisi, sepertinya "yang benar" yang harus dilakukan adalah membuat objek pembaca sistem file. Misalnya, Magento tampaknya memuat import.xmlfile dengan yang berikut ini

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

Kelas dasar Magento\Framework\Config\Reader\Filesystemsepertinya memiliki kode untuk menyelesaikan cakupan area.

Namun beberapa file konfigurasi Magento tampaknya menghindari pola ini. Meskipun ada pembaca untuk file-file ini ( event.xmldalam contoh ini)

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

Ada juga kelas "data cakupan" yang menggunakan pembaca ini.

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

Ini membuatnya tampak seperti kelas pembaca dengan cakupan adalah apa yang harus dibuat oleh pengembang modul. Tetapi tidak semua file konfigurasi memiliki pembaca scoped ini.

Apakah ada jalur yang jelas untuk diikuti oleh pengembang modul Magento 2? Atau apakah ini hanya sesuatu yang harus didekati oleh pengembang modul Magento 2 dengan caranya sendiri, dan kekacauan / non-standar-konfigurasi-pembebanan yang dihasilkan hanyalah biaya untuk melakukan bisnis?

The dokumentasi resmi melakukan pekerjaan yang baik yang meliputi beberapa kelas yang tersedia, tapi tidak ada yang mendamaikan fakta tidak ada panduan yang jelas di mana implementasi konkret kita kira untuk digunakan, atau jika harapan adalah setiap modul memutuskan bagaimana melakukan ini pada nya sendiri.

Alan Storm
sumber
Saya pikir ini dapat membantu: magento.stackexchange.com/q/51915/146
Marius
Pernahkah Anda melihat PR ini oleh @vinai github.com/magento/magento2/pull/1410 ? Saya pikir jika Anda tidak memiliki persyaratan khusus, Anda dapat menggulung file konfigurasi Anda sendiri hanya dengan tipe virtual.
Kristof di Fooman

Jawaban:

4

Untuk membuat tipe konfigurasi baru, pengembang modul harus membuat kelas tipe konfigurasi yang akan digunakan oleh klien konfigurasi.

Untuk membuat kelas tipe ini sesederhana mungkin, semua perilaku membaca file konfigurasi dan data caching dipindahkan ke \Magento\Framework\Config\DataInterfacedengan dua implementasi yang dapat digunakan kembali:

  • \Magento\Framework\Config\Data - untuk tipe konfigurasi yang hanya masuk akal untuk dimuat dalam satu lingkup (hanya eav_attributes.xml di global)
  • \Magento\Framework\Config\Data\Scoped - untuk tipe konfigurasi yang dapat dimuat pada cakupan yang berbeda (events.xml - global dan per-area)

Setiap tipe konfigurasi seharusnya memiliki objek yang telah dikonfigurasi sebelumnya Config\DataInterface. Konfigurasi dapat dilakukan dengan Tipe Virtual atau dengan warisan.

Meskipun pengembang modul secara teknis dapat mewarisi jenis konfigurasi mereka dari Config\DataInterfaceimplementasi, disarankan untuk tidak memperpanjang dari kelas inti. Selalu lebih baik menggunakan komposisi.

Sekarang \Magento\Framework\Config\Datadan Data\Scopedhanya melakukan caching dan mendelegasikan pembacaan konfigurasi \Magento\Framework\Config\ReaderInterface. ReaderInterfaceseharusnya menyediakan konfigurasi yang valid dalam format array PHP untuk lingkup yang diminta (jika konfigurasi dicakup). Beberapa implementasi ReaderInterfaceyang mungkin (untuk konfigurasi misalnya membaca dari DB) tapi Magento hanya kapal satu pembaca generik: \Magento\Framework\Config\Reader\Filesystem.

\Magento\Framework\Config\Reader\Filesystem tidak semua operasi diperlukan untuk membaca file dari sistem file modular: membaca file, menggabungkan dan memvalidasi.

Setiap Config\DataInterfaceseharusnya memiliki instance yang dikonfigurasi secara terpisah Config\ReaderInterface. Seperti contoh apa pun dalam sistem, pembaca tertentu dapat dikonfigurasi baik dengan Tipe Virtual atau dengan warisan. Dokumentasi Magento Menjelaskan semua Filesystemdependensi.

Setiap elemen dalam rantai ini adalah opsional (kecuali untuk Kelas Jenis Konfigurasi sendiri) dan dapat diganti dengan implementasi yang lebih spesifik.

Anton Kril
sumber
1

Sepertinya dokumentasi resmi memiliki jawaban untuk pertanyaan Anda.

KAndy
sumber
1
Terima kasih telah merespons, tetapi saya tidak yakin bahwa dokumentasi menjawab pertanyaan saya. Ini mencantumkan sejumlah antarmuka (yang berguna, +1 untuk itu) yang tersedia, tetapi tidak merekonsiliasi fakta bahwa tidak ada implementasi konkret dari antarmuka tersebut ( Magento\Framework\Config\Datadan Magento\Framework\App\Config) tidak ditandai dengan @api. Jika dibiarkan hanya dengan dokumentasi itu saya akan berada di bawah asumsi bahwa, sebagai pengembang modul, tidak ada sistem standar untuk membuat dan membaca file konfigurasi, dan bahwa saya dapat melakukan apa pun yang saya inginkan. Sepertinya itu tidak benar.
Alan Storm
Bisakah Anda menjelaskan kasus ketika Anda perlu membaca konfigurasi untuk beberapa modul lain? Bagi saya konfigurasi pembaca adalah api modul pribadi.
KAndy
Jika seorang pengembang ingin berkontribusi pada inti Magento. Jika pengembang bekerja pada banyak modul, tidak semuanya dikontrol, dan tidak ingin menguraikan grafik UML untuk membaca nilai dari file konfigurasi. Lihat juga - sebagian besar kerangka kerja PHP lainnya dengan sistem konfigurasi. Apapun, jika maksud dari tim inti Magento 2 adalah bahwa konfigurasi modul adalah pribadi dan kustom per modul, yang harus dinyatakan di suatu tempat.
Alan Storm
Juga - (sedikit berbeda / tangensial) bagian Konfigurasi Sistem di bagian belakang Magento - membangun fitur berdasarkan konfigurasi bagian yang ada.
Alan Storm
2
Api apa pun yang tidak dijelaskan dengan @api bersifat pribadi dalam arti bahwa jika Anda menggunakannya maka Anda bertanggung jawab atas kompatibilitas mundur / api mengubah masalah. \ Magento \ Framework \ Config \ ReaderInterface memiliki \ @api anotasi.
KAndy
0

Tidak ada, pada saat penulisan ini, tampaknya menjadi standar adalah membaca pohon konfigurasi digabungkan di Magento 2. Setiap modul mengimplementasikan kelas membaca konfigurasi sendiri, yang berarti terserah masing-masing pengembang untuk memutuskan bagaimana mereka ingin penggabungan ini terjadi. Sementara Magento menawarkan beberapa kelas saham untuk melakukan ini, bahkan di antara kode inti penggunaan kelas-kelas ini tidak konsisten.

Alan Storm
sumber