Magento 2: Cómo filtrar una colección de productos por ID de tienda

11

Utilizando un objeto de fábrica de productos, puedo crear un producto, tomar una colección de productos y obtener el primer elemento de esa colección

/* var $productFactory \Magento\Catalog\Model\ProductFactory */
$product = $this->productFactory->create()->getCollection()->getFirstItem();

Sin embargo, si intento agregar un store_id al filtro de la colección

    $product = $this->productFactory
        ->create()
        ->getCollection()
        ->addFieldToFilter('store_id', 1)
        ->getFirstItem();

Obtuve el siguiente error

Invalid attribute name: store_id
#0 /Users/alanstorm/Sites/magento-2-dev-docs.dev/magento2/app/code/Magento/Eav/Model/Entity/Collection/AbstractCollection.php(1434): Magento\Eav\Model\Entity\Collection\AbstractCollection->_addAttributeJoin('store_id', 'inner')
#1 /Users/alanstorm/Sites/magento-2-dev-docs.dev/magento2/app/code/Magento/Eav/Model/Entity/Collection/AbstractCollection.php(359): Magento\Eav\Model\Entity\Collection\AbstractCollection->_getAttributeConditionSql('store_id', 1, 'inner')
#2 /Users/alanstorm/Sites/magento-2-dev-docs.dev/magento2/app/code/Magento/Catalog/Model/Resource/Product/Collection.php(1489): Magento\Eav\Model\Entity\Collection\AbstractCollection->addAttributeToFilter('store_id', 1, 'inner')
#3 /Users/alanstorm/Sites/magento-2-dev-docs.dev/magento2/app/code/Magento/Eav/Model/Entity/Collection/AbstractCollection.php(382): Magento\Catalog\Model\Resource\Product\Collection->addAttributeToFilter('store_id', 1)
...
#63 {main}

Lo mismo sucede si intento usar un repositorio de productos para filtrar por store_id (los repositorios usan las colecciones bajo el capó).

¿Es esto un error? ¿O las relaciones entre tiendas, sitios web y productos han cambiado en Magento 2 de modo que ya no se trata de una consulta legítima? ¿Ambos? ¿Ninguno? ¿Algo más?

Alan Storm
fuente
Soy muy nuevo en M2, pero ¿no puedes usar este github.com/magento/magento2/blob/develop/app/code/Magento/… ?
fmrng
@fnng Use el método para saber, pero quiero decir "por favor, consígame una lista de todos los productos que forman parte de la tienda X". No estoy seguro de cómo setStoreId haría eso.
Alan Storm

Respuestas:

4

Puede hacer esto con el método addStoreFilter(), veaMagento\Catalog\Model\ResourceModel\Product\Collection#addStoreFilter()

la addStoreFilter()función aceptará la identificación de la tienda o el Storeobjeto como parámetro.

Por ejemplo, para obtener todos los productos para la tienda actual :

public function getProducts(){
    return $this->collection->addStoreFilter($this->_storeManager->getStore()); 
}

Con suerte, esto ayuda.

Amit Bera
fuente
Gracias @amitbeta! Si tiene un momento, ¿sabe si es posible crear un filtro de tienda utilizando repositorios de productos? magento.stackexchange.com/questions/91278/…
Alan Storm
claro .. voy a mirar
Amit Bera
@AmitBera, ¿Puede explicar un poco cómo usar addStoreFilter () para la colección de productos.
5

Por ahora esto parece un error, porque no hay posibilidad de aplicar el filtro de la tienda con el ProductRepository::getList()método, pasando la identificación de la tienda como un filtro de SearchCriteria .

En la implementación de getList, puede encontrar que todos los filtros de SearchCriteria se aplicaron a la colección

    foreach ($searchCriteria->getFilterGroups() as $group) {
        $this->addFilterGroupToCollection($group, $collection);
    }

En Magento\Catalog\Model\ProductRepository::addFilterGroupToCollectionexiste un manejo especial para el filtro Categoría , pero no hay nadie para tienda.

Por lo tanto, se debe agregar una condición adicional a la Magento\Catalog\Model\ProductRepository::addFilterGroupToCollectionque verifica si tenemos filtro de tienda y si tenemos - establecemos el ID de la tienda para la colección, algo como:

        if ($filter->getField() == \Magento\Catalog\Model\Product::STORE_ID) {
            $collection->setStore($filter->getValue());
            continue;
        }

Error interno creado para este problema, su número es MAGETWO-45950

Igor Minyaylo
fuente
¿Alguna noticia sobre eso? No puedo encontrar una referencia al número de ticket en Github.
Fabian Schmengler
1
En Magento 2, los productos se asignan a sitios web, no a tiendas. Por lo tanto, el comportamiento inicial descrito por Alan es correcto, ya que la entidad del Producto no tiene un enlace de Id. De tienda, solo vincula al Id. De sitio web. Y el ticket interno trata sobre la introducción del atributo Extension con ProductWebsiteLinkInterface en ProductInterface
Igor Minyaylo
Además de la asociación tienda / sitio web, ¿no setStore()especifica qué valores de atributo específicos de la tienda se obtienen? ¿O se hace esto de una manera diferente ahora?
Fabian Schmengler
Existen métodos setStoreId / getStoreId en la implementación del modelo de Producto, pero no hay ninguno en ProductInterface, por lo que no se recomienda confiar en ellos en la lógica de su negocio.
Igor Minyaylo
Por ahora resolviendo los valores de nivel de StoreView (por ejemplo, localización de atributos) realizados por la parte de URL de StoreID en las API REST
Igor Minyaylo
0

Si usa un modelo personalizado con varias tablas, agregue table_name como: addFieldToFilter('**table_name.**column_name', 1)

PolyakovAO
fuente
¿Podría compartir todo el fragmento para cargar la colección de productos de mi columna, por ejemplo, identificador de entidad, como ha dicho anteriormente
Sushivam
0

1) La clase es \Magento\Catalog\Model\ResourceModel\Category\Collection:

/** @var \Magento\Catalog\Model\ResourceModel\Category\Collection $collection */
$collection = $this->categoryFactory->create()->getCollection()
        ->addFieldToSelect('*');

2) Entonces el método es $collection->setStoreId(0);

Giedrius Tumelis
fuente
PD: en lugar de 0, puede poner su ID de tienda 1, 2, ...
Giedrius Tumelis
Meta: Por alguna razón, el símbolo de estrella fue eliminado de mi mensaje aquí.
Giedrius Tumelis