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 SearchCriteriaBuilder
The FilterGroupBuilder
The FilterBuilder
oraz 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::setItemObjectClass
wymaga 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?