ZF2 - Get controller name into layout/views

26,853

Solution 1

ZF2 is out and so is the skeleton. This is adding on top of the skeleton so it should be your best example:

Inside Module.php

public function onBootstrap($e)
{
    $e->getApplication()->getServiceManager()->get('translator');
    $e->getApplication()->getServiceManager()->get('viewhelpermanager')->setFactory('controllerName', function($sm) use ($e) {
        $viewHelper = new View\Helper\ControllerName($e->getRouteMatch());
        return $viewHelper;
    });

    $eventManager        = $e->getApplication()->getEventManager();
    $moduleRouteListener = new ModuleRouteListener();
    $moduleRouteListener->attach($eventManager);
}

The actual ViewHelper:

// Application/View/Helper/ControllerName.php

namespace Application\View\Helper;

use Zend\View\Helper\AbstractHelper;

class ControllerName extends AbstractHelper
{

protected $routeMatch;

    public function __construct($routeMatch)
    {
        $this->routeMatch = $routeMatch;
    }

    public function __invoke()
    {
        if ($this->routeMatch) {
            $controller = $this->routeMatch->getParam('controller', 'index');
            return $controller;
        }
    }
}

Inside any of your views/layouts

echo $this->controllerName()

Solution 2

This would be a solution I got to work with zf2 beta5

module/MyModule/Module.php

namespace MyModule;

use Zend\Mvc\ModuleRouteListener;
use MyModule\View\Helper as MyViewHelper;

class Module
{
    public function onBootstrap($e)
    {
        $app = $e->getApplication();
        $serviceManager = $app->getServiceManager();

        $serviceManager->get('viewhelpermanager')->setFactory('myviewalias', function($sm) use ($e) {
            return new MyViewHelper($e->getRouteMatch());
        });
    }
    ...
}

module/MyModule/src/MyModule/View/Helper.php

namespace MyModule\View;

use Zend\View\Helper\AbstractHelper;

class Helper extends AbstractHelper
{

    protected $route;

    public function __construct($route)
    {
        $this->route = $route;
    }

    public function echoController()
    {
        $controller = $this->route->getParam('controller', 'index');
        echo $controller;
    }
}

In any viewfile

$this->myviewalias()->echoController();

Solution 3

instead of extending onBootStrap() in Module.php, you can use getViewHelperConfig() (also in Module.php). The actual helper is unchanged, but you get the following code to create it:

public function getViewHelperConfig()
{
   return array(
         'factories' => array(
            'ControllerName' => function ($sm) {
               $match = $sm->getServiceLocator()->get('application')->getMvcEvent()->getRouteMatch();
               $viewHelper = new \Application\View\Helper\ControllerName($match);
               return $viewHelper;
            },
         ),
   );
}

Solution 4

Short Code here :

$this->getHelperPluginManager()->getServiceLocator()->get('application')->getMvcEvent()->getRouteMatch()->getParam('action', 'index');

$controller = $this->getHelperPluginManager()->getServiceLocator()->get('application')->getMvcEvent()->getRouteMatch()->getParam('controller', 'index');

