Magento 2: Как отфильтровать коллекцию товаров по идентификатору магазина

11

Используя объект фабрики продуктов, я могу создать продукт, получить коллекцию продуктов и получить первый элемент этой коллекции.

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

Однако, если я попытаюсь добавить store_id в фильтр коллекции

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

Я получаю следующую ошибку

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}

То же самое происходит, если я пытаюсь использовать репозиторий продуктов для фильтрации по store_id (репозитории используют коллекции изнутри).

Это ошибка? Или в Magento 2 изменились отношения между магазинами, веб-сайтами и продуктами, так что этот запрос больше не является законным? И то и другое? Ни? Что-то другое?

Алан Сторм
источник
Я очень новичок в M2, но вы не можете использовать этот github.com/magento/magento2/blob/develop/app/code/Magento/… ?
2015 г.
@fnng Используйте метод, чтобы узнать, но я хочу сказать: «Пожалуйста, принесите мне список всех продуктов, которые являются частью магазина X». Не уверен, как setStoreId сделает это.
Алан Сторм

Ответы:

4

Вы можете сделать это с помощью метода addStoreFilter(), см.Magento\Catalog\Model\ResourceModel\Product\Collection#addStoreFilter()

addStoreFilter()функция принимает идентификатор магазина или Storeобъект в качестве параметра.

Например, чтобы получить все товары для текущего магазина:

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

Надеюсь, это поможет.

Amit Бера
источник
Спасибо @amitbeta! Если у вас есть момент - знаете ли вы, возможно ли создать магазинный фильтр, используя репозитории продуктов? magento.stackexchange.com/questions/91278/…
Алан Сторм
конечно .. я посмотрю
Амит Бера
@AmitBera, не могли бы вы немного объяснить, как использовать addStoreFilter () для сбора продуктов.
5

На данный момент это выглядит как ошибка, потому что нет возможности применить фильтр магазина с ProductRepository::getList()методом, передавая идентификатор магазина в качестве фильтра SearchCriteria .

В реализации getList вы можете обнаружить, что все фильтры из SearchCriteria применяются к коллекции.

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

В Magento\Catalog\Model\ProductRepository::addFilterGroupToCollectionесть специальная обработка категории фильтра , но не один для магазина.

Итак, нужно добавить дополнительное условие, Magento\Catalog\Model\ProductRepository::addFilterGroupToCollectionкоторое проверяет, есть ли у нас фильтр хранилища и, если есть, - установить идентификатор хранилища для коллекции, что-то вроде:

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

Создана внутренняя ошибка для этой проблемы, ее номер MAGETWO-45950

Игорь Миняйло
источник
Есть новости по этому поводу? Я не могу найти ссылку на номер билета на Github.
Фабиан Шменглер
1
В Magento 2 продукты предназначены для веб-сайтов, а не для магазинов. Итак, первоначальное поведение, описанное Аланом, является правильным, так как сущность Product не имеет ссылки Store Id, просто ссылка на Идентификатор веб-сайта. И Внутренний тикет о введении атрибута Extension с ProductWebsiteLinkInterface в ProductInterface
Игорь Миняйло
Помимо связи магазин / веб-сайт, setStore()также не указывается, какие значения атрибутов конкретного магазина выбираются? Или это теперь сделано по-другому?
Фабиан Шменглер
В реализации модели продукта есть методы setStoreId / getStoreId, но в ProductInterface их нет, поэтому не рекомендуется полагаться на них в своей бизнес-логике.
Игорь Миняйло
На данный момент разрешаем значения уровня StoreView (например, локализацию атрибутов), сделанные URL-частью StoreID в API REST
Игорь Миняйло
0

Если вы используете пользовательскую модель с несколькими таблицами, добавьте table_name, например: addFieldToFilter('**table_name.**column_name', 1)

PolyakovAO
источник
Не могли бы вы поделиться целым фрагментом для загрузки коллекции продуктов из моей колонки, скажем, идентификатор сущности, как вы сказали выше
Sushivam
0

1) Класс это \Magento\Catalog\Model\ResourceModel\Category\Collection:

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

2) Тогда метод $collection->setStoreId(0);

Гедриус ​​Тумелис
источник
PS вместо 0 вы можете поставить свой магазин с идентификатором 1, 2, ...
Giedrius Tumelis
Мета: По какой-то причине символ звезды был удален из моего сообщения здесь.
Гедриус ​​Тумелис,