shopwareshopware6

Get total number of products in ProductListingCriteriaEvent in Shopware 6


I have a very simple subscriber to compute the total number of products for a product listing. My intention is to redirect the user when the pagination overshoots the total number of pages.

class PaginationSubscriberTest implements EventSubscriberInterface
{
    private EntityRepository $productRepository;

    public function __construct(EntityRepository $productRepository)
    {
        $this->productRepository = $productRepository;
    }

    public static function getSubscribedEvents(): array
    {
        return [
            ProductListingCriteriaEvent::class => 'onProductListingLoaded',
        ];
    }

    public function onProductListingLoaded(ProductListingCriteriaEvent $event): void
    {
        $total = $this->productRepository->searchIds($event->getCriteria(), $event->getContext())->getTotal();
    }
}

The total number of products is completely different from the number of products I see in the frontend. $total gives me something like 45k (which is way to high) whereas I only see like 450 products in the listing on the frontend side. How can I get the same number as in the frontend?


Solution

  • Are you using the product.repository or the sales_channel.repository in your DI?

    The product.repository will return all products in your project. In my case it returns 1175 products.

    When using the sales_channel.product.repository it applies the ProductAvailableFilter and ProductCloseoutFilter to the criteria, so

    In my case then 275 products are returned, see ProductListingLoader for the implementation.

    Also in my Twig extend for the file views/storefront/component/product/listing.html.twig you can use the searchResult.total to get the total amount of products inside the category, for example:

    {% sw_extends '@Storefront/storefront/component/product/listing.html.twig' %}
    
    {% block element_product_listing_pagination_nav_actions %}
        <div class="cms-element-product-listing-actions row justify-content-between">
            <div class="col-auto">
                {% block element_product_listing_pagination_nav_top %}
                    <span class="product-count">
                       {{ searchResult.total }} product(s)
                    </span>
                    {# Remove pagination top #}
                {% endblock %}
            </div>
    
            <div class="col-auto">
                {% block element_product_listing_sorting %}
                    {% sw_include '@Storefront/storefront/component/sorting.html.twig' with {
                        current: searchResult.sorting,
                        sortings: searchResult.availableSortings
                    } %}
                {% endblock %}
            </div>
        </div>
    {% endblock %}

    Code above is working for Shopware 6.5.8.16