Czy historia kolekcji znajduje się w Magento 2?

25

Wiem, że dużo kodu, który jest obecnie w Magento 2 (2.1.2), jest mniej więcej przeniesiony z Magento 1 i że wiele kodu zostanie w przyszłości zastąpionych odpowiednikiem. W tym aspekcie zastanawiam się, jaka jest przyszłość kolekcji w Magento 2.

Pozwól mi wyjaśnić:

Magento 1:

W Magento 1 jesteśmy przyzwyczajeni do uzyskania takiej kolekcji:

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

Następnie możemy zastosować filtry i inne operacje do kolekcji:

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

I wreszcie, nasza kolekcja zwróci modele:

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

Magento 2:

Magento dodaje wiele nowych warstw abstrakcji, wdrażając bardziej SOLIDNY ​​sposób pracy. Oznacza to, że gdy potrzebujemy listy podmiotów, pytamy ją z repozytorium:

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

Jeśli chcemy zastosować filtry używamy kombinacji SearchCriteriaBuilderThe FilterGroupBuilderThe FilterBuilderoraz 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()
];

A jeśli chcemy powtórzyć nasze wyniki, otrzymujemy Modele danych, a nie rzeczywiste (odziedziczone) modele:

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

Ten rodzaj abstrakcji jest zgodny z zasadą SOLID i obejmuje zasadę „kompozycja nad dziedziczeniem” . Wszelkie „egzotyczne” operacje, które w innym przypadku zostałyby wykonane na kolekcji (np. Sprzężenia na przykład), są wykonywane wewnętrznie w repozytorium, co ułatwia także korzystanie poza modułem.

Pytanie:

Wszystko to sprawia, że ​​zastanawiam się: czy przy całym podejściu do repozytorium / modelu danych jest w przyszłości miejsce na kolekcje Magento 2? Czy kolekcje mają być używane tylko wewnętrznie przez sam moduł, a nie poza nim? A może zostanie wycofany na korzyść Entity Managera?

Obecnie, jeśli chcesz objąć Modele danych, nadal musisz utworzyć model odziedziczony (dziedziczony z \Magento\Framework\Model\AbstractModel), aby kolekcja działała (ponieważ Magento\Framework\Data\Collection::setItemObjectClasswymaga rozszerzenia modelu Magento\Framework\DataObject). I musisz zbierać, aby móc filtrować w swoim repozytorium. Ale z drugiej strony w repozytorium musisz „przekonwertować” swój (zwykły) model na model danych.

Czy musimy zaimplementować go tak, jak Repozytorium zamówień, w którym getList()zwraca instancję Magento\Sales\Api\Data\OrderSearchResultInterface, ale pod wodą wyniki wyszukiwania są niczym więcej niż zwykłą kolekcją, która implementuje ten interfejs. Ciekawostka: wyniki wyszukiwania wskazują, że zwróci tablicę modeli danych ( Magento\Sales\Api\Data\OrderInterface[]), ale jeśli przeanalizujesz kod, getItems()wykona on, Magento\Framework\Data\Collection::getItems()który w zamian zwróci nie modele danych, ale modele porządkowe (ustawione przez Magento\Sales\Model\ResourceModel\Order\Collection::_construct()). Tyle o „kompozycji nad dziedziczeniem”.

Wiele pytań o właściwy sposób w Magento 2. Znów istnieje 100 sposobów na zrobienie tego samego, ale czym jest „The Magento Way”? A może po prostu jestem na niewłaściwym torze?

Giel Berkers
źródło
2
Zadawanie prawdziwych pytań tutaj +1. Naprawdę chciałbym tutaj znaleźć odpowiedź od głównego dewelopera
Marius
Uważam, że planem jest wycofanie kolekcji. Jednak, jak zauważyłeś, nie jest to nawet bliskie osiągnięcia i istnieje wiele obszarów, które wydają się być w różnych stanach refaktoryzacji (mając stabilny interfejs API jako Magento \ Sales \ Api \ Data \ OrderSearchResultInterface, pozwala Magento na zastąpienie tego, co łatwiej będzie później). Nie pomaga to, że różne implementacje getList nie są jeszcze tak skuteczne, jak to, co możemy obecnie zrobić z kolekcjami. Niezgodność, którą zauważyłeś wokół zwrotu, może być warta rozwiązania problemu na github.
Kristof w Fooman

Odpowiedzi:

16

Kolekcje nie są już przestarzałe. Podczas gdy niektóre moduły już udostępniają interfejsy API umów serwisowych, inne wciąż udostępniają tylko interfejsy API modeli / kolekcji.

Plan jest następujący:

  1. Odzwierciedlaj aktualny stan dzięki lepszemu pokryciu @api: adnotuj kolekcje abstrakcyjne i określone kolekcje w niektórych modułach za pomocą @api
  2. Ulepsz strukturę utrwalania, aby umożliwić łatwe tworzenie umów serwisowych bez polegania na interfejsach API opartych na dziedziczeniu: kolekcje, modele, modele zasobów
  3. Przestarzałe zbiory abstrakcyjne nie promują opartych na kolekcji wdrożeń umów serwisowych
  4. Stopniowo wypuszczaj nowsze wersje modułów z interfejsami API umów serwisowych

Kolekcje będą w pewnym momencie przestarzałe, ale teraz są jednym z interfejsów API Magento 2.

Jeśli chodzi o wdrażanie umów serwisowych, - Modele i kolekcje są jedynym wygodnym sposobem na ich wdrożenie w Magento <= 2.1. Umowy serwisowe to tylko interfejsy. Ich implementacja nie jest częścią publicznego interfejsu API i może zostać później zmieniona.

Anton Kril
źródło
1
Dzięki za odpowiedź. Jaka jest zatem twoja rada dla programistów tworzących nowe moduły? Moja obecna strategia polega na tworzeniu umów serwisowych, które (pod wodą) nadal wykorzystują kolekcje, ponieważ a) ułatwia filtrowanie, oraz b) menedżer encji jest nadal zbyt eksperymentalny / nieudokumentowany. W pewnym momencie wewnętrzne funkcjonowanie można zastąpić czymkolwiek innym, ale interfejs pozostaje taki sam. Ale jeśli dobrze rozumiem twoją odpowiedź, to na razie właściwy sposób, prawda?
Giel Berkers,
Poprawny. Zredagowałem swoją odpowiedź, aby to odzwierciedlić.
Anton Kril,
1
Biorąc pod uwagę powyższe, jaki byłby właściwy sposób wdrożenia funkcjonalności wymagającej danych, których nie można pobrać za pośrednictwem umów serwisowych? Na przykład, jeśli moduł A wymaga wszystkich zamówień filtrowanych według metody płatności.
Stjepan