はじめに
- やり方が分からなかったため、備忘録として。
- 公式の無料プラグインを参考にしました。
PluginManager.php について
- ここにインストール時、有効化時、アンインストール時、等の処理を記載する。
namespace Plugin\FaqManager;
use Doctrine\ORM\EntityManagerInterface;
use Eccube\Entity\Layout;
use Eccube\Entity\Page;
use Eccube\Entity\PageLayout;
use Eccube\Common\EccubeConfig;
use Eccube\Plugin\AbstractPluginManager;
use Psr\Container\ContainerInterface;
use Symfony\Component\Filesystem\Filesystem;
class PluginManager extends AbstractPluginManager
{
private array $pages = [
[
'name' => 'FAQ',
'url' => 'faq_manager_index',
'filename' => 'FaqManager/Resource/template/default/index',
],
];
// 有効化時
public function enable(array $meta, ContainerInterface $c)
{
$em = $c->get('doctrine')->getManager();
foreach ($this->pages as $p) {
$this->createPage($em, $p['name'], $p['url'], $p['filename']);
}
$this->copyTwigFiles($c);
}
// アンインストール時
public function uninstall(array $meta, ContainerInterface $c)
{
$em = $c->get('doctrine')->getManager();
foreach ($this->pages as $p) {
$this->removePage($em, $p['url']);
}
$this->removeTwigFiles($c);
}
/* ---------- 以下ヘルパ --------- */
private function createPage(EntityManagerInterface $em, string $name, string $url, string $filename): void
{
if ($em->getRepository(Page::class)->findOneBy(['url' => $url])) {
return; // 重複防止
}
$page = (new Page())
->setEditType(Page::EDIT_TYPE_DEFAULT)
->setName($name)
->setUrl($url)
->setFileName($filename);
$em->persist($page);
$em->flush();
$layout = $em->find(Layout::class, Layout::DEFAULT_LAYOUT_UNDERLAYER_PAGE);
$em->persist(
(new PageLayout())
->setPage($page)->setPageId($page->getId())
->setLayout($layout)->setLayoutId($layout->getId())
->setSortNo(0)
);
$em->flush();
}
private function removePage(EntityManagerInterface $em, string $url): void
{
$page = $em->getRepository(Page::class)->findOneBy(['url' => $url]);
if (!$page) {
return;
}
foreach ($page->getPageLayouts() as $pl) {
$em->remove($pl);
}
$em->flush();
$em->remove($page);
$em->flush();
}
private function copyTwigFiles(ContainerInterface $c): void
{
$themeDir = $c->get(EccubeConfig::class)->get('eccube_theme_front_dir');
$dst = $themeDir.'/FaqManager/Resource/template/default';
$fs = new Filesystem();
if (!$fs->exists($dst)) {
$fs->mkdir($dst);
$fs->mirror(__DIR__.'/Resource/template/default', $dst);
}
}
private function removeTwigFiles(ContainerInterface $c): void
{
$themeDir = $c->get(EccubeConfig::class)->get('eccube_theme_front_dir');
(new Filesystem())->remove($themeDir.'/FaqManager');
}
}
コントローラ、ルーティング等
namespace Plugin\FaqManager\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Attribute\Route;
class FaqController extends AbstractController
{
// @Route("/faq", name="faq_manager_index", methods={"GET", "POST"})
// @Template("FaqManager/Resource/template/default/faq/index.twig")
public function index()
{
return [];
}
}
テンプレートパスを @FaqManager/...
にしておくと、プラグイン内テンプレートを直接読める。
ただし管理画面で編集したい場合は、Page.file_name
のパスに合わせて テーマ側コピーを使う。
ハマったところ
// PluginManager.php
class PluginManager extends AbstractPluginManager
{
private array $pages = [
[
'name' => 'FAQ',
'url' => 'faq_manager_index', // ← ココ
'filename' => 'FaqManager/Resource/template/default/index',
],
];
// FaqController.php
class FaqController extends AbstractController
{
// ↓ ココ
// @Route("/faq", name="faq_manager_index", methods={"GET", "POST"})
// @Template("FaqManager/Resource/template/default/faq/index.twig")
- 画像の箇所を統一してなかったため、うまくルーティングの設定ができていなかった。
参考リンク