Apakah sejarah koleksi di Magento 2?

25

Saya tahu bahwa banyak kode yang saat ini ada di Magento 2 (2.1.2) lebih atau kurang porting dari Magento 1 dan bahwa banyak kode akan diganti dengan yang setara di masa depan. Dalam aspek ini, saya bertanya-tanya bagaimana masa depan koleksi di Magento 2.

Biarkan saya jelaskan:

Magento 1:

Di Magento 1 kita terbiasa mendapatkan koleksi seperti ini:

$products = Mage::getModel('catalog/product')->getCollection();

Kami kemudian dapat menerapkan filter dan operasi lain ke koleksi:

$products->addAttributeToFilter('price', ['gteq' => 10]);
$products->addFieldToFilter('created_at', ['lt' => '2016-10-10']);
$products->setPageSize(10);
// ... etc ...

Dan last but not least, koleksi kami akan mengembalikan model:

foreach ($products as $product) {
    echo get_class($product); // Mage_Catalog_Model_Product
}

Magento 2:

Magento menambahkan banyak lapisan abstraksi baru, menerapkan cara kerja yang lebih SOLID. Ini berarti bahwa ketika kita menginginkan daftar entitas, kita memintanya dari repositori:

$productResults = $this->productRepository->getList($searchCriteria);

Jika kita ingin menerapkan filter kita menggunakan kombinasi dari SearchCriteriaBuilder, para FilterGroupBuilder, yang FilterBuilderdan SortOrderBuilder:

$this->searchCriteriaBuilder->addSortOrder(
    $this->sortOrderBuilder
        ->setField('created_at')
        ->setAscendingDirection()
        ->create()
);
$priceFilter = $this->filterBuilder
    ->setField('price')
    ->setValue(10)
    ->setConditionType('gteq')
    ->create();
$createdAtFilter = $this->filterBuilder
    ->setField('created_at')
    ->setValue('2016-10-10')
    ->setConditionType('lt')
    ->create();
$filterGroups = [
    $this->filterGroupBuilder->addFilter($priceFilter)->create(),
    $this->filterGroupBuilder->addFilter($createdAtFilter)->create()
];

Dan jika kami ingin mengulangi hasil kami, kami mendapatkan Model Data, bukan model yang sebenarnya (diwariskan):

foreach ($productResults->getItems() as $product) {
    echo get_class($product); // \Magento\Catalog\Model\Data\Product
}

Abstraksi semacam ini mengikuti prinsip SOLID dan merangkul prinsip 'komposisi atas warisan' . Setiap operasi 'eksotis' yang kalau tidak akan dilakukan pada koleksi (seperti bergabung untuk contoh) dilakukan secara internal dalam repositori, yang membuatnya juga lebih mudah untuk digunakan di luar modul.

Pertanyaan:

Semua ini membuat saya bertanya-tanya: dengan seluruh repositori / model data-pendekatan, apakah ada ruang di masa depan Magento 2 untuk koleksi? Apakah koleksi hanya untuk digunakan secara internal oleh modul itu sendiri dan bukan di luarnya? Atau apakah akan ditinggalkan demi Entity Manager?

Saat ini, jika Anda ingin merangkul Model Data, Anda masih harus membuat model yang diwarisi (diwarisi dari \Magento\Framework\Model\AbstractModel) hanya untuk mendapatkan koleksi bekerja (karena Magento\Framework\Data\Collection::setItemObjectClassmemerlukan model untuk memperpanjang dari Magento\Framework\DataObject). Dan Anda perlu koleksi untuk dapat memfilter di repositori Anda. Tetapi sekali lagi, dalam repositori Anda harus 'mengkonversi' Model (biasa) Anda ke Model Data.

