Eu sei que muito código atualmente no Magento 2 (2.1.2) é mais ou menos portado do Magento 1 e que muito código será substituído por um equivalente no futuro. Nesse aspecto, estou me perguntando qual é o futuro das coleções no Magento 2.
Deixe-me explicar:
Magento 1:
No Magento 1, estamos acostumados a obter uma coleção como esta:
$products = Mage::getModel('catalog/product')->getCollection();
Poderíamos então aplicar filtros e outras operações à coleção:
$products->addAttributeToFilter('price', ['gteq' => 10]);
$products->addFieldToFilter('created_at', ['lt' => '2016-10-10']);
$products->setPageSize(10);
// ... etc ...
E por último mas não menos importante, nossa coleção retornaria os modelos:
foreach ($products as $product) {
echo get_class($product); // Mage_Catalog_Model_Product
}
Magento 2:
O Magento adiciona muitas novas camadas de abstração, implementando uma maneira mais sólida de trabalhar. Isso significa que, quando queremos uma lista de entidades, solicitamos em um repositório:
$productResults = $this->productRepository->getList($searchCriteria);
Se queremos aplicar filtros, usamos uma combinação de SearchCriteriaBuilder, the FilterGroupBuilder, the FilterBuildere the 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()
];
E se queremos iterar sobre nossos resultados, obtemos modelos de dados, não modelos reais (herdados):
foreach ($productResults->getItems() as $product) {
echo get_class($product); // \Magento\Catalog\Model\Data\Product
}
Esse tipo de abstração segue o princípio do SOLID e abrange o princípio da 'composição sobre herança' . Quaisquer operações 'exóticas' que de outra forma seriam realizadas na coleção (como junções para exemplos) são realizadas internamente no repositório, o que também facilita o uso fora do módulo.
A questão:
Tudo isso me faz pensar: com toda a abordagem de repositório / modelo de dados, existe algum espaço no futuro do Magento 2 para coleções? As coleções devem ser usadas apenas internamente pelo próprio módulo e não fora dele? Ou será preterido em favor do Entity Manager?
Atualmente, se você deseja adotar os Modelos de Dados, ainda precisa criar um modelo herdado (herdado de \Magento\Framework\Model\AbstractModel) apenas para que a coleção funcione (já que Magento\Framework\Data\Collection::setItemObjectClassrequer que o modelo seja estendido Magento\Framework\DataObject). E você precisa fazer a coleta para poder filtrar em seu repositório. Mas, novamente, no repositório você precisa 'converter' seu Modelo (regular) em um Modelo de Dados.
Ou temos que implementá-lo como o Repositório de Pedidos, em que getList()retorna uma instância de Magento\Sales\Api\Data\OrderSearchResultInterface, mas debaixo d'água os resultados da pesquisa nada mais são do que uma coleção regular que implementa essa interface. Curiosidade: os resultados da pesquisa indicam que ele retornará uma matriz de Modelos de Dados ( Magento\Sales\Api\Data\OrderInterface[]), mas se você analisar o código, getItems()executará o Magento\Framework\Data\Collection::getItems()que, em troca, não retornará os modelos de dados, mas os modelos de ordem (conforme definido por Magento\Sales\Model\ResourceModel\Order\Collection::_construct()). Tanta coisa para 'composição sobre herança'.
Muitas perguntas sobre qual é o caminho correto no Magento 2. Novamente, existem 100 maneiras de fazer a mesma coisa, mas o que é 'The Magento Way'? Ou estou totalmente no caminho errado aqui?