如何在Symfony RoutingBundle (PHPCR)中创建自定义路径的路由


How to create a route with custom path in Symfony RoutingBundle (PHPCR)?

我目前正在为我最近开始的一个项目研究Symfony CMF和PHPCR。我目前想弄清楚的是如何创建一个Route并将其保存到数据库中。据我所知,我必须使用Symfony'Cmf'Bundle'RoutingBundle'Doctrine'Phpcr'Route并将元素持久化到数据库中。这可以正常工作,但会自动生成一个路由路径,这不是我想要的。我需要做的是生成一个链接到特定控制器的自定义路由。下面是我的代码:

$em = $this->get('doctrine_phpcr.odm.document_manager');
$parent = $em->find(null, '/cms/routes');
$route = new 'Symfony'Cmf'Bundle'RoutingBundle'Doctrine'Phpcr'Route();
$route->setParentDocument($parent);
$route->setName('my_route_name');
$route->setDefault('_controller', 'AppBaseBundle:Frontend/Users:index');
$em->persist($route);
$em->flush();

如果我执行此代码,生成的路由将是/cms/routes/my_route_name。从我所看到的,您可以使用$route->setPath('/testing');,但这会生成以下异常:

无法确定前缀。这要么是一个新的、未持久化的文档,要么是调用setPrefix的侦听器没有正确设置。

有谁知道怎么解决这个问题吗?

在PHPCR中,每个文档都有一个存储它的path。如果您熟悉原则ORM,则路径具有ID的角色。ORM的不同之处在于,所有文档(无论其类型如何)都位于同一棵树中。这很好,因为您的路由可以引用任何东西,而不限于特定的文档类型。但是我们需要用路径创建一些结构。这就是为什么我们有prefix概念。所有路由都放在前缀(默认为/cms/routes)下。文档路径的这一部分将为URL路径删除。所以存储库路径/cms/route/testing是url domain.com/testing。

关于示例代码:通常,您希望通过内容文档的类或路由"type"属性来配置控制器,以避免将控制器名称存储到数据库中,以便将来进行重构。这在[CMF文档的路由章节][1]中有很多解释,但前缀只在那里使用,没有明确解释。我们需要改进那里的文档。

[1] http://symfony.com/doc/master/cmf/book/routing.html

我设法找到了克服这个问题的方法。因为在我的项目中我也有RouteAutoBundle,所以我创建了一个扩展'Symfony'Cmf'Bundle'RoutingBundle'Doctrine'Phpcr'Route的类。在这个类中我添加了:

/**
 * @PHPCR'Document(referenceable=true)
 */
class MenuRoute extends Route
{
    protected $url;
    /**
     * Get $this->url
     *
     * @return mixed
     */
    public function getUrl() {
        return $this->url;
    }
    /**
     * Set $this->url
     *
     * @param mixed $url
     */
    public function setUrl($url) {
        $this->url = $url;
    }
}

之后,我把这个添加到cmf_routing_auto.yml:

App'MenuBundle'Document'MenuRoute:
    uri_schema: /{getUrl}
    token_providers:
        getUrl: [content_method, { method: getUrl }]

所以现在只需创建MenuRoute的实例(就像使用Route时一样)并调用方法setUrl($your_url)传递所需的url。

如果有人找到更好的方法,我愿意接受建议。