How to list all controllers

From time to time the question “how can I list all controllers?” pops up. I provided a (untested) solution in the german google group, but yesterday I had to see that it didn’t work (thanks to Kinesis77). So here is the improved code as a component:

// app/controllers/components/controller_list.php
class ControllerListComponent extends Object
{
    function get()
    {
        $controllerList = array(); 
     	$controllerClasses = listClasses(CONTROLLERS); 
		    
        foreach($controllerClasses as $controller => $fileName) 
        { 
            list($name) = explode('.', $fileName); 
            $controllerName = Inflector::camelize(
                                         str_replace('_controller', '', $name)); 
		        
            $file = CONTROLLERS.$fileName;
            require_once($file);
            $className = $controllerName . 'Controller';
            $actions = get_class_methods($className);
            $parentActions = get_class_methods('AppController');
            $controllers[$controllerName] = array_diff($actions, $parentActions);
        }
		     
        return $controllers;  
    }
}

The usage is simple. Just include the component in the $components array of your controller:

var $components = array('ControllerList');

and call it with:

$this->ControllerList->get()

It returns an array with the following format:

Array
(
    [Pages] => Array
        (
            [0] => display
        )
    [Tests] => Array
        (
            [0] => index
            [1] => groups
            [2] => cases
        )

4 Comments

  1. Posted July 21, 2006 at 7:26 pm | Permalink

    Like it.

    I have a sneaky suspicion that many users want to use this to generate a navigation menu whilst in development.

    You seem to be one blog ahead of me ;), here’s a snippet of code taken from something I was going to post in the coming days:

    $class_methods = get_class_methods($this->controller);
    $controller_methods = get_class_methods(“AppController”);
    $class_methods = array_diff($class_methods,$controller_methods);
    foreach ($class_methods as $method)
    {
    if ($method{0}”_”)
    {
    $admin = strpos($method, CAKE_ADMIN);
    if ($admin === false)
    {
    if (!stristr($method,”controller”)) // Without this, class names are appearing in the results (?) with PHP4.
    {
    $this->PublicUrls[] = Array(ucfirst($method),”/”.$this->controller->name.”/”.$method);
    }
    }
    }
    }

    That way, methods defined in app_controller or the plugin app controller are captured, and all the private methods are ignored (as well as the default methods, as is the case for your example.)

  2. Posted July 21, 2006 at 7:28 pm | Permalink

    Ooops made a copy paste error… that should be:

    $controller_methods = get_class_methods(”Controller”);

  3. Posted July 21, 2006 at 9:03 pm | Permalink

    Hi, one more thing to consider for any solution that is supposed to list controllers/models/etc., is that they can also be placed outside of app/controllers or app/models, and that those places can be defined in the bootstrap.php. For that reason, it is neccessary to loop through ldall those possible locations which you can get from the Configure singleton. Bear in mind that also plugins can have controllers in them.

    Just do something like this:
    uses(‘Folder’);
    $paths = Configure::getInstance();
    $folder =& new Folder();

    $controllers = array();

    foreach ($paths->controllerPaths as $path)
    {
    $folder->cd($path);
    $files = $folder->findRecursive(‘.*_controller\.php’);
    $controllers = array_merge($controllers, $files);
    }

    $folder->cd(APP.’plugins’);
    $files = $folder->findRecursive(‘.*_controller\.php’);
    $files = $folder->findRecursive(‘.*[^api]_controller\.php’);

    $controllers = array_merge($controllers, $files);

    Ok, this is not 100% perfect either, since it doesn’t go through each plugin folder and only checks the /controllers subdir in it, but you can add that.

    In SpliceIt! I sucessfully am using an automatically generated menu based on all _admin functions, the code can be found here:
    https://cakeforge.org/plugins/scmsvn/viewcvs.php/trunk/spliceit/app/plugins/admin/controllers/admin_api.php?rev=78&root=spliceit&view=markup

    Anyway, other then that thanks for publishing it, I think that’s really useful for a lot of people out there ; ).

  4. Posted July 22, 2006 at 9:54 am | Permalink

    @AD7six, Felix: Thanks for your additions. I have completely missed plug-ins ;)


One Trackback/Pingback

  1. […] How to list all controllers: ”From time to time the question ‘how can I list all controllers?’ pops up. I provided a (untested) solution in the german google group, but yesterday I had to see that it didn’t work (thanks to Kinesis77). So here is the improved code as a component: […]

%d bloggers like this: