新しいページを追加するには
新しいページを追加するには Controllerのカスタマイズ > 新しいルーティングの追加 で簡単にできます。
ただし、この状態のままでは共通フッター・ヘッダーが付きません。
共通フッター ・ヘッダーを付けるには、ページの管理にデータを追加する必要があるようです。
アノテーションを利用してページ管理のレコードを自動生成するコマンド
@Template
と @Route
アノテーションを目印にしてデータを取得。
そのデータをページ管理にインサートします。
すでに同じデータがある場合はスキップするので、何度実行しても問題ありません。
<?php
declare(strict_types=1);
namespace Customize\Command;
use Doctrine\Common\Annotations\AnnotationReader;
use Doctrine\ORM\EntityManagerInterface;
use Eccube\Entity\Layout;
use Eccube\Entity\Page;
use Eccube\Entity\PageLayout;
use Eccube\Repository\LayoutRepository;
use Eccube\Repository\PageLayoutRepository;
use Eccube\Repository\PageRepository;
use PhpParser\Node\Stmt\Namespace_;
use PhpParser\ParserFactory;
use ReflectionClass;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\Finder\Finder;
use Symfony\Component\Routing\Annotation\Route;
use function assert;
use function dirname;
use function pathinfo;
use function sprintf;
class CreatePageCommand extends Command
{
protected static $defaultName = 'customize:create-page';
/** @var PageRepository */
private $pageRepository;
/** @var PageLayoutRepository */
private $pageLayoutRepository;
/** @var LayoutRepository */
private $layoutRepository;
/** @var EntityManagerInterface */
private $entityManager;
public function __construct(
PageRepository $pageRepository,
PageLayoutRepository $pageLayoutRepository,
LayoutRepository $layoutRepository,
EntityManagerInterface $entityManager
) {
parent::__construct();
$this->pageRepository = $pageRepository;
$this->pageLayoutRepository = $pageLayoutRepository;
$this->layoutRepository = $layoutRepository;
$this->entityManager = $entityManager;
}
protected function configure(): void
{
$this->setDescription('Create page record into database.');
}
protected function execute(InputInterface $input, OutputInterface $output): ?int
{
$io = new SymfonyStyle($input, $output);
$this->entityManager->beginTransaction();
$connection = $this->entityManager->getConnection();
$sortNo = $connection->fetchColumn('SELECT MAX(sort_no) FROM dtb_page_layout');
$layout = $this->layoutRepository->get(Layout::DEFAULT_LAYOUT_UNDERLAYER_PAGE);
$reader = new AnnotationReader();
$controllerDir = dirname(__DIR__) . '/Controller';
$finder = Finder::create()->in($controllerDir)->name('*.php');
foreach ($finder->getIterator() as $fileInfo) {
$code = file_get_contents($fileInfo->getPathname());
$parser = (new ParserFactory())->create(ParserFactory::PREFER_PHP7);
$stmts = $parser->parse($code);
if ($stmts === null) {
continue;
}
$namespace = null;
foreach ($stmts as $stmt) {
if (! $stmt instanceof Namespace_) {
continue;
}
$namespace = $stmt->name->toString();
break;
}
if ($namespace === null) {
break;
}
$className = $namespace . '\\' . pathinfo($fileInfo->getPathname(), PATHINFO_FILENAME);
$reflectionClass = new ReflectionClass($className);
$reflectionMethods = $reflectionClass->getMethods();
foreach ($reflectionMethods as $reflectionMethod) {
$route = $reader->getMethodAnnotation($reflectionMethod, Route::class);
$template = $reader->getMethodAnnotation($reflectionMethod, Template::class);
if ($route === null || $template === null || strpos($route->getPath(), '%eccube_admin_route%') !== false) {
continue;
}
assert($route instanceof Route);
assert($template instanceof Template);
if ($route->getName() === null) {
continue;
}
$page = $this->pageRepository->findOneBy([
'url' => $route->getName()
]);
if ($page !== null) {
continue;
}
$pathInfo = pathinfo($template->getTemplate());
$page = (new Page())->setUrl($route->getName())
->setFileName(sprintf('%s/%s', $pathInfo['dirname'], $pathInfo['filename']))
->setEditType(Page::EDIT_TYPE_DEFAULT);
$this->entityManager->persist($page);
$this->entityManager->flush();
$pageLayout = (new PageLayout())->setLayoutId(Layout::DEFAULT_LAYOUT_UNDERLAYER_PAGE)
->setLayout($layout)
->setPageId($page->getId())
->setPage($page)
->setSortNo(++$sortNo);
$this->entityManager->persist($pageLayout);
$this->entityManager->flush();
$io->text(
sprintf('id: %d, class: %s, url: %s, file_name: %s', $page->getId(), $className, $route->getName(), $template->getTemplate())
);
}
}
$this->entityManager->commit();
$io->success('success.');
return 0;
}
}
実行
./bin/console customize:create-page
Docker Compose で起動している人であれあば、以下でもOK
docker-compose exec --user apache web ./bin/console customize:create-page