如何向现有Symfony应用程序添加简单的CMS功能

时间:2016-12-02 07:32:45

标签: content-management-system symfony symfony-cmf symfony-routing

我有一个访问MySQL数据库的现有Web应用程序。我将此应用程序移植到Symfony。新应用程序必须使用旧数据库,因为我们无法立即移植整个应用程序,即旧应用程序和新应用程序正在访问同一数据库并且应用程序同时运行。

旧应用程序有一个简单的CMS功能,必须移植:

有一个表page表示页面树。每个页面都有一个slug字段。 URL路径由表示标识页面节点的路径的那些段塞组成,例如, "/[parent-slug]/[child-slug]"

页表还包含content字段。正如我已经提到的,CMS功能非常简单,因此内容只是呈现为页面布局中的页面内容。页面条目还指定页面布局/模板。

我的问题是我不知道如何设置路由。在正常的Symfony应用程序中,我之前知道URL模式,但在这种情况下它们是动态的。此外,路由也不能缓存,因为用户可以随时更改它们。我想知道我是否必须完全放弃Symfony的路由并自行实现。但是如何?

现在我找到了Symfony CMF,它讲述了很多关于VS CMS路由冲突的框架。首先,我认为这将是正确的方式。然而,这些教程旨在构建一个基于PHPRC的全新应用程序。我无法将教程的概念推导到我的用例中。

2 个答案:

答案 0 :(得分:1)

由于您在一个symfony应用程序上运行多个URL规则,因此您需要使用url前缀。你的cms应该使用前缀/ cms / parent-slug / child-slug或所有其他控制器。否则,当动态请求到达时,您无法区分哪个控制器。

您可以尝试使用KernelControllerListener进行解决方法。他将赶上每个请求,然后检查是否请求了cms页面。根据请求,您可以自己设置控制器和操作。概念:

仅使用“/”创建一个路径。放弃oll其他规则。然后像这样创建一个Listener:

<?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/

答案 1 :(得分:0)

问题是:您是否愿意迁移数据?对于这两个问题,CMF都可以作为答案。如果您想要一个简单的动态路由器,您应该查看具有自定义路由器定义的ChainRouterhttps://symfony.com/doc/current/cmf/bundles/routing/dynamic.htmlhttps://symfony.com/doc/current/cmf/components/routing/chain.html 如果您想迁移数据,可以使用夹具加载器,就像我们在几乎所有示例中都使用的那样。