Sé que una gran cantidad de código que se encuentra actualmente en Magento 2 (2.1.2) está más o menos portado desde Magento 1 y que una gran cantidad de código será sustituido por un equivalente en el futuro. En este aspecto, me pregunto cuál es el futuro de las colecciones en Magento 2.
Dejame explicar:
Magento 1:
En Magento 1 estamos acostumbrados a obtener una colección como esta:
$products = Mage::getModel('catalog/product')->getCollection();
Luego podríamos aplicar filtros y otras operaciones a la colección:
$products->addAttributeToFilter('price', ['gteq' => 10]);
$products->addFieldToFilter('created_at', ['lt' => '2016-10-10']);
$products->setPageSize(10);
// ... etc ...
Y por último pero no menos importante, nuestra colección devolvería los modelos:
foreach ($products as $product) {
echo get_class($product); // Mage_Catalog_Model_Product
}
Magento 2:
Magento agrega muchas capas nuevas de abstracción, implementando una forma de trabajo más SÓLIDA. Esto significa que cuando queremos una lista de entidades, la pedimos desde un repositorio:
$productResults = $this->productRepository->getList($searchCriteria);
Si queremos aplicar filtros, usamos una combinación de los SearchCriteriaBuilder
, los FilterGroupBuilder
, los FilterBuilder
y los 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()
];
Y si queremos iterar sobre nuestros resultados, obtenemos modelos de datos, no modelos reales (heredados):
foreach ($productResults->getItems() as $product) {
echo get_class($product); // \Magento\Catalog\Model\Data\Product
}
Este tipo de abstracción sigue el principio SÓLIDO y abarca el principio de "composición sobre herencia" . Cualquier operación 'exótica' que de otro modo se realizaría en la colección (como las combinaciones para ejemplos) se realiza internamente en el repositorio, lo que hace que sea más fácil de usar fuera del módulo.
La pregunta:
Todo esto me hace preguntarme: con todo el enfoque de repositorio / modelo de datos, ¿hay espacio en el futuro de Magento 2 para las colecciones? ¿Las colecciones solo deben ser utilizadas internamente por el módulo en sí y no fuera de él? ¿O van a quedar en desuso en favor del Entity Manager?
Actualmente, si desea adoptar los Modelos de datos, aún tiene que crear un modelo heredado (heredado de \Magento\Framework\Model\AbstractModel
) solo para que la colección funcione (ya que Magento\Framework\Data\Collection::setItemObjectClass
requiere que el modelo se extienda desde Magento\Framework\DataObject
). Y necesita una colección para poder filtrar en su repositorio. Pero, de nuevo, en el repositorio debe 'convertir' su Modelo (regular) en un Modelo de Datos.
¿O tenemos que implementarlo como el Repositorio de pedidos, donde getList()
devuelve una instancia de Magento\Sales\Api\Data\OrderSearchResultInterface
, pero bajo el agua los resultados de búsqueda no son más que una colección regular que implementa esta interfaz. Dato curioso: los resultados de búsqueda indican que devolverá una matriz de modelos de datos ( Magento\Sales\Api\Data\OrderInterface[]
), pero si analiza el código, getItems()
ejecutará lo Magento\Framework\Data\Collection::getItems()
que a cambio no devuelve los modelos de datos, sino los modelos de orden (según lo establecido por Magento\Sales\Model\ResourceModel\Order\Collection::_construct()
). Esto en cuanto a 'composición sobre herencia'.
Muchas preguntas sobre cuál es la forma correcta en Magento 2. Una vez más, hay 100 formas de hacer lo mismo, pero ¿qué es 'The Magento Way'? ¿O simplemente estoy totalmente en el camino equivocado aquí?