Magento 2: Como filtrar uma coleção de produtos por ID da loja

11

Usando um objeto de fábrica do produto, sou capaz de criar um produto, pegar uma coleção de produtos e buscar o primeiro item dessa coleção

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

No entanto, se eu tentar adicionar um store_id ao filtro da coleção

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

Eu obtenho o seguinte erro

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}

O mesmo acontece se eu tentar usar um repositório de produtos para filtrar por store_id (os repositórios usam as coleções sob o capô).

Isso é um inseto? Ou os relacionamentos entre lojas, sites e produtos foram alterados no Magento 2, de modo que essa não seja mais uma consulta legítima? Ambos? Nem? Algo mais?

Alan Storm
fonte
Eu sou muito novo no M2, mas você não pode usar este github.com/magento/magento2/blob/develop/app/code/Magento/… ?
fmrng
@fnng Use o método para saber, mas quero dizer "por favor, me dê uma lista de todos os produtos que fazem parte da loja X". Não tenho certeza de como o setStoreId faria isso.
Alan Storm

Respostas:

4

Você pode fazer isso com o método addStoreFilter(), consulteMagento\Catalog\Model\ResourceModel\Product\Collection#addStoreFilter()

a addStoreFilter()função aceitará o ID ou Storeobjeto da loja como parâmetro.

Por exemplo, para obter todos os produtos da loja atual :

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

Felizmente, isso ajuda.

Amit Bera
fonte
Obrigado @amitbeta! Se você tiver um momento - você sabe se é possível criar um filtro de loja usando repositórios de produtos? magento.stackexchange.com/questions/91278/...
Alan Storm
certeza .. i vai olhar
Amit Bera
@AmitBera, Você pode explicar um pouco como usar addStoreFilter () na coleção de produtos.
5

Por enquanto, isso parece um bug, porque não há possibilidade de aplicar filtro de loja com o ProductRepository::getList()método, passando o ID da loja como um filtro de SearchCriteria .

Na implementação getList, você pode encontrar todos os filtros de SearchCriteria aplicados à coleção

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

Em Magento\Catalog\Model\ProductRepository::addFilterGroupToCollectionhá tratamento especial para Categoria filtro , mas não há ninguém para Store.

Portanto, deve ser adicionada uma condição adicional para Magento\Catalog\Model\ProductRepository::addFilterGroupToCollectionverificar se temos filtro de loja e se definimos o ID da loja para coleta, algo como:

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

Criado bug interno para esse problema, seu número é MAGETWO-45950

Igor Minyaylo
fonte
Alguma notícia sobre isso? Não consigo encontrar uma referência ao número do bilhete no Github.
Fabian Schmengler
1
No Magento 2, os produtos são atribuídos a sites, não a lojas. Portanto, o comportamento inicial descrito por Alan está correto, pois a entidade Produto não possui um link de ID da loja, basta vincular ao ID do site. E bilhete interno é de cerca de introdução de atributo de extensão com ProductWebsiteLinkInterface no ProductInterface
Igor Minyaylo
Além da associação loja / site, setStore()também não especifica quais valores de atributo específicos da loja são buscados? Ou isso é feito de uma maneira diferente agora?
Fabian Schmengler
Existem métodos setStoreId / getStoreId na implementação do modelo do produto, mas não existem no ProductInterface, portanto, não é recomendável confiar neles na sua lógica de negócios.
Igor Minyaylo
Por agora resolver para valores de nível StoreView (por exemplo, a localização de atributos) feito por StoreID URL parte em APIs de REST
Igor Minyaylo
0

Se você usar o modelo personalizado com várias tabelas, adicione table_name como: addFieldToFilter('**table_name.**column_name', 1)

PolyakovAO
fonte
Você poderia por favor compartilhar todo o trecho para carregar a coleção produto da minha coluna digamos id entidade, como você disse acima
Sushivam
0

1) A turma é \Magento\Catalog\Model\ResourceModel\Category\Collection:

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

2) Então o método é $collection->setStoreId(0);

Giedrius Tumelis
fonte
PS em vez de 0 você pode colocar a sua loja ID de 1, 2, ...
Giedrius Tumelis
Meta: Por alguma razão, o símbolo da estrela foi removido da minha mensagem aqui.
Giedrius Tumelis