Atau apakah kita harus mengimplementasikannya seperti Repositori Pesanan, yang getList()mengembalikan instance Magento\Sales\Api\Data\OrderSearchResultInterface, tetapi di bawah air hasil pencarian tidak lebih dari kumpulan biasa yang mengimplementasikan antarmuka ini. Fakta menyenangkan: hasil pencarian menyatakan akan mengembalikan array Model Data ( Magento\Sales\Api\Data\OrderInterface[]), tetapi jika Anda menganalisis kode, getItems()akan mengeksekusi Magento\Framework\Data\Collection::getItems()yang mengembalikan bukan model data, tetapi model urutan (sebagaimana ditetapkan oleh Magento\Sales\Model\ResourceModel\Order\Collection::_construct()). Begitu banyak untuk 'komposisi atas warisan'.

Banyak pertanyaan tentang apa cara yang tepat di Magento 2. Sekali lagi, ada 100 cara melakukan hal yang sama, tetapi apa itu 'Cara Magento'? Atau apakah saya benar-benar di jalur yang salah di sini?

Giel Berkers
sumber
2
Mengajukan pertanyaan nyata di sini +1. Saya akan sangat menyukai jawaban inti dev di sini
Marius
Saya yakin rencananya Koleksi akan dihapus. Namun seperti yang Anda perhatikan ini hampir tidak hampir selesai dan ada banyak area yang tampaknya berada di berbagai negara sedang di-refactored (memiliki api stabil sebagai Magento \ Penjualan \ Api \ Data \ OrderSearchResultInterface, memungkinkan Magento untuk menggantikan apa terjadi di bawah tenda lebih mudah nanti). Tidak membantu bahwa berbagai implementasi getList belum mampu seperti yang saat ini dapat kita lakukan dengan koleksi. Ketidakkonsistenan yang Anda catat sekitar pengembalian dinyatakan mungkin layak untuk masalah di github.
Kristof at Fooman

Jawaban:

16

Koleksi tidak ditinggalkan sekarang. Sementara beberapa modul telah mengekspos API Kontrak Layanan, yang lain masih mengekspos hanya API Model / Koleksi.

Rencananya adalah:

  1. Merefleksikan keadaan saat ini dengan cakupan @api yang lebih baik: membubuhi keterangan koleksi abstrak dan koleksi khusus di beberapa modul dengan @api
  2. Tingkatkan kerangka kerja ketekunan untuk memudahkan pembuatan Kontrak Layanan tanpa bergantung pada API berbasis warisan: Koleksi, Model, Model sumber daya
  3. Turunkan Koleksi Abstrak untuk tidak mempromosikan implementasi berbasis kontrak Layanan Kontrak
  4. Lepaskan modul versi yang lebih baru secara bertahap dengan API Kontrak Layanan

Jadi koleksi akan ditinggalkan pada beberapa titik, tetapi sekarang mereka adalah salah satu dari Magento 2 API.

Adapun implementasi Kontrak Layanan, - Model dan Koleksi adalah satu-satunya cara mudah untuk mengimplementasikannya di Magento <= 2.1. Kontrak Layanan hanyalah Antarmuka. Implementasinya bukan bagian dari API publik dan dapat diubah kemudian.

Anton Kril
sumber
1
Terima kasih atas jawaban anda. Jadi apa saran Anda untuk pengembang yang membuat modul baru? Strategi saya saat ini adalah membuat kontrak layanan yang (di bawah air) masih menggunakan koleksi karena a) membuat penyaringan mudah, dan b) manajer entitas masih terlalu eksperimental / tidak berdokumen. Pada titik tertentu cara kerja bagian dalam dapat diganti dengan yang lain tetapi antarmuka tetap sama. Tetapi jika saya memahami jawaban Anda dengan benar, itulah cara yang tepat untuk saat ini, bukan?
Giel Berkers
Benar. Saya mengedit jawaban saya untuk mencerminkan ini.
Anton Kril
1
Mempertimbangkan hal di atas, apa cara yang tepat untuk mengimplementasikan fungsionalitas yang membutuhkan data yang tidak dapat diambil melalui kontrak layanan? Sebagai contoh, jika modul A mengharuskan semua pesanan difilter dengan metode pembayaran.
Stjepan