LoginSignup
13
20

More than 5 years have passed since last update.

[EC-CUBE4] ヘッダー・フッター付きの新規ページを作成する方法→プラグイン化

Last updated at Posted at 2019-02-10

概要

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

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

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 にアクセスして表示を確認します。

表示結果1.png

EC-CUBE4のヘッダーとフッターが表示されておらず、準備したテンプレートファイルの内容しか表示されておりません。これでは、寂しい…まだ実装が続きます。

3. プラグイン有効化時に、新規ページに関する情報をDBテーブルdtb_pagedtb_page_layoutにINSERTする

dtb_pageにページ自体の情報、dtb_page_layoutにページで使用するレイアウトの情報をINSERTする必要があります。

新規会員登録、商品詳細、カートなどのページもヘッダー・フッターが表示されているのは、それらのテーブルに情報が入っているからなんですね。

では、プラグイン有効化時に情報をINSERTする処理を実装しましょう。そして、無効化時にはDELETEする処理も実装します(※プラグインが不要になったときにテーブルにゴミデータを残さないようにするため)

プラグインの有効化時/無効化時の処理はPluginManager.phpで実装をしていきます。

ファイル app/Plugin/SamplePage/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

表示させてみる

表示結果2.png

実家のような安心感…! ヘッダー・フッター付きのページが現れました!
以上です。

13
20
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
20