Magento 2: Jak filtrować kolekcję produktów według identyfikatora sklepu

11

Korzystając z obiektu fabryki produktów, mogę utworzyć produkt, pobrać kolekcję produktów i pobrać pierwszy element z tej kolekcji

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

Jeśli jednak spróbuję dodać identyfikator_sklepu do filtra kolekcji

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

Pojawia się następujący błąd

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}

To samo dzieje się, jeśli spróbuję użyć repozytorium produktów do filtrowania według store_id (repozytoria używają kolekcji pod maską).

Czy to błąd? A może relacje między sklepami, stronami internetowymi i produktami zmieniły się w Magento 2, tak że nie jest to już uzasadnione zapytanie? Obie? Ani? Coś innego?

Alan Storm
źródło
Jestem bardzo nowy w M2, ale czy nie możesz użyć tego github.com/magento/magento2/blob/develop/app/code/Magento/... ?
fmrng
@fnng Użyj metody, aby wiedzieć, ale chcę powiedzieć „proszę o listę wszystkich produktów, które są częścią sklepu X”. Nie jestem pewien, jak setStoreId by to zrobił.
Alan Storm,

Odpowiedzi:

4

Możesz to zrobić za pomocą metody addStoreFilter(), patrzMagento\Catalog\Model\ResourceModel\Product\Collection#addStoreFilter()

addStoreFilter()funkcja będzie akceptować sklepu identyfikator lub Storeobiekt jako parametr.

EG, aby uzyskać wszystkie produkty dla bieżącego sklepu:

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

Mam nadzieję, że to pomaga.

Amit Bera
źródło
Dzięki @amitbeta! Jeśli masz chwilę - czy wiesz, czy można utworzyć filtr sklepu za pomocą repozytoriów produktów? magento.stackexchange.com/questions/91278/…
Alan Storm
na pewno .. będę szukać
Amit Bera
@AmitBera, proszę wyjaśnić trochę, jak używać addStoreFilter () do kolekcji produktów.
5

Na razie wygląda to na błąd, ponieważ nie ma możliwości zastosowania filtru sklepu za pomocą ProductRepository::getList()metody, przekazując identyfikator sklepu jako filtr SearchCriteria .

W implementacji getList można stwierdzić, że wszystkie filtry z SearchCriteria zastosowano do kolekcji

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

W Magento\Catalog\Model\ProductRepository::addFilterGroupToCollectionnie ma specjalnego traktowania dla filtru kategorii , ale nie ma nikogo do sklepu.

Tak więc należy dodać dodatkowy warunek, Magento\Catalog\Model\ProductRepository::addFilterGroupToCollectionktóry sprawdza, czy mamy filtr sklepu, a jeśli mamy - ustawiam identyfikator sklepu do zbierania, na przykład:

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

Utworzono wewnętrzny błąd dla tego problemu, jego numer to MAGETWO-45950

Igor Minyaylo
źródło
Jakieś wieści na ten temat? Nie mogę znaleźć odniesienia do numeru biletu na Github.
Fabian Schmengler,
1
W Magento 2 produkty są przypisane do stron internetowych, a nie do sklepów. Tak więc początkowe zachowanie opisane przez Alana jest prawidłowe, ponieważ jednostka produktu nie ma linku do identyfikatora sklepu, wystarczy link do identyfikatora witryny. A bilet wewnętrzny dotyczy wprowadzenia atrybutu rozszerzenia z ProductWebsiteLinkInterface do ProductInterface
Igor Minyaylo
Oprócz powiązania sklepu / strony internetowej, nie setStore()określa również, które konkretne atrybuty sklepu są pobierane? Czy jest to teraz robione w inny sposób?
Fabian Schmengler
Istnieją metody setStoreId / getStoreId w implementacji modelu produktu, ale nie ma żadnych w interfejsie ProductInterface, więc nie jest zalecane poleganie na nich w logice biznesowej.
Igor Minyaylo,
Na razie rozwiązanie dla wartości poziomu StoreView (na przykład lokalizacja atrybutów) dokonanych przez część StoreID URL w interfejsach API REST
Igor Minyaylo
0

Jeśli używasz modelu niestandardowego z kilkoma tabelami, dodaj nazwę_tabeli, taką jak: addFieldToFilter('**table_name.**column_name', 1)

PolyakovAO
źródło
Czy mógłbyś udostępnić cały fragment kodu do ładowania kolekcji produktów z mojej kolumny, powiedz identyfikator podmiotu, jak powiedziałeś powyżej
Sushivam
0

1) Klasa jest \Magento\Catalog\Model\ResourceModel\Category\Collection:

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

2) Zatem metoda jest $collection->setStoreId(0);

Giedrius Tumelis
źródło
PS zamiast 0 możesz podać swój identyfikator sklepu 1, 2, ...
Giedrius Tumelis
Meta: Z jakiegoś powodu symbol gwiazdy został usunięty z mojej wiadomości tutaj.
Giedrius Tumelis