In Shopware I want to implement pagination for reviews on the product detail-page.
To achieve this I extend pagination.html.twig
{% sw_include '@Storefront/storefront/component/pagination.html.twig' with {
entities: reviews,
criteria: criteria,
} %}
Because I wanted to customize the limit of the items per page I made a custom decorator
<?php declare(strict_types=1);
namespace My\App\Decorators;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Shopware\Storefront\Page\Product\Review\ProductReviewLoader;
use Symfony\Component\HttpFoundation\Request;
use Shopware\Storefront\Page\Product\Review\ReviewLoaderResult;
final class ProductDetailPageReviewPagerDecorator extends ProductReviewLoader
{
private const LIMIT = 3;
private ProductReviewLoader $decorated;
public function __construct(ProductReviewLoader $decorated)
{
$this->decorated = $decorated;
}
public function load(Request $request, SalesChannelContext $context): ReviewLoaderResult
{
$request->attributes->set("limit", $request->get("limit", self::LIMIT));
return $this->decorated->load($request, $context);
}
}
The pagination is not showing, the issue is the totalPages
variable in pagination.html.twig
.
{% set totalPages = (entities.total / criteria.limit)|round(0, 'ceil') %}
The totalPages is calculated by using entities.total
but this contains the value of the amount of LOADED reviews which by definition is equal to or lower then the limit. So totalPages is always 1.
There is also a variable totalReviews
which does contain the correct amount of totalReviews. So by making the following change:
{% set totalPages = (entities.totalReviews / criteria.limit)|round(0, 'ceil') %}
it does work. But making changes in the vendor Shopware-core of course is not allowed.
Other disallowed options
pdp-pagination.html.twig
containing the following code{% sw_extends '@Storefront/storefront/component/pagination.html.twig' %}
{% block component_pagination_nav %}
{% set currentPage = ((criteria.offset + 1) / criteria.limit )|round(0, 'ceil') %}
{% set totalPages = (entities.totalReviews / criteria.limit)|round(0, 'ceil') %}
{% if totalPages > 1 %}
<nav aria-label="pagination" class="pagination-nav">
{% block component_pagination %}
{% set totalPages = (entities.totalReviews / criteria.limit)|round(0, 'ceil') %}
{{ parent() }}
{% endblock %}
</nav>
{% endif %}
{% endblock %}
This fixes the issue but is not allowed.
public function load(Request $request, SalesChannelContext $context): ReviewLoaderResult
{
$request->attributes->set("limit", $request->get("limit", self::LIMIT));
$result = $this->decorated->load($request, $context);
$reflectionReviewLoaderResult = new ReflectionClass($result);
$reviewLoaderResultTotal = $reflectionReviewLoaderResult->getProperty('total');
$reviewLoaderResultTotal->setAccessible(true);
$reviewLoaderResultTotal->setValue($result, $result->getTotalReviews());
return $result;
}
So how would I fix this?
Use $criteria->setTotalCountMode(Criteria::TOTAL_COUNT_MODE_EXACT);
.