Symfony2 / FOSUserBundle:在不改变父类的情况下更改渲染变量

时间:2013-08-16 08:34:26

标签: php symfony twig fosuserbundle

我的一个类目前在FOSUserBundle上扩展BaseController,并返回父操作。但是,由于项目规范,我不需要编辑父类。有没有办法通过子回复发送额外的变量,以便渲染树枝?

儿童班:

class ChangePasswordController extends BaseController
{
    public function changePasswordAction(Request $request)
    {
        $response = parent::changePasswordAction($request);

        return $response; // and 'myVariable' => $myVariable
    }
}

家长班:

class ChangePasswordController extends ContainerAware
{
    /**
     * Change user password
     */
    public function changePasswordAction(Request $request)
    {
        //lots of code.....

        return $this->container->get('templating')
                    ->renderResponse(
                    'FOSUserBundle:ChangePassword:changePassword.html.'
                        .$this->container->getParameter('fos_user.template.engine'),
                         array(
                         'form' => $form->createView()

                          //and 'myVariable' => $myVariable     

                          )
               );

    }
}

总而言之,是否有一种方法可以将一些东西传递给父类,而无需更改父类......同时使用其他变量渲染树枝视图。

- 更新 -

基本上我想使用FOSUserBundle changePassword动作渲染表单,因此这很好用:

return $this->container
            ->get('templating')
            ->renderResponse(
            'FOSUserBundle:ChangePassword:changePassword.html.'.$this->container->getParameter('fos_user.template.engine'),
            array('form' => $form->createView())
        );

但是,我想将更多变量传递给视图,就像上面显示的'form'一样,没有更改 FosUserBundle ChangePassword控制器。因此,我有一个继承该控制器的类,添加了一些额外的功能并返回父更改密码操作:

class ChangePassController extends ChangePasswordController
{
    public function changePasswordAction(Request $request)
    {
        // more code......

        $response = parent::changePasswordAction($request);
        return $response;
    }
}

但是,与大多数应用程序一样,我想在视图模板中添加不仅仅是表单变量。那么是否有一种方法可以将其他变量传递给视图,而无需更改父控制器/操作?喜欢(但不喜欢)推'myVariable'=> $ myVariable到父的changePasswordAction返回语句?

3 个答案:

答案 0 :(得分:0)

有一个section in FOSUserBundle documentation描述了如何做到这一点,并且来自Symfony2的Cookbook,How to use Bundle Inheritance to Override parts of a Bundle

总之,创建一个Bundle类来覆盖FOSUserBundle中的src

// src/Acme/UserBundle/AcmeUserBundle.php
<?php

namespace Acme\UserBundle;

use Symfony\Component\HttpKernel\Bundle\Bundle;

class AcmeUserBundle extends Bundle
{
    public function getParent()
    {
        return 'FOSUserBundle';
    }
}

然后,覆盖ChangePasswordController类:

use FOS\UserBundle\Controller\ChangePasswordController as BaseController;

class ChangePasswordController extends BaseController
{
    public function changePasswordAction(Request $request)
    {
        $response = parent::changePasswordAction($request);

        return $response; // and 'myVariable' => $myVariable
    }
}

<强> - UPDATE -

好吧我想我误解了你的问题。无论如何renderResponse()服务的templating基本上是:

$response->setContent($this->render($view, $parameters));

您可以运行Class实际上是TwigEngine class来查看templating服务的app/console container:debug

因此,您可以重新调用renderResponse()并为您提供额外的参数。例如:

return $this->container->get('templating')->renderResponse(
    'FOSUserBundle:ChangePassword:changePassword.html.'.$this->container->getParameter('fos_user.template.engine'),
    array(
        'form' => $form->createView(),
        'myVariable' => $myVariable', // There you go
    ),
    $response // The previous response that has been rendered by the parent class, by this is not necessary
);

答案 1 :(得分:0)

自下而上思考。

您可以使用Twig Extension http://symfony.com/doc/current/cookbook/templating/twig_extension.html

访问您的数据,而无需通过操作
    twig.extension.user_profile:
    class: 'MyBundle\UserProfileExtension'
    arguments:
        - '@doctrine.orm.entity_manager'
    tags:
        - { name: twig.extension }

扩展类

class UserProfileExtension extends \Twig_Extension
{
/**
 * @var EntityManager
 */
private $entityManager;

/**
 * @param UserProfileDataService $userProfileDataService
 */
public function __construct(EntityManager $entityManager)
{
    $this->entityManager = $entityManager;
}

/**
 * @return array
 */
public function getFunctions()
{
    return array(
        new \Twig_SimpleFunction('get_my_custom_var', array($this, 'getMyCustomVar')),
    );
}

/**
 * @return array
 */
public function getMyCustomVar()
{
    $var = $this->entityManager->getRepository('MyCustomRepository')->findOneBy(['id' => 1]);

    return $var;
}

/**
 * Returns the name of the extension.
 *
 * @return string The extension name
 */
public function getName()
{
    return 'user_profile_extension';
}

模板用法

{dump(get_my_custom_var())}

答案 2 :(得分:-1)

如果我正确理解您的问题,您应该能够在响应上设置其他变量,如下所示:

use FOS\UserBundle\Controller\ChangePasswordController as BaseController;

class ChangePasswordController extends BaseController
{
    public function changePasswordAction(Request $request)
    {
        $response = parent::changePasswordAction($request);

        $response['myVariable'] = $myVariable;

        return $response;
    }
}

希望这有帮助!