1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

EC-CUBE4 ページ管理のデータを自動追加

Last updated at Posted at 2021-01-22

新しいページを追加するには

新しいページを追加するには 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;
    }
}

実行 :rocket:

./bin/console customize:create-page

Docker Compose で起動している人であれあば、以下でもOK

docker-compose exec --user apache web ./bin/console customize:create-page
1
1
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
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?