Magento 2: comment filtrer une collection de produits par ID de magasin


11

À l'aide d'un objet de fabrique de produits, je peux créer un produit, récupérer une collection de produits et récupérer le premier élément de cette collection

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

Cependant, si j'essaye d'ajouter un store_id au filtre de la collection

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

J'obtiens l'erreur suivante

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}

La même chose se produit si j'essaie d'utiliser un référentiel de produit pour filtrer par store_id (les référentiels utilisent les collections sous le capot).

Est-ce un bug? Ou les relations entre les magasins, les sites Web et les produits ont-elles changé dans Magento 2 de sorte que ce n'est plus une requête légitime? Tous les deux? Ni? Autre chose?


Je suis très nouveau sur M2, mais ne pouvez-vous pas utiliser ce github.com/magento/magento2/blob/develop/app/code/Magento/… ?
fmrng

@fnng Utilisez la méthode pour le savoir, mais je veux dire "veuillez me donner une liste de tous les produits qui font partie du magasin X". Je ne sais pas comment setStoreId ferait cela.
Alan Storm

Réponses:


4

Vous pouvez le faire avec la méthode addStoreFilter(), voirMagento\Catalog\Model\ResourceModel\Product\Collection#addStoreFilter()

la addStoreFilter()fonction acceptera l'ID de magasin ou l' Storeobjet comme paramètre.

EG, pour obtenir tous les produits du magasin actuel :

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

Espérons que cela aide.


Merci @amitbeta! Si vous avez un moment - savez-vous s'il est possible de créer un filtre de magasin à l'aide de référentiels de produits? magento.stackexchange.com/questions/91278/…
Alan Storm

bien sûr .. je vais regarder
Amit Bera

@AmitBera, pouvez-vous expliquer un peu comment utiliser addStoreFilter () pour la collection de produits.

5

Pour l'instant, cela ressemble à un bogue, car il n'y a aucune possibilité d'appliquer un filtre de magasin avec la ProductRepository::getList()méthode, en passant l'ID de magasin comme filtre de SearchCriteria .

Dans l'implémentation getList, vous pouvez constater que tous les filtres de SearchCriteria appliqués à la collection

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

Il Magento\Catalog\Model\ProductRepository::addFilterGroupToCollectiony a une manipulation spéciale pour le filtre de catégorie , mais il n'y a personne pour Store.

Donc, une condition supplémentaire devrait être ajoutée pour Magento\Catalog\Model\ProductRepository::addFilterGroupToCollectionvérifier si nous avons un filtre de magasin et si nous avons - définir l'ID de magasin pour la collecte, quelque chose comme:

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

Bogue interne créé pour ce problème, son numéro est MAGETWO-45950


Des nouvelles à ce sujet? Je ne trouve pas de référence au numéro de ticket sur Github.
Fabian Schmengler

1
Dans Magento 2, les produits sont attribués à des sites Web et non à des magasins. Ainsi, le comportement initial décrit par Alan est correct, car l'entité produit n'a pas de lien d'ID de magasin, il suffit de créer un lien vers l'ID de site Web. Et le ticket interne concerne l'introduction de l'attribut Extension avec ProductWebsiteLinkInterface dans ProductInterface
Igor Minyaylo

Outre l'association magasin / site Web, ne setStore()spécifie pas également les valeurs d'attribut spécifiques au magasin qui sont récupérées? Ou est-ce que cela se fait différemment maintenant?
Fabian Schmengler

Il existe des méthodes setStoreId / getStoreId dans l'implémentation du modèle de produit, mais il n'y en a pas dans ProductInterface, il n'est donc pas recommandé de les utiliser dans votre logique métier.
Igor Minyaylo

Pour l'instant, résolution des valeurs de niveau StoreView (par exemple, localisation des attributs) effectuées par la partie URL StoreID dans les API REST
Igor Minyaylo

0

Si vous utilisez un modèle personnalisé avec plusieurs tables, ajoutez table_name comme: addFieldToFilter('**table_name.**column_name', 1)


Pourriez-vous s'il vous plaît partager l'extrait entier pour charger la collection de produits à partir de ma colonne, dites l'ID d'entité, comme vous l'avez dit ci
Sushivam

0

1) La classe est \Magento\Catalog\Model\ResourceModel\Category\Collection:

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

2) Ensuite, la méthode est $collection->setStoreId(0);


PS au lieu de 0, vous pouvez mettre votre identifiant de magasin 1, 2, ...
Giedrius Tumelis

Meta: Pour une raison quelconque, le symbole étoile a été supprimé de mon message ici.
Giedrius Tumelis
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.