覆盖路由器并将参数添加到特定路由(在使用路径/ URL之前) [英] Override router and add parameter to specific routes (before path/url used)

查看:63
本文介绍了覆盖路由器并将参数添加到特定路由(在使用路径/ URL之前)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我会使用简单的管理路由系统。



例如,现在我有此路由。

  _welcome任意ANY / 
acmedemo_example_index ANY ANY / acme / demos
acmedemo_example_edit ANY ANY / acme / edit / {id}
acmedemo_example_delete ANY ANY ANY / acme / delete / {id}
acmeapi_backup_get获取任何内容/ api / acme
acmeapi_backup_edit发布任何内容/ api / acme

现在,我将当前用户ID添加到每条路由,因为如果用户向我或其他支持者/管理员发送了链接,我们将看到用户看到的内容。
您了解吗?



我现在要这样做。

  _welcome任何ANY ANY / 
acmedemo_example_index ANY ANY ANY / {user} / acme / demos
acmedemo_example_edit ANY ANY / {user} / acme / edit / {id}
acmedemo_example_delete ANY ANY任意/ {user} / acme / delete / {id}
acmeapi_backup_get获取任何任意/ api / acme
acmeapi_backup_edit POST任何任意/ api / acme

现在,问题 ...如果路由名称匹配 preg_match,我想自动将 user参数添加到每个路由('/ ^ acmedemo_ / i')



例如(index.html.twig):

 < a href = {{path('acmedemo_example_index')}}>显示演示< / a> 

 < a href = {{path('acmedemo_example_edit',{id:Entity.id})}}}>编辑演示< / a> 

要使用 {{路径( acmedemo_example_edit,{id:entity.id,用户:app.user.id})}}



用户参数需要 \d +。



例如,我想覆盖路由器上的生成功能。
然后我可以检查 $ router-> getUrl()是否与 ^ acmedemo _ 匹配,然后我可以添加 user 参数:)



谢谢!

解决方案

对我来说是新的一天:D



我覆盖了路由器和UrlGenerator。



@ Chausser :我用一个简单的方法解决了问题1:

  acme_demo_example:
资源: @ AcmeDemoBundle / Controller /
类型:注释
前缀:/ {user}

现在我有这样的路线。

  _welcome任何ANY ANY / 
acmedemo_example_index ANY ANY ANY / {user} / acme / demos
acmedemo_example_edit ANY ANY / {user} / acme / edit / {id}
acmedemo_example_delete任意任意/ {user} / acme / delete / {id}
acmeapi_examples_get获取任何任意/ api / acme
acmeapi_examples_edit发布任何文件/ api / acme

问题1已解决!



现在的问题2是因为我不需要额外的路由功能或其他东西。
我想使用< a href = {{path('acmedemo_example_index')}}>显示演示< / a> < a href = {{path('acmedemo_example_edit',{id:Entity.id})}} && gt;编辑演示< / a>



但是如果我使用它,我会得到错误。
也可以执行此操作。



此服务的问题在于我没有容器>。

services.yml

 参数:
router.class: Acme\DemoBundle\Routing\路由器
router.options.generator_base_class:Acme\DemoBundle\Routing\Generator\UrlGenerator

Acme\DemoBundle\Routing\Router

 使用Symfony\捆绑\FrameworkBundle\路由\Router作为BaseRouter; 
类Router扩展BaseRouter实现ContainerAwareInterface
{
private $ container;

公共功能__construct(ContainerInterface $ container,$ resource,array $ options = array(),RequestContext $ context = null)
{
parent :: __ construct($ container, $ resource,$ options,$ context);
$ this-> setContainer($ container);
}

公共函数getGenerator()
{
$ generator = parent :: getGenerator();
$ generator-> setContainer($ this-> container);
return $ generator;
}

公共功能setContainer(ContainerInterface $ container = null)
{
$ this-> container = $ container;
}
}

Acme\DemoBundle\Routing\ \Generator\UrlGenerator

 使用Symfony\Component\Routing\Generator\UrlGenerator作为BaseUrlGenerator; 
类UrlGenerator扩展BaseUrlGenerator实现ContainerAwareInterface
{
private $ container;

受保护的函数doGenerate($ variables,$ defaults,$ requirements,$ tokens,$ parameters,$ name,$ referenceType,$ hostTokens)
{
/ **设置没有用户参数的路由的默认用户参数* /
if(preg_match('/ ^ acmedemo_ / i',$ name)&& in_array('user',$ variables)&& ;!array_key_exists('user',$ parameters))
{
$ parameters ['user'] = $ this-> getUser()-> getId();
}

return parent :: doGenerate($ variables,$ defaults,$ requirements,$ tokens,$ parameters,$ name,$ referenceType,$ hostTokens);
}

公共功能setContainer(ContainerInterface $ container = null)
{
$ this-> container = $ container;
}

/ **
* @see \Symfony\组件\安全\核心\身份验证\令牌\令牌接口:: getUser()
* /
公共函数getUser()
{
if(!$ this-> container-> has('security.context')){
throw新的\LogicException('SecurityBundle未在您的应用程序中注册。');
}

if(null === $ token = $ this->容器-> get('security.context')-> getToken()){
返回null;
}

if(!is_object($ user = $ token-> getUser())){
返回null;
}

return $ user;
}
}

问题2已解决!



