一から新しい人気商品機能ファイルを作るのは難しいですね。

デフォルトの新着商品と同じ機能を持った人気商品機能を作るようにします。

デフォルトの新着商品機能をベースに、機能を読み込んで、人気商品でカート機能やUIに再利用します。

まず、srcで新着商品に関するnew_item.twig、product/list.twig、ProductController.php、

管理システムのブロック管理でpopular_item.twigを作成

includeでファイルを読み込む。

{% include 'new_item.twig' with { 'title': '人気商品', 'products': PopularProducts } %}

また、ファイル管理で商品一覧画面popular_list.twigを作成

{% extends 'default_frame.twig' %}

{% set body_class = 'popular_product_page' %}

{% block main %}
    <div class="ec-productListRole">
        <h1 class="ec-headingTitle">{{ '人気商品一覧'|trans }}</h1>

        {% if PopularProducts is defined and PopularProducts is not empty %}
        {% include 'Product/list.twig' with { 'pagination': PopularProducts, 'subtitle': '人気商品' } %}
        {% else %}
        <p class="text-center">{{ '現在、人気商品はありません。'|trans }}</p>
        {% endif %}


    </div>
{% endblock %}

appのCusutomizeフォルダにControllerフォルダにPopularProductController.phpを作成する

<?php 
namespace Customize\Controller;

use Customize\Repository\CustomProductRepository;
use Eccube\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\Request;
use Knp\Component\Pager\PaginatorInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;

class PopularProductController extends AbstractController
{
    /**
     * @var CustomProductRepository
     */
    protected $productRepository;

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

    /**
     * 人気商品一覧画面.
     *
     * @Route("/popular", name="popular_list", methods={"GET"})
     */
    public function index(Request $request, PaginatorInterface $paginator)
    {
        // 人気商品のデータ取得
        $PopularProducts = $this->productRepository->findPopularProducts(20);

        // ページネーション
        $pagination = $paginator->paginate(
            $PopularProducts,  // クエリ結果
            $request->query->getInt('page', 1), // 現在のページ番号(デフォルト1)
            10 // 1ページあたりの件数
        );

        return $this->render('@user_data/popular_list.twig', [
            'PopularProducts' => $PopularProducts, 
            'pagination' => $pagination ?? [],
            'subtitle' => '人気商品一覧',
        ]);
        
        
    }
}

app/Customizeフォルダ下にRepositoryフォルダを作成し、CustomProductRepository.phpを作成する

<?php
namespace Customize\Repository;

use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
use Eccube\Entity\Product;

class CustomProductRepository extends ServiceEntityRepository
{
    public function __construct(ManagerRegistry $registry)
    {
        parent::__construct($registry, Product::class);
    }

    public function findPopularProducts($limit = 20)
    {
        return $this->getEntityManager()
        ->createQuery(
            'SELECT p, COUNT(oi.id) AS HIDDEN order_count
            FROM Eccube\Entity\Product p
            JOIN Eccube\Entity\OrderItem oi WITH oi.Product = p
            GROUP BY p.id
            ORDER BY order_count DESC'
        )
        ->setMaxResults($limit)
        ->getResult();
    }
}

Repositoryファイルを作ったら、services.yamlにファイルの登録作業をする

services:
#人気商品リポジトリ登録
    Customize\Repository\CustomProductRepository:
        arguments:
            $registry: '@doctrine'

app/config/eccube/にある、routes.yamlにpopular_listのルーティングを登録する

#人気商品
popular_list:
    path: /popular
    controller: Customize\Controller\PopularProductController::index
    methods: [GET]

全てのファイルを作成した後、キャッシュをクリアすると完成です。