Help us understand the problem. What is going on with this article?

ec-cube4でプラグイン開発を始める|ページ追加

プラグイン開発しているとほぼやることになるページ追加の手順メモ。

大まかな手順は

  1. PluginManger
    1. 有効化にした際にページを追加
    2. 無効化にした際にページを削除
  2. テンプレートファイルの追加
  3. コントローラー追加

今回はメーカー一覧ページを追加する流れを書く。

PluginMangerに処理を書く

まず最初にページ挿入の関数を作成

/**
     * ページ情報を挿入する dtb_page, dtb_page_layout
     *
     * @param  ContainerInterface  $container
     * @param $page
     *
     * @throws ORMException
     * @throws OptimisticLockException
     */
    private function createPage(
        ContainerInterface $container,
        $addPage
    ): void {
        $pageRepository = $container->get(PageRepository::class);
        $pageFindResult = $pageRepository->findOneBy(['url' => $addPage['url']]);

        // dtb_page に存在しないことを確認する
        if ($pageFindResult !== null) {
            return;
        }

        // dtb_layout から下層ページ用レイアウトを取得する
        $layoutRepository = $container->get(LayoutRepository::class);
        $underLayout      = $layoutRepository->findOneBy(['id' => $addPage['edit_type']]);

        // 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($addPage['name'])
            ->setUrl($addPage['url'])
            ->setFileName($addPage['file_name'])
            ->setEditType($addPage['edit_type'])
            ->setMetaRobots($addPage['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();
    }

pages変数に追加したページの情報を記述。
ここで設定するurlは後ほど作成するControllerと合わせる必要があるので間違えないように注意。

private $pages = [
        [
            'name'        => 'メーカー一覧',
            'url'         => 'maker_index',
            'file_name'   => '@Maker4/default/list',
            'meta_robots' => null,
            'edit_type'   => 2,
        ],
    ];

次にプラグインを有効化した際にページ追加の関数を呼び出す。
同じページが

/**
     * プラグイン有効化時に走る
     *
     * @param  array  $meta
     * @param  ContainerInterface  $container
     *
     * @throws \Exception
     */
    public function enable(array $meta, ContainerInterface $container)
    {
        foreach ($this->pages as $addPage) {
            //既存ページがないかを確認
            $isPage = $container->get(PageRepository::class)->findOneBy(['url' => $addPage['url']]);
            if (null === $isPage) {
                $this->createPage($container, $addPage);
            }
        }
    }

最後に削除する関数を追加して準備おk。

/**
     * ページ情報を削除 dtb_page, dtb_page_layout
     *
     * @param  ContainerInterface  $container
     *
     * @throws ORMException
     * @throws OptimisticLockException
     */
    private function deletePage(ContainerInterface $container, $addPage): void
    {
        // dtb_page に存在することを確認する
        $pageRepository = $container->get(PageRepository::class);
        $page           = $pageRepository->findOneBy(['url' => $addPage['url']]);
        if ($page === null) {
            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 ($pageLayout !== null) {
            $em->remove($pageLayout);
            $em->flush($pageLayout);
        }
        $em->commit();
    }

全体はこんな感じ。

PluginManger.php
<?php

declare(strict_types=1);
namespace Plugin\Maker4;

use Doctrine\ORM\OptimisticLockException;
use Doctrine\ORM\ORMException;
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.
 */
class PluginManager extends AbstractPluginManager
{
    private $pages = [
        [
            'name'        => 'メーカー一覧',
            'url'         => 'maker_index',
            'file_name'   => '@Maker4/default/list',
            'meta_robots' => null,
            'edit_type'   => 2,
        ],
    ];

    /**
     * プラグイン有効化時に走る
     *
     * @param  array  $meta
     * @param  ContainerInterface  $container
     *
     * @throws \Exception
     */
    public function enable(array $meta, ContainerInterface $container)
    {
        foreach ($this->pages as $addPage) {
            //既存ページがないかを確認
            $isPage = $container->get(PageRepository::class)->findOneBy(['url' => $addPage['url']]);
            if (null === $isPage) {
                $this->createPage($container, $addPage);
            }
        }
    }


    /**
     * プラグイン無効化時・アンインストール時に走る
     *
     * @param  array  $meta
     * @param  ContainerInterface  $container
     *
     * @throws ORMException
     * @throws OptimisticLockException
     * @throws \Exception
     */
    public function disable(
        array $meta,
        ContainerInterface $container
    ) {
        foreach ($this->pages as $addPage) {
            $this->deletePage($container, $addPage);
        }
    }

    /**
     * ページ情報を挿入する dtb_page, dtb_page_layout
     *
     * @param  ContainerInterface  $container
     * @param $page
     *
     * @throws ORMException
     * @throws OptimisticLockException
     */
    private function createPage(
        ContainerInterface $container,
        $addPage
    ): void {
        $pageRepository = $container->get(PageRepository::class);
        $pageFindResult = $pageRepository->findOneBy(['url' => $addPage['url']]);

        // dtb_page に存在しないことを確認する
        if ($pageFindResult !== null) {
            return;
        }

        // dtb_layout から下層ページ用レイアウトを取得する
        $layoutRepository = $container->get(LayoutRepository::class);
        $underLayout      = $layoutRepository->findOneBy(['id' => $addPage['edit_type']]);

        // 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($addPage['name'])
            ->setUrl($addPage['url'])
            ->setFileName($addPage['file_name'])
            ->setEditType($addPage['edit_type'])
            ->setMetaRobots($addPage['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
     *
     * @throws ORMException
     * @throws OptimisticLockException
     */
    private function deletePage(ContainerInterface $container, $addPage): void
    {
        // dtb_page に存在することを確認する
        $pageRepository = $container->get(PageRepository::class);
        $page           = $pageRepository->findOneBy(['url' => $addPage['url']]);
        if ($page === null) {
            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 ($pageLayout !== null) {
            $em->remove($pageLayout);
            $em->flush($pageLayout);
        }
        $em->commit();
    }
}

テンプレートファイルの追加

Plugin名/Resource/template/default/list.twigを追加。

Controller

Plugin名/Controller/MakerController.phpに以下ファイルを作成

makerContrller.php
declare(strict_types=1);
namespace Plugin\Maker4\Controller;

use Eccube\Controller\AbstractController;
use Plugin\Maker4\Repository\MakerRepository;
use Symfony\Component\Routing\Annotation\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;

/**
 * Class MakerController.
 */
class MakerController extends AbstractController
{
    /**
     * @var MakerRepository
     */
    protected $makerRepository;

    /**
     * MakerController constructor.
     *
     * @param  MakerRepository  $makerRepository
     */
    public function __construct(MakerRepository $makerRepository)
    {
        $this->makerRepository = $makerRepository;
    }

    /**
     * メーカー一覧
     * @Route("/maker", name="maker_index")
     * @Template("@Maker4/default/list.twig")
     */
    public function list(): array
    {
        $makers = $this->makerRepository->findAll();

        return ['makers'=> $makers];
    }
}

管理画面のページ管理に作成したページにアクセス出来れば終わり!!

Call to a member function getPath() on nullって怒られる場合は、ControllerのNameとPluginMangerで設定したURLで差異がある可能性が高い。

自分がそうだったんでw

yyphp
PHPerが毎週集まり、ざっくばらんに情報交換する雑談コミュニティ
https://yyphp.connpass.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away