Controllerのカスタマイズ
新しいルーティングの追加
#[Route] 属性(Attribute)を付与したコントローラクラスを./app/Customize/Controller/ 以下に配置することで、サイトに新しいルーティングを追加することが可能です。
以下は最もシンプルなルーティング追加の例です。
http://サイトURL/sample にアクセスすると”Hello sample page !”と表示するルーティングを追加しています。
Controllerファイル
./app/Customize/Controller/SamplePageController.php
<?php
namespace Customize\Controller;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class SamplePageController
{
#[Route('/sample', methods: ['GET'])]
public function testMethod(): Response
{
return new Response('Hello sample page !');
}
}
テンプレートファイルの利用
#[Template] 属性(Attribute)を利用することで、Twigのテンプレートファイルを利用することができます。
以下のサンプルは、http://サイトURL/sample にアクセスすると”Hello EC-CUBE !”と表示します。
Controllerファイル
<?php
namespace Customize\Controller;
use Symfony\Bridge\Twig\Attribute\Template;
use Symfony\Component\Routing\Attribute\Route;
class SamplePageController
{
#[Route(path: '/sample', methods: ['GET'])]
#[Template('Sample/index.twig')]
public function testMethod(): array
{
return [
'message' => 'Hello EC-CUBE !',
];
}
}
Twigファイル
./app/template/default/Sample/index.twig
<h3>{{ message }}</h3>
カスタマイズのヒント
URLからパラメータを受け取る
http://サイトURL/sample/1 のようにURLに含まれるパラメータを変数の値として受け取ることができます。
#[Route] 属性(Attribute)で定義したパスの {id} の部分は、コントローラーメソッドの引数に同名の変数 $id を定義することで、自動的に受け取れます。
#[Route('/sample/{id}', methods: ['GET'])]
public function testMethod($id): Response
{
return new Response('Parameter is '.$id);
}
追加したルーティングへのリンクをする
他のページのテンプレートファイルから、追加したルーティングにリンクをするには、ルーティングに名前をつける必要があります。
#[Route] 属性(Attribute)の name パラメータを指定することで、ルーティング名を設定できます。
#[Route('/sample/{id}', name: 'sample_page', methods: ['GET'])]
public function testMethod($id): Response
{
return new Response('Parameter is '.$id);
}
他のページのテンプレートファイルからリンクをする場合には、以下のように記述します。
パラメータを渡すことも出来ます。
<a href="{{ path('sample_page', { id: 1 }) }}">サンプルページへ</a>
EC-CUBE既存のルーティングを上書きする
EC-CUBE既存のルーティングを上書きするには、同じパスと名前でルーティングを定義します。
下記のサンプルでは、「当サイトについて」のページを上書きしています。
#[Route('/help/about', name: 'help_about', methods: ['GET'])]
public function testMethod(): Response
{
return new Response('Overwrite /help/about page');
}
管理画面のルーティングを追加する
管理画面にログインしているユーザーのみがアクセスできるルーティングを追加する場合には、パスに /%eccube_admin_route% を利用します。
#[Route('/%eccube_admin_route%/sample', methods: ['GET'])]
public function testMethod(): Response
{
return new Response('admin page');
}
同様にUserDataへのルーティングは /%eccube_user_data_route% を指定します。
リダイレクトを行う
AbstractControllerを継承して redirectToRoute 関数を利用することでリダイレクトが可能です。
下記のサンプルでは、アクセスがあると「当サイトについて」のページへリダイレクトしています。
#[Route('/sample', methods: ['GET'])]
public function testMethod(): RedirectResponse
{
return $this->redirectToRoute('help_about');
}
また forward() メソッドを利用することで、リダイレクトではなく内部的に他のコントローラーへ処理を渡すことができます。
Controller内でサービスを利用する
AbstractController あらかじめコントローラに注入されているサービスをプロパティとして利用できます。
以下のサンプルでは、EntityManagerを利用して商品のEntityを取得しています。
<?php
namespace Customize\Controller;
use Eccube\Controller\AbstractController;
use Eccube\Entity\Product;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class SamplePageController extends AbstractController
{
#[Route('/sample', methods: ['GET'])]
public function testMethod(): Response
{
/** @var Product $product */
$product = $this->entityManager->getRepository(Product::class)->find(1);
return new Response('Product is '.$product->getName());
}
}
EntityManger以外に、AbstractControllerを継承することで利用できるサービスは ./src/Eccube/Controller/AbstractController.php を確認してください。
AbstractControllerに無いサービスを利用する
インジェクションを利用することで、AbstractController であらかじめ用意されていないサービスのインスタンスも自由に利用できます。 以下のサンプルでは、BaseInfoからショップ名を取得しています。
<?php
namespace Customize\Controller;
use Eccube\Repository\BaseInfoRepository;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
class SamplePageController
{
/** @var \Eccube\Entity\BaseInfo */
protected $BaseInfo;
public function __construct(BaseInfoRepository $baseInfoRepository)
{
$this->BaseInfo = $baseInfoRepository->get();
}
#[Route('/sample', methods: ['GET'])]
public function testMethod(): Response
{
return new Response('Shop name is '.$this->BaseInfo->getShopName());
}
}
画面を表示する必要がないコントローラーを作成する
画面を表示する必要のないコントローラの場合も必ずResponseオブジェクトを返してください。
(exit() で処理を終了するとEC-CUBEが正常な動作を行えなくなります)
Responseのレスポンスコードやヘッダーを指定することも可能です。
#[Route('/sample', methods: ['GET'])]
public function testMethod(): Response
{
return new Response(
'',
Response::HTTP_OK,
['Content-Type' => 'text/plain; charset=utf-8']
);
}
$ curl -D - http://サイトURL/sample
HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
参考情報
EC-CUBE 4 ではSymfonyのController機構を利用しています。
その他のカスタマイズ方法についてはSymfonyのドキュメントを参照してください。