(我在Symfony上写的代码 * 2.3 *



感谢您的帮助。但这更好,我认为 =)


I would use a easy management routing system.

For example NOW i have this routes.

_welcome                    ANY      ANY    ANY  /
acmedemo_example_index      ANY      ANY    ANY  /acme/demos
acmedemo_example_edit       ANY      ANY    ANY  /acme/edit/{id}
acmedemo_example_delete     ANY      ANY    ANY  /acme/delete/{id}
acmeapi_backup_get          GET      ANY    ANY  /api/acme
acmeapi_backup_edit         POST     ANY    ANY  /api/acme

Now I would add the current user id to each route, because if a user send me or another supporter/administrator a link, we would see what the user see. You understand?

I would have this now.

_welcome                    ANY      ANY    ANY  /
acmedemo_example_index      ANY      ANY    ANY  /{user}/acme/demos
acmedemo_example_edit       ANY      ANY    ANY  /{user}/acme/edit/{id}
acmedemo_example_delete     ANY      ANY    ANY  /{user}/acme/delete/{id}
acmeapi_backup_get          GET      ANY    ANY  /api/acme
acmeapi_backup_edit         POST     ANY    ANY  /api/acme

And now the "problem"... I want to add the "user" parameter to each route automatically if the route name matches preg_match('/^acmedemo_/i').

For example (index.html.twig):

<a href="{{ path('acmedemo_example_index') }}">Show demos</a>

Or

<a href="{{ path('acmedemo_example_edit', {id: entity.id}) }}">Edit demo</a>

I NOT want to use {{ path('acmedemo_example_edit', {id: entity.id, user: app.user.id}) }}!

And the "user" parameter requires "\d+".

I would like to override the "generate" function on the router, for example. Then I could check if $router->getUrl() matches the ^acmedemo_ and then I could add the user parameter :)

Thanks!

解决方案

Soooo new day for me :D

I overrided the router and the UrlGenerator.

@Chausser: I fixed your problem 1 with an easy:

acme_demo_example:
    resource: "@AcmeDemoBundle/Controller/"
    type:     annotation
    prefix:   /{user}

Now I have routes like this.

_welcome                    ANY      ANY    ANY  /
acmedemo_example_index      ANY      ANY    ANY  /{user}/acme/demos
acmedemo_example_edit       ANY      ANY    ANY  /{user}/acme/edit/{id}
acmedemo_example_delete     ANY      ANY    ANY  /{user}/acme/delete/{id}
acmeapi_examples_get        GET      ANY    ANY  /api/acme
acmeapi_examples_edit       POST     ANY    ANY  /api/acme

Problem 1 solved!

Now problem 2, because I want no extra route function or something else. I want to use <a href="{{ path('acmedemo_example_index') }}">Show demos</a> and <a href="{{ path('acmedemo_example_edit', {id: entity.id}) }}">Edit demo</a>.

But if I would use that I would get errors. Also lets do this.

The problem I had with this service is that I have no container >.<

services.yml

parameters:
    router.class: Acme\DemoBundle\Routing\Router
    router.options.generator_base_class: Acme\DemoBundle\Routing\Generator\UrlGenerator

Acme\DemoBundle\Routing\Router

use Symfony\Bundle\FrameworkBundle\Routing\Router as BaseRouter;
class Router extends BaseRouter implements ContainerAwareInterface
{
    private $container;

    public function __construct(ContainerInterface $container, $resource, array $options = array(), RequestContext $context = null)
    {
        parent::__construct($container, $resource, $options, $context);
        $this->setContainer($container);
    }

    public function getGenerator()
    {
        $generator = parent::getGenerator();
        $generator->setContainer($this->container);
        return $generator;
    }

    public function setContainer(ContainerInterface $container = null)
    {
        $this->container = $container;
    }
}

Acme\DemoBundle\Routing\Generator\UrlGenerator

use Symfony\Component\Routing\Generator\UrlGenerator as BaseUrlGenerator;
class UrlGenerator extends BaseUrlGenerator implements ContainerAwareInterface
{
    private $container;

    protected function doGenerate($variables, $defaults, $requirements, $tokens, $parameters, $name, $referenceType, $hostTokens)
    {
        /** Set the default user parameter for the routes which haven't a user parameter */
        if(preg_match('/^acmedemo_/i', $name) && in_array('user', $variables) && !array_key_exists('user', $parameters))
        {
            $parameters['user'] = $this->getUser()->getId();
        }

        return parent::doGenerate($variables, $defaults, $requirements, $tokens, $parameters, $name, $referenceType, $hostTokens);
    }

    public function setContainer(ContainerInterface $container = null)
    {
        $this->container = $container;
    }

    /**
     * @see \Symfony\Component\Security\Core\Authentication\Token\TokenInterface::getUser()
     */
    public function getUser()
    {
        if (!$this->container->has('security.context')) {
            throw new \LogicException('The SecurityBundle is not registered in your application.');
        }

        if (null === $token = $this->container->get('security.context')->getToken()) {
            return null;
        }

        if (!is_object($user = $token->getUser())) {
            return null;
        }

        return $user;
    }
}

Problem 2 solved!

(Codes writed by me on Symfony*2.3*)

Thanks for your help. But this is better I think =)

这篇关于覆盖路由器并将参数添加到特定路由(在使用路径/ URL之前)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