$controller = array_pop(explode('\', $controller));

Solution 5

I wanted to access current module/controller/route name in navigation menu partial and there was no way but to implement custom view helper and access it, i came up with the following, i am posting it here.

<?php
namespace Application\View\Helper;

use Zend\View\Helper\AbstractHelper;

/**
 * View Helper to return current module, controller & action name.
 */
class CurrentRequest extends AbstractHelper
{
    /**
     * Current Request parameters
     *
     * @access protected
     * @var array
     */
    protected $params;

    /**
     * Current module name.
     *
     * @access protected
     * @var string
     */
    protected $moduleName;

    /**
     * Current controller name.
     *
     * @access protected
     * @var string
     */
    protected $controllerName;

    /**
     * Current action name.
     *
     * @access protected
     * @var string
     */
    protected $actionName;

    /**
     * Current route name.
     *
     * @access protected
     * @var string
     */
    protected $routeName;

    /**
     * Parse request and substitute values in corresponding properties.
     */
    public function __invoke()
    {
        $this->params = $this->initialize();
        return $this;
    }

    /**
     * Initialize and extract parameters from current request.
     *
     * @access protected
     * @return $params array
     */
    protected function initialize()
    {
        $sm = $this->getView()->getHelperPluginManager()->getServiceLocator();
        $router = $sm->get('router');
        $request = $sm->get('request');
        $matchedRoute = $router->match($request);
        $params = $matchedRoute->getParams();
        /**
         * Controller are defined in two patterns.
         * 1. With Namespace
         * 2. Without Namespace.
         * Concatenate Namespace for controller without it.
         */
        $this->controllerName = !strpos($params['controller'], '\\') ?
            $params['__NAMESPACE__'].'\\'.$params['controller'] :
            $params['controller'];
        $this->actionName = $params['action'];
        /**
         * Extract Module name from current controller name.
         * First camel cased character are assumed to be module name.
         */
        $this->moduleName = substr($this->controllerName, 0, strpos($this->controllerName, '\\'));
        $this->routeName = $matchedRoute->getMatchedRouteName();
        return $params;
    }

    /**
     * Return module, controller, action or route name.
     *
     * @access public
     * @return $result string.
     */
    public function get($type)
    {
        $type = strtolower($type);
        $result = false;
        switch ($type) {
            case 'module':
                    $result = $this->moduleName;
                break;
            case 'controller':
                    $result = $this->controllerName;
                break;
            case 'action':
                    $result = $this->actionName;
                break;
            case 'route':
                    $result = $this->routeName;
                break;
        }
        return $result;
    }
}

In order to access the values in layout/view here is how i do it.

1. $this->currentRequest()->get('module');
2. $this->currentRequest()->get('controller');
3. $this->currentRequest()->get('action');
4. $this->currentRequest()->get('route');

Hope this helps someone.

Share:
26,853
Intellix
Author by

Intellix

Developer of an online game: Konoro Kingdom (Conquer Games) and also the developer of Browser Game List Check out my game and if you register send me an instant message as I'd love to hear from you. In my spare time I enjoy breakdancing, playing poker and odd sports!

Updated on November 24, 2020

Comments

  • Intellix
    Intellix over 3 years

    I know with ZF1 you would retrieve the module/controller name using custom View Helpers that would get the singleton frontController object and get the name there.

    Using ZF2 as they've abolished alot of the singleton nature of the framework and introduced DI where I've specified aliases for all of my controllers within this module... I can imagine I would get it through accessing the DI or perhaps injecting the current name into the layout.

    Anyone got any idea how you would do it. I guess there a hundred different ways but after sniffing about the code for a few hours I can't really figure out how its meant to be done now.

    The reason I wanted the controller name is to add it to the body as a class for specific controller styling.

    Thanks, Dom

  • rdo
    rdo almost 12 years
    Example was taken from here: git.mwop.net/…
  • Intellix
    Intellix over 11 years
    I believe you can change echoController() to __invoke() and change echo $controller; to return $controller
  • Intellix
    Intellix over 11 years
    Also, in case you're getting errors about calling getParam() on a non-object it might be worth checking if a resource is being called and exists... like a favicon. Had ZF2 being called and bootstrapped without any parameters when favicon was called and didn't exist so this was complaining/logging an error and making each request real slow.
  • Kathiravan
    Kathiravan almost 11 years
    Hi Dominic Watson, am got the error instead of 404 page. May i know how to check resource is being called or exists am new to ZF2 please help
  • Intellix
    Intellix almost 11 years
    I've added if ($this->routeMatch) in the above code to check that it exists so you should get 404 rather than an error (as theres no routeMatch for missing favicon or something like that)
  • Armfoot
    Armfoot over 10 years
    This solution is even better than the accepted one (slimmer onBootstrap)! For logic reasons, I suggest placing this on the Application module instead of one of your own modules due to the fact that you're able to call $this->myviewalias() in any module view. As Dominic suggested, if you use __invoke() and return the string, you don't need ->echoController(), but if you want to use myviewalias for more purposes, do not use __invoke() and add more functions to the helper (e.g.: another function that returns the action ->getParam('action', 'index')). Hope it helps!
  • Armfoot
    Armfoot over 10 years
    Actually the accepted answer edits the onBootstrap function from the Application\Module.php... So in fact, they are almost the same answer. The real difference is how each one uses the view functions (by __invoke() or independent functions).
  • Borje
    Borje over 10 years
    If I had done this today I would have registered the view help factory in the Module::getViewHelperConfig() method instead of setting it up in the bootstrap. See dstj's example below. If the helper only needs to echo the controller, the __invoke() method leads the slimmer looking view files. If you'd like the same helper to be able to output other stuff like action, then the above solution might be preferable.
  • user269867
    user269867 about 10 years
    Fatal error: Class 'Application\View\Helper\ControllerName' not found in C:\wamp\www\project\module\Application\Module.php on line 95 ...My directory structure is module>>Application>>view>>Helper>>ControllerName.php....wha‌​ts wrong
  • Intellix
    Intellix about 10 years
    It needs to be in: module>>Application>>src>>Application>>View>>Helper>>Control‌​lerName.php - You've put it where your actual phtml views are
  • tasmaniski
    tasmaniski over 8 years
    there is no __NAMESPACE__ in $params. Which version you are using?
  • Sarang
    Sarang about 8 years
    Thanks this worked for me. Can I also get action name as well?
  • php-dev
    php-dev over 7 years
    Do you mind wrapping your code-only-answer with some comments?