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 FilterBuilder
e 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::setItemObjectClass
requer 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?