Как я могу добавить простую функциональность CMS в существующее приложение Symfony

У меня есть существующее веб-приложение для доступа к базе данных MySQL. Портирую это приложение на Symfony. Новое приложение должно использовать старую базу данных, поскольку мы не можем перенести все приложение сразу, т.е. старое и новое приложение обращаются к одной и той же базе данных, и приложения работают одновременно.

Старое приложение имело простую функциональность CMS, которую нужно было перенести:

Есть таблица page, которая представляет дерево страниц. На каждой странице есть поле slug. Путь URL-адреса состоит из этих ярлыков, представляющих путь, идентифицирующий узел страницы, например "/[parent-slug]/[child-slug]".

Таблица страниц также содержит поле content. Как я уже упоминал, функциональность CMS очень проста, поэтому контент просто отображается как контент страницы внутри макета страницы. Запись страницы также определяет макет / шаблон страницы.

Моя проблема в том, что я не знаю, как настроить маршрутизацию. В обычном приложении Symfony я бы знал шаблоны URL и раньше, но в данном случае они динамические. Также маршруты не могут быть кэшированы, потому что они могут быть изменены пользователем в любой момент. Интересно, придется ли мне полностью отказаться от маршрутизации Symfony и реализовать что-то самостоятельно. Но как?

Теперь я нашел Symfony CMF, который много говорит о конфликте маршрутизации фреймворка VS CMS. Итак, сначала я подумал, что это будет правильный путь. Однако учебные пособия нацелены на создание совершенно нового приложения на основе PHPRC. Мне не удалось перенести концепции учебника на свой вариант использования.


person fishbone    schedule 02.12.2016    source источник
comment
Отредактировал и уточнил вопрос. Надеюсь, что либо отрицательный голос будет удален, либо проголосовавший против объяснит, в чем проблема   -  person fishbone    schedule 02.12.2016


Ответы (2)


поскольку вы запускаете несколько правил URL-адресов в одном приложении Symfony, вам нужно будет работать с префиксами URL-адресов. Либо ваша cms должна работать с префиксом / cms / parent-slug / child-slug, либо со всеми другими контроллерами. В противном случае вы не сможете отличить, какой контроллер имеется в виду при поступлении динамического запроса.

Вы можете попробовать обходной путь с помощью KernelControllerListener. Он обработает каждый запрос, а затем проверит, запрашивается ли страница cms. На основании запроса вы можете самостоятельно настроить контроллер и действие. Концепция:

Создайте только один маршрут с "/". Откажитесь от других правил. Затем создайте слушателя следующим образом:

<?php

namespace AppBundle\Listener;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;

/**
 * Class KernelControllerListener
 * @package ApiBundle\Listener
 */
class KernelControllerListener
{
    /**
     * @var CmsRepository
     */
    private $requestParser;

    /**
     * KernelControllerListener constructor.
     * @param CmsRepository $CmsRepository
     */
    public function __construct(CmsRepository $CmsRepository)
    {
        $this->CmsRepository = $CmsRepository;
    }

    /**
     * @param FilterControllerEvent $event
     */
    public function onKernelController(FilterControllerEvent $event){
        $request = $event->getRequest();
        //should be /parent-slug/children/slug or any other path
        $path = $request->getPathInfo();

        if($this->CmsRepository->getCmsControllerIfMatch($path)){
            //cms repository search in db for page with this path, otherwise return false
            $event->setController([AppBundle\CmsController::class, 'cmsAction']);
            return;
        }

        //repeat if clause for any other application part
    }
}

в services.yml:

app.controller_listener:
  class: AppBundle\Listener\KernelControllerListener
  arguments:
    - "@app.cms_repository"
  tags:
    - { name: kernel.event_listener, event: kernel.controller, method: onKernelController }

Изменить: поймать все маршруты, см. https://www.jverdeyen.be/symfony2/symfony-catch-all-route/

person Rawburner    schedule 02.12.2016

Вопрос в том, хотите ли вы перенести данные или нет. На оба вопроса ответом может быть CMF. Если вам нужен простой динамический маршрутизатор, вам следует взглянуть на ChainRouter с настраиваемым определением маршрутизатора: https://symfony.com/doc/current/cmf/bundles/routing/dynamic.html и https://symfony.com/doc/current/cmf/components/routing/chain.html Если вы хотите перенести данные, вы можете используйте загрузчики приспособлений, которые мы используем почти во всех наших примерах.

person Maximilian Berghoff    schedule 18.07.2017