Я знаю, что большая часть кода, который в настоящее время находится в Magento 2 (2.1.2), более или менее перенесена из Magento 1, и что большая часть кода будет заменена эквивалентом в будущем. В этом аспекте мне интересно, каково будущее коллекций в Magento 2.
Позволь мне объяснить:
Magento 1:
В Magento 1 мы привыкли получать такую коллекцию:
$products = Mage::getModel('catalog/product')->getCollection();
Затем мы можем применить фильтры и другие операции к коллекции:
$products->addAttributeToFilter('price', ['gteq' => 10]);
$products->addFieldToFilter('created_at', ['lt' => '2016-10-10']);
$products->setPageSize(10);
// ... etc ...
И, наконец, наша коллекция вернет модели:
foreach ($products as $product) {
echo get_class($product); // Mage_Catalog_Model_Product
}
Magento 2:
Magento добавляет много новых слоев абстракции, реализуя более твердый способ работы. Это означает, что когда мы хотим получить список объектов, мы запрашиваем его из репозитория:
$productResults = $this->productRepository->getList($searchCriteria);
Если мы хотим применить фильтры мы используем комбинацию из SearchCriteriaBuilder
, то FilterGroupBuilder
, то FilterBuilder
и 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()
];
И если мы хотим перебрать наши результаты, мы получим модели данных, а не фактические (унаследованные) модели:
foreach ($productResults->getItems() as $product) {
echo get_class($product); // \Magento\Catalog\Model\Data\Product
}
Этот вид абстракции следует принципу SOLID и охватывает принцип «композиция поверх наследования» . Любые «экзотические» операции, которые в противном случае были бы выполнены в коллекции (например, объединения для примеров), выполняются внутри хранилища, что также облегчает использование вне модуля.
Вопрос:
Все это заставляет меня задуматься: при всем подходе к репозиторию / модели данных, есть ли место в будущем Magento 2 для коллекций? Разве коллекции используются только самим модулем, а не за его пределами? Или не рекомендуется использовать Entity Manager?
В настоящее время, если вы хотите использовать модели данных, вам все равно нужно создать унаследованную модель (унаследованную от \Magento\Framework\Model\AbstractModel
) только для того, чтобы заставить коллекцию работать (поскольку Magento\Framework\Data\Collection::setItemObjectClass
требуется, чтобы модель расширялась от Magento\Framework\DataObject
). И вам нужно собрать, чтобы иметь возможность фильтровать в вашем хранилище. Но опять же, в хранилище вы должны «преобразовать» свою (обычную) модель в модель данных.
Или мы должны реализовать его как репозиторий заказов, где getList()
возвращается экземпляр Magento\Sales\Api\Data\OrderSearchResultInterface
, но под водой результаты поиска - не что иное, как обычная коллекция, реализующая этот интерфейс. Интересный факт: в результатах поиска указывается, что он вернет массив Data Models ( Magento\Sales\Api\Data\OrderInterface[]
), но, если вы проанализируете код, getItems()
он выполнит, Magento\Framework\Data\Collection::getItems()
который, в свою очередь, вернет не модели данных, а модели порядка (как установлено Magento\Sales\Model\ResourceModel\Order\Collection::_construct()
). Вот вам и «композиция, а не наследство».
Много вопросов о том, как правильно поступить в Magento 2. Опять же, есть 100 способов сделать то же самое, но что такое «Путь Magento»? Или я просто на неправильном пути?