概要
EC-CUBE4の新規ページを作成する方法を紹介いたします。新規ページを追加するプラグインのサンプルコードを書いていきますので、プラグインの制作に興味がある方もぜひ参考にしていただければと思います。
今回実装したサンプルページプラグインはこちらのリポジトリでも配布しております。
https://github.com/seiyaan/eccube4-plugin-SamplePage
実装
1. コンソールからプラグインの雛形を作成
MacのターミナルなどからEC-CUBE4のルートディレクトリでbin/console eccube:plugin:generate
を実行してください。プラグインの雛形が作成されます。どんなプラグインにするか聞かれますので以下のように入力してください。
$ bin/console eccube:plugin:generate
EC-CUBE Plugin Generator Interactive Wizard
===========================================
name [EC-CUBE Sample Plugin]:
> サンプルページプラグイン
code [Sample]:
> SamplePage
ver [1.0.0]:
> 1.0.0
[OK] Plugin was successfully created: サンプルページプラグイン SamplePage 1.0.0
2. 新しいルーティングの追加とテンプレートファイルの準備
プラグインのディレクトリ(今回の場合はapp/Plugin/SamplePage/)に新規ページのコントローラーを設置します。@Route
でルーティングの設定、@Template
で使用するテンプレートを指定します。
ファイル app/Plugin/SamplePage/Controller/SampleController.php
<?php
namespace Plugin\SamplePage\Controller;
use Eccube\Controller\AbstractController;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Component\Routing\Annotation\Route;
class SampleController extends AbstractController
{
/**
* @Route("sample", name="sample")
* @Template("@SamplePage/default/index.twig")
*/
public function index()
{
return [];
}
}
使用するテンプレートも設置します。{% block main %}{% endblock %}
内に表示させたい内容を実装してください。
ファイル app/Plugin/SamplePage/Resource/template/default/index.twig
{% extends 'default_frame.twig' %}
{% block main %}
<p>サンプルページです</p>
{% endblock %}
表示させてみる
まだ完成ではないです。が、今どんな状態なのかを確認しましょう。
以下のコマンドで、プラグインのインストールと有効化を行ってください。
$ bin/console eccube:plugin:install --code=SamplePage
$ bin/console eccube:plugin:enable --code=SamplePage
http://127.0.0.1:8000/sample にアクセスして表示を確認します。
EC-CUBE4のヘッダーとフッターが表示されておらず、準備したテンプレートファイルの内容しか表示されておりません。これでは、寂しい…まだ実装が続きます。
3. プラグイン有効化時に、新規ページに関する情報をDBテーブルdtb_page
とdtb_page_layout
にINSERTする
dtb_page
にページ自体の情報、dtb_page_layout
にページで使用するレイアウトの情報をINSERTする必要があります。
新規会員登録、商品詳細、カートなどのページもヘッダー・フッターが表示されているのは、それらのテーブルに情報が入っているからなんですね。
では、プラグイン有効化時に情報をINSERTする処理を実装しましょう。そして、無効化時にはDELETEする処理も実装します(※プラグインが不要になったときにテーブルにゴミデータを残さないようにするため)
プラグインの有効化時/無効化時の処理はPluginManager.php
で実装をしていきます。
ファイル app/Plugin/SamplePage/PluginManager.php
<?php
namespace Plugin\SamplePage;
use Eccube\Entity\PageLayout;
use Eccube\Plugin\AbstractPluginManager;
use Eccube\Repository\LayoutRepository;
use Eccube\Repository\PageLayoutRepository;
use Eccube\Repository\PageRepository;
use Symfony\Component\DependencyInjection\ContainerInterface;
class PluginManager extends AbstractPluginManager
{
// 1: トップページ用レイアウト, 2:下層ページ用レイアウト
const ADD_PAGE_LAYOUT_ID = 2;
// ページ設定
const ADD_PAGE_NAME = "サンプルページ";
const ADD_PAGE_URL = "sample";
const ADD_PAGE_FILE_NAME = "SamplePage/Resource/template/default/index";
const ADD_PAGE_META_ROBOTS = "noindex"; // or null
// 0: Controller不要, 2: Controller必要
const ADD_PAGE_EDIT_TYPE = 2;
/**
* プラグイン有効化時に走る
* @param array $meta
* @param ContainerInterface $container
*/
public function enable(array $meta, ContainerInterface $container) {
$this->createPage($container);
}
/**
* プラグイン無効化時・アンインストール時に走る
* @param array $meta
* @param ContainerInterface $container
*/
public function disable(array $meta, ContainerInterface $container) {
$this->deletePage($container);
}
/**
* ページ情報を挿入する dtb_page, dtb_page_layout
* @param ContainerInterface $container
*/
private function createPage(ContainerInterface $container) {
// dtb_page に存在しないことを確認する
$pageRepository = $container->get(PageRepository::class);
$pageFindResult = $pageRepository->findOneBy(["url" => $this::ADD_PAGE_URL]);
if (is_null($pageFindResult) == false) return;
// dtb_layout から下層ページ用レイアウトを取得する
$layoutRepository = $container->get(LayoutRepository::class);
$underLayout = $layoutRepository->findOneBy(["id" => $this::ADD_PAGE_LAYOUT_ID]);
// dtb_page_layout の次のSortNoを取得する
$pageLayoutRepository = $container->get(PageLayoutRepository::class);
$LastPageLayout = $pageLayoutRepository->findOneBy([], ['sort_no' => 'DESC']);
$nextSortNo = $LastPageLayout->getSortNo() + 1;
// EntityManager準備
$em = $container->get('doctrine.orm.entity_manager');
$em->beginTransaction();
// INSERT INTO dtb_page
$page = $pageRepository->newPage();
$page->setName($this::ADD_PAGE_NAME)
->setUrl($this::ADD_PAGE_URL)
->setFileName($this::ADD_PAGE_FILE_NAME)
->setEditType($this::ADD_PAGE_EDIT_TYPE)
->setMetaRobots($this::ADD_PAGE_META_ROBOTS);
$em->persist($page);
$em->flush($page);
// INSERT INTO dtb_page_layout
$pageLayout = new PageLayout();
$pageLayout->setLayout($underLayout)
->setLayoutId($underLayout->getId())
->setPageId($page->getId())
->setSortNo($nextSortNo)
->setPage($page);
$em->persist($pageLayout);
$em->flush($pageLayout);
$em->commit();
}
/**
* ページ情報を削除 dtb_page, dtb_page_layout
* @param ContainerInterface $container
*/
private function deletePage(ContainerInterface $container) {
// dtb_page に存在することを確認する
$pageRepository = $container->get(PageRepository::class);
$page = $pageRepository->findOneBy(["url" => $this::ADD_PAGE_URL]);
if (is_null($page)) return;
// EntityManager準備
$em = $container->get('doctrine.orm.entity_manager');
$em->beginTransaction();
// DELETE FROM dtb_page WHERE インストール時にINSERTしたページ
$em->remove($page);
$em->flush($page);
// DELETE FROM dtb_page_layout WHERE インストール時にINSERTしたページレイアウト
$pageLayoutRepository = $container->get(PageLayoutRepository::class);
$pageLayout = $pageLayoutRepository->findOneBy(["page_id" => $page->getId()]);
if(is_null($pageLayout) === false){
$em->remove($pageLayout);
$em->flush($pageLayout);
}
$em->commit();
}
}
PluginManagerクラスの始めの方に定数を準備しております。定数の内容を変えるだけで追加したいページの情報を変更できるようにしております。活用してどうぞ。
あとは、一度無効化にして、再度有効化してあげましょう。
$ bin/console eccube:plugin:disable --code=SamplePage
$ bin/console eccube:plugin:enable --code=SamplePage
表示させてみる
実家のような安心感…! ヘッダー・フッター付きのページが現れました!
以上です。