プラグイン開発しているとほぼやることになるページ追加の手順メモ。
大まかな手順は
- PluginManger
- 有効化にした際にページを追加
- 無効化にした際にページを削除
- テンプレートファイルの追加
- コントローラー追加
今回はメーカー一覧ページを追加する流れを書く。
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