Logo BrocksiNet

BrocksiNet

Try to clean the web

What's the difference between product.repository and sales_channel.product.repository in Shopware 6?

Looks easy? ๐Ÿ˜‰ But did you checked in detail the differences or you just use always the product.repository? Let's deep dive into the core files to fully understand the differences so you can decide what to use when. ๐Ÿ’™

First of all there is a file called: EntityRepositoryInterface.php where you can see what kind of methodes you can use like search, update, merge and many more. You need to know that Shopware 6 uses Data Abstraction Layer (DAL) and generates for every entity the correspondending repository class. So normally you can use always the same functions for every entity repository.

But ๐Ÿ˜ˆ the sales_channel.product.repository is using this interface: SalesChannelRepositoryInterface.php and there we have only these three functions like search, aggregate, searchIds. This means you can only use this to search for products, aggregate some additional data to the product defaults data and search for Ids. So you can not use the sales_channel.product.repository to update, delete or create products. That's big difference depending on what you need to do. What else do we got? ๐Ÿค”

So if you search with the sales_channel.product.repository it will call a function called processCriteria and this function will check if $this->definition is an Interface called: SalesChannelDefinitionInterface and this Interface will be called with a function that is also called processCriteria. Let's look at the implemtaion of this function:

public function processCriteria(Criteria $criteria, SalesChannelContext $context): void
{
    $criteria
        ->addAssociation('prices')
        ->addAssociation('unit')
        ->addAssociation('deliveryTime')
        ->addAssociation('cover.media')
    ;

    if (!$this->hasAvailableFilter($criteria)) {
        $criteria->addFilter(
            new ProductAvailableFilter($context->getSalesChannel()->getId(), ProductVisibilityDefinition::VISIBILITY_LINK)
        );
    }
}

So this function is adding some default associations and also adding the ProductAvailableFilter. So you only will get products that are assigned to the salesChannel, are visible and active. Keep this in mind. Because this can burn a lot of time when you search for some specific product. Here are the conditions from the ProductAvailableFilter.

class ProductAvailableFilter extends MultiFilter
{
    public function __construct(string $salesChannelId, int $visibility = ProductVisibilityDefinition::VISIBILITY_ALL)
    {
        parent::__construct(
            self::CONNECTION_AND,
            [
                new RangeFilter('product.visibilities.visibility', [RangeFilter::GTE => $visibility]),
                new EqualsFilter('product.visibilities.salesChannelId', $salesChannelId),
                new EqualsFilter('product.active', true),
            ]
        );
    }
}

Also do not forget that the sales_channel.product.repository is loading prices and the product.repository is not loading any association out of the box.

Released - 16.11.2021

Comments


About the author

Bild Bjoern
Bjรถrn MeyerSoftware Engineer
Bjรถrn is interested in the details of web technologies. He started with Joomla, Drupal, Typo3, vBulletin, Fireworks and Photoshop. Today his focus is on PHP for example with Magento 2, Shopware 6 and Symfony. He also likes JavaScript with Angular, React, VueJs and TypeScript. In his free time, he seeks constant balance with swimming, running and yoga.