[EC-Cube 4.2] [Symfony] 変更に伴う修正必要?


EC-Cube 4.2になって、フレームワークがSymfony5.4 / PHP8に変わりました。
それに伴って、いろいろ参考にさせて頂いているホームページのコードではそのまま動作しないことがあります。
変更点については、以下のEC-cubeのページを最初に読むと良いと思います。

例えば、EC-CubeのRepositoryって何だろう?とかを知るためにググりながら、参考になるページを見つけて、コードを参考にしてテストをします。
ところが、Symfony 4.4から5.4に変わったことで動かないことがあります。
例1 全商品名を表示する

このコードを参考にさせて頂いて動かすと
Cannot autowire service "Customize\Repository\xxxx": argument "$registry" of method "construct()" has type "Symfony\Bridge\Doctrine\RegistryInterface" but this class was not found.
というエラーが表示されて、動きません。
理由は、この通り ”Symfony\Bridge\Doctrine\RegistryInterface"の__construct() に$registryが無いからです。
Symfony 4.4 -> 5.2への移行の際にこのmethodが無くなったようです。
このエラーでググると

https://stackoverflow.com/questions/59289824/cannot-load-the-symfony-bridge-doctrine-registryinterface

StackOverflow

が出てきます。
上記のStackOverflowの回答では、
use Doctrine\Common\Persistence\ManagerRegistry;
となっていますが、さらに修正が必要です。
まず、参考にしたホームページに従って、app/Customize/Repository/CustomizeProductRepository.php 
を作成し、以下の変更を行います。
use Symfony\Bridge\Doctrine\RegistryInterface; を最終的に
use Doctrine\Persistence\ManagerRegistry; に書き換えることと関係する行を変更することで表示されるようになります。

Repository 作成
参考 app/Customize/Repository/CustomizeProductRepository.phpの変更 

<?php
namespace Customize\Repository;
use Eccube\Entity\Product; #ProductのDBから取得する為
# use Symfony\Bridge\Doctrine\RegistryInterface; この行削除
use Doctrine\Persistence\ManagerRegistry; #この行を追加 Entityと連携するため
use Eccube\Repository\AbstractRepository; #Repositoryを拡張する為

/**
 * CustomizeProductRepository
 *
 * This class was generated by the Doctrine ORM. Add your own custom
 * repository methods below.
 */
class CustomizeProductRepository extends AbstractRepository
{
    /**
     * CustomizeProductRepository constructor.
     *
#     * @param RegistryInterface $registry <- この行削除
     * @param ManagerRegistry $registry # <-この行へ変更
     */
#   public function __construct(RegistryInterface $registry) <-この行削除
    public function __construct(ManagerRegistry $registry) # <- この行へ変更
    {
        parent::__construct($registry, Product::class); #EntityのProductを呼び出している
    }
    /**
     * 全検索
     *
     * @return Products|array
     */
    public function customFindAll() #関数名(何でも良い)
    {
        $qb = $this->createQueryBuilder('p'); #何でも良いがproductの頭文字を取ってます。
        $products = $qb
            ->getQuery() #作成したクエリを取得
            ->getResult(); #実行
        return $products;
    }
}

controller作成

app/Customize/TestController.php を作成

<?php
namespace Customize\Controller;
use Eccube\Controller\AbstractController;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Component\Routing\Annotation\Route;
use Customize\Repository\CustomizeProductRepository; #Repositoryを取得する為の宣言

class TestController extends AbstractController
{
    /**
     * @var ProductRepository
     */
    protected $customizeProductRepository;
    /**
     *
     *
     * TestController constructor.
     *
     *  @param CustomizeProductRepository $productRepository
     *
     */

    public function __construct(CustomizeProductRepository $customizeProductRepository)
    {
      $this->customizeProductRepository = $customizeProductRepository;
    }

    /**
     *
     * @Route("/test", name="test") #URLを指定
     * @Template("Product/test.twig") #ページ遷移先を指定
     * 
     */
    public function index()
    {
        $products = $this->customizeProductRepository->customFindAll();
        return ['products'=>$products];
    }
}

表示用Twigの作成

Controllerに合わせて、表示用Twigを
app/Customize/template/Product/test.twig を作成

{% for product in products %}
    <p>{{ product }}</p>
{% endfor %}

これで、実行するとDBに書かれたProduct名が表示されます。

参考になればと思います。

よろしければサポートをお願いします。 今後の活動の励みになります。