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() {
$controllerClasses = Configure::listObjects('controller');
foreach($controllerClasses as $controller) {
if ($controller != 'App') {
$fileName = strtolower($controller).'_controller.php';
$file = CONTROLLERS.$fileName;
require_once($file);
$className = $controller . 'Controller';
$actions = get_class_methods($className);
foreach($actions as $k => $v) {
if ($v{0} == '_') {
unset($actions[$k]);
}
}
$parentActions = get_class_methods(’AppController’);
$controllers[$controller] = 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
)
Update 2008-02-04: Applying Jej’s patch and adapted the component to work with Cake 1.2.




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.)
Ooops made a copy paste error… that should be:
$controller_methods = get_class_methods(”Controller”);
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 ; ).
@AD7six, Felix: Thanks for your additions. I have completely missed plug-ins ;)
[...] 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: [...]
[...] The Permission Model is simplified by the fact that permission are either 1 or 0. There are no levels, it’s either can or can’t. Development was aided by a year old post from Daniel Hofstetter, the cakeBaker himself: How to list all controllers. [...]
[...] The Permission Model is simplified by the fact that permission are either 1 or 0. There are no levels, it’s either can or can’t. Development was aided by a year old post from Daniel Hofstetter, the cakeBaker himself: How to list all controllers. [...]
Hi,
Thanks for this hack, very useful for me.
I noticed that the _private _functions() are returned as controller functions. That’s not correct I think. Here is a small patch for this :
$actions = get_class_methods($className);
+ foreach($actions as $k => $v)
+ if ($v{0} == ‘_’) unset($actions[$k]);
$parentActions = get_class_methods(’AppController’);
Bye,
J.
Hi again,
Here is a modified version compatible with cake 1.2 :
$v)
if ($v{0} == ‘_’) unset($actions[$k]);
$parentActions = get_class_methods(’AppController’);
$controllersList[$controller] = array_diff($actions, $parentActions);
}
return $controllersList;
}
}
?>
Bye,
J.
@Jej: Thanks for your patch, I modified the article accordingly.
Hi cakebaker,
Thanks for the update. You can delete comment February 02, 2008 at 20:06, it was a mistake (the first submit didn’t appear)
Cheers,
Jej
@Jej: Ok, comment is now deleted.
After the $file = CONTROLLERS.$fileName; You may want to put a check for file existence, just in case a controller file is not there.
$file = CONTROLLERS.$fileName;
if(!file_exists($file)) continue; //Just in case
require_once($file);
@Chris: Thanks for your comment!
I’m not sure, if that’s really necessary, as Configure::listObjects(’controller’); gets the names of the controllers from the file system (at least if there is no caching).