Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Base class controller with global twig service

Tags:

symfony

First of all, I have to say that I have been seeing answers and documentation for several days but none of them answer my question.

The only and simple thing I want to do is to use the twig service as a global service in a BaseController.

This is my code:

<?php
namespace App\Controller;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use App\Service\Configuration;
use App\Utils\Util;


abstract class BaseController extends Controller
{

    protected $twig;
    protected $configuration;

    public function __construct(\Twig_Environment $twig,Configuration $configuration)
  {
    $this->twig = $twig;
    $this->configuration = $configuration;
  }

}

Then in all my controllers extend the twig and configuration service, without having to inject it again & again.

//...
//......

/**
 * @Route("/configuration", name="configuration_")
 */
class ConfigurationController extends BaseController
{

    public function __construct()
    {
       //parent::__construct();

       $this->twig->addGlobal('menuActual', "config");

    }

As you can see the only thing I want is to have some services global to have everything more organized and also to create some global shortcuts for all my controllers. In this example I am assigning a global variable to make a link active in the menu of my template and in each controller I have to add a new value for menuActual, for example in the UserController the variable would be addGlobal('menuActual', "users").

I think this should be in the good practices of symfony which I don't find :(.

Having to include the \Twig_Environment in each controller to assign a variable to the view seems very repetitive to me. This should come by default in the controller.

Thanks

like image 345
jcarlosweb Avatar asked Apr 17 '26 18:04

jcarlosweb


1 Answers

I've had that problem as well - trying to not have to repeat a bit of code for every controller / action.

I solved it using an event listener:

# services.yaml
app.event_listener.controller_action_listener:
    class: App\EventListener\ControllerActionListener
    tags:
        - { name: kernel.event_listener, event: kernel.controller, method: onKernelController }
#src/EventListener/ControllerActionListener.php
namespace App\EventListener;

use App\Controller\BaseController;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;

/**
 * Class ControllerActionListener
 *
 * @package App\EventListener
 */
class ControllerActionListener
{
    public function onKernelController(FilterControllerEvent $event)
    {
        //fetch the controller class if available
        $controllerClass = null;
        if (!empty($event->getController())) {
            $controllerClass = $event->getController()[0];
        }

        //make sure your global instantiation only fires if the controller extends your base controller
        if ($controllerClass instanceof BaseController) {
            $controllerClass->getTwig()->addGlobal('menuActual', "config");
        }
    }
}
like image 53
Bananaapple Avatar answered Apr 19 '26 14:04

Bananaapple