Symfony框架之重写FOSUserBundle的默认控制器

原文地址http://symfony.com/doc/current/bundles/FOSUserBundle/overriding_controllers.html

FOSUserBundle中默认的控制器提供了大量的功能来满足日常使用. 但在你的应用中, 通常需要继承这些功能, 并且在里面添加你自己的业务逻辑.

重写控制器需要复制所有的action逻辑. 大多数情况下使用事件来实现功能会更简单一些. 只有在没有其他办法的情况下才会考虑重写控制器.

重写控制器的第一步是创建一个继承FOSUserBundle的子bundle. 下面的代码片段定义了一个名为AcmeUserBundle的继承自FOSUserBundle的子bundle.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
// src/Acme/UserBundle/AcmeUserBundle.php

namespace Acme\UserBundle;

use Symfony\Component\HttpKernel\Bundle\Bundle;

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

Symfony框架只中每个bundle只能有一个子bundle. 这意味着你不能再创建另外一个继承自FOSUserBundle的子bundle.

现在你已经创建了一个新的子bundle, 你可以创建一个与你想重写的控制器路径以及名称相同的控制器类. 在这个例子中,通过扩展FOSUserBundle中的RegistrationController类来实现对RegistrationController的方法中额外的功能的重写.
下面的例子中重写了registerAction方法. 它使用了base 控制器的代码并且添加了新用户登录的逻辑.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<?php
// src/Acme/UserBundle/Controller/RegistrationController.php

namespace Acme\UserBundle\Controller;

use Symfony\Component\HttpFoundation\RedirectResponse;
use FOS\UserBundle\Controller\RegistrationController as BaseController;
use Symfony\Component\HttpFoundation\Request;

class RegistrationController extends BaseController
{
public function registerAction(Request $request)
{
$form = $this->container->get('fos_user.registration.form');
$formHandler = $this->container->get('fos_user.registration.form.handler');
$confirmationEnabled = $this->container->getParameter('fos_user.registration.confirmation.enabled');

$process = $formHandler->process($confirmationEnabled);
if ($process) {
$user = $form->getData();

/*****************************************************
* Add new functionality (e.g. log the registration) *
*****************************************************/
$this->container->get('logger')->info(
sprintf('New user registration: %s', $user)
);

if ($confirmationEnabled) {
$this->container->get('session')->set('fos_user_send_confirmation_email/email', $user->getEmail());
$route = 'fos_user_registration_check_email';
} else {
$this->authenticateUser($user);
$route = 'fos_user_registration_confirmed';
}

$this->setFlash('fos_user_success', 'registration.flash.user_created');
$url = $this->container->get('router')->generate($route);

return new RedirectResponse($url);
}

return $this->container->get('templating')->renderResponse('FOSUserBundle:Registration:register.html.twig', array(
'form' => $form->createView(),
));
}
}

如果在你想重写时不继承FOSUserBundle控制器类而是继承自FrameworkBundle提供的容器或者控制器, 那你就必须实现FOSUserBundle 的控制器所有的方法.