Shopware商品详情页评论分页计算错误,求合规修复方案
合规修复Shopware商品详情页评论分页问题
问题背景
我需要在Shopware商品详情页为评论实现分页功能,已完成以下操作:
- 扩展分页模板引入核心分页组件:
{% sw_include '@Storefront/storefront/component/pagination.html.twig' with { entities: reviews, criteria: criteria, } %}
- 编写自定义装饰器设置每页评论显示数量:
<?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); } }
问题现象
分页无法正常渲染,总页数始终显示为1。
问题根源
核心分页模板pagination.html.twig的总页数计算逻辑依赖entities.total,但该值是当前页已加载的评论数(最多等于每页限制),正确的总评论数实际存储在entities.totalReviews中。直接修改核心文件、新建独立分页组件、用反射修改私有属性均不符合Shopware合规开发规范。
合规解决方案
方案1:模板扩展+自定义参数传递
无需修改核心文件,通过模板扩展重写总页数计算逻辑,同时在引入分页组件时传入正确的总评论数:
- 修改分页组件引入代码,新增
total参数:
{% sw_include '@Storefront/storefront/component/pagination.html.twig' with { entities: reviews, criteria: criteria, total: reviews.totalReviews } %}
- 创建模板扩展文件
src/Resources/views/storefront/component/pagination.html.twig,重写总页数和统计信息的计算逻辑:
{% sw_extends '@Storefront/storefront/component/pagination.html.twig' %} {% block component_pagination_nav %} {% set totalPages = (total is defined ? total : entities.total) / criteria.limit %} {% set totalPages = totalPages|round(0, 'ceil') %} {% if totalPages > 1 %} {{ parent() }} {% endif %} {% endblock %} {% block component_pagination_info %} {% set totalItems = total is defined ? total : entities.total %} {{ parent() }} {% endblock %}
该方案保留了核心分页组件的通用性,同时针对评论场景传入正确的总条数。
方案2:通过装饰器重构ReviewLoaderResult实例
利用Shopware的DTO构造函数,在装饰器中用正确的总评论数创建新的ReviewLoaderResult实例,无需反射:
<?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)); $originalResult = $this->decorated->load($request, $context); // 用总评论数替换原total值,创建新的结果实例 return new ReviewLoaderResult( $originalResult->getReviews(), $originalResult->getTotalReviews(), $originalResult->getAverageRating(), $originalResult->getTotalReviews() ); } }
此方案完全通过Shopware官方API实现修改,符合合规开发要求,分页组件将自动使用正确的总条数计算页数。
内容的提问来源于stack exchange,提问作者O'Niel
相关产品推荐
相关产品推荐

