dongyue3795 2016-02-02 06:40
浏览 39
已采纳

beforeFilter函数不在Symfony2中重定向

I have implemented following code to run a code on before any action of any controller. However, the beforeFilter() function not redirecting to the route I have specified. Instead it takes the user to the location where the user clicked.

//My Listener
namespace Edu\AccountBundle\EventListener;
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;

class BeforeControllerListener
{
    public function onKernelController(FilterControllerEvent $event)
    {
        $controller = $event->getController();
        if (!is_array($controller))
        {
            //not a controller do nothing
            return;
        }
        $controllerObject = $controller[0];
        if (is_object($controllerObject) && method_exists($controllerObject, "beforeFilter"))
        //Set a predefined function to execute Before any controller Executes its any method
        {
            $controllerObject->beforeFilter();
        }
    }
}
//I have registered it already

//My Controller
class LedgerController extends Controller
{        
    public function beforeFilter()
    {   
        $commonFunction = new CommonFunctions();
        $dm = $this->getDocumentManager();
        if ($commonFunction->checkFinancialYear($dm) == 0 ) {
            $this->get('session')->getFlashBag()->add('error', 'Sorry');
            return $this->redirect($this->generateUrl('financialyear'));//Here it is not redirecting
        }
    }
}

public function indexAction() {}

Please help, What is missing in it. Thanks Advance

  • 写回答

3条回答 默认 最新

  • dshyu6866 2016-02-02 16:06
    关注

    I would suggest you follow the Symfony suggestions for setting up before and after filters, where you perform your functionality within the filter itself, rather than trying to create a beforeFilter() function in your controller that is executed. It will allow you to achieve what you want - the function being called before every controller action - as well as not having to muddy up your controller(s) with additional code. In your case, you would also want to inject the Symfony session to the filter:

    # app/config/services.yml
    services:
        app.before_controller_listener:
            class: AppBundle\EventListener\BeforeControllerListener
            arguments: ['@session', '@router', '@doctrine_mongodb.odm.document_manager']
            tags:
                - { name: kernel.event_listener, event: kernel.controller, method: onKernelController }
    

    Then you'll create your before listener, which will need the Symony session and routing services, as well as the MongoDB document manager (making that assumption based on your profile).

    // src/AppBundle/EventListener/BeforeControllerListener.php
    namespace AppBundle\EventListener;
    
    use Doctrine\ODM\MongoDB\DocumentManager;
    use Symfony\Bundle\FrameworkBundle\Routing\Router;
    use Symfony\Component\HttpFoundation\RedirectResponse;
    use Symfony\Component\HttpFoundation\Session\Session;
    use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
    use AppBundle\Controller\LedgerController;
    use AppBundle\Path\To\Your\CommonFunctions;
    
    class BeforeControllerListener
    {
        private $session;
        private $router;
        private $documentManager;
        private $commonFunctions;
    
        public function __construct(Session $session, Router $router, DocumentManager $dm)
        {
            $this->session = $session;
            $this->router = $router;
            $this->dm = $dm;
            $this->commonFunctions = new CommonFunctions();
        }
    
        public function onKernelController(FilterControllerEvent $event)
        {
            $controller = $event->getController();
    
            if (!is_array($controller)) {
                return;
            }
    
            if ($controller[0] instanceof LedgerController) {
                if ($this->commonFunctions->checkFinancialYear($this->dm) !== 0 ) {
                    return;
                }
    
                $this->session->getFlashBag()->add('error', 'Sorry');
                $redirectUrl= $this->router->generate('financialyear');
    
                $event->setController(function() use ($redirectUrl) {
                    return new RedirectResponse($redirectUrl);
                });
            }
        }
    }
    

    If you are in fact using the Symfony CMF then the Router might actually be ChainRouter and your use statement for the router would change to use Symfony\Cmf\Component\Routing\ChainRouter;

    There are a few additional things here you might want to reconsider - for instance, if the CommonFunctions class needs DocumentManager, you might just want to make your CommonFunctions class a service that injects the DocumentManager automatically. Then in this service you would only have to inject your common functions service instead of the document manager.

    Either way what is happening here is that we are checking that we are in the LedgerController, then checking whether or not we want to redirect, and if so we overwrite the entire Controller via a callback. This sets the redirect response to your route and performs the redirect.

    If you want this check on every single controller you could simply eliminate the check for LedgerController. .

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥15 关于#sql#的问题:#情况描述 在用vs对项目进行调试时,出现找不到网络路径,然后查看SQL配置工具,发现SQL服务显示远程调用过程失败(相关搜索:防火墙)
  • ¥15 主要进行描述泥浆在管路不同区段泥浆的密度不相同,泥浆的密度有高有低,此时管路的摩阻分布需要怎么计算,(标签-matlab)
  • ¥40 通过编制程序计算圆管内层流充分发展对流换热,参数如图5-4,以及公式5-16所示,要求用表5-6对程序计算准确性进行验证
  • ¥20 该学习哪个编程语言? AI会取代程序员吗?
  • ¥15 ensp如何拼通IP地址
  • ¥15 saber软件导入Ibis模型报错
  • ¥15 商城生产日期批次库存问题
  • ¥15 esp8266控制共阳极wrgb灯板无法关闭所有led灯
  • ¥100 python读取速度问题
  • ¥15 stm32f407使用DMA问题