We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

get all controllers and actions names

Hi, I'm trying to setup a form for administrating roles and permissions per role for that I want admin to be able to choose all controllers one-by-one for and then select several actions from selected controller to allow them to user. So, the question is how to actually get list of all controllers and then list of all actions for selected controller?



5.2k

Actually raising this question again - how to get list of controllers then?



6.4k
Accepted
answer

Something like this might help, but depends on the structure of your of application

<?php

$controllers = [];

foreach (glob(APP_PATH . '/src/Controller/*Controller.php') as $controller) {
    $className = 'YourNamespace\Controller\\' . basename($controller, '.php');
    $controllers[$className] = [];
    $methods = (new \ReflectionClass($className))->getMethods(\ReflectionMethod::IS_PUBLIC);

    foreach ($methods as $method) {
        if (\Phalcon\Text::endsWith($method->name, 'Action')) {
            $controllers[$className][] = $method->name;
        }
    }
}


5.2k
edited Mar '15

Here is what I did:

<?php
    public function getAllControllers()
    {
        $files = scandir('../plc/app/controllers');
        $controllers = array();
        foreach ($files as $file) {
            if ($controller = $this->extractController($file)) {
                $controllers[] = $controller;
            }
        }
        return $controllers;
    }

    public function getAllActions($controller)
    {
        $functions = get_class_methods($controller);
        $actions = array();
        foreach ($functions as $name) {
            $actions[] = $this->extractAction($name);
        }
        return array_filter($actions);
    }   

    protected function extractAction($name)
    {
        $action = explode('Action', $name);
        if ((count($action) > 1)) {
            return $action[0];
        }
    }

    protected function extractController($name)
    {
        $filename = explode('.php', $name);
        if (count(explode('Controller.php', $name)) > 1) {
            # code...
            if (count($filename) > 1) {
                return $filename[0];
            }
        }

        return false;
    }


5.2k

This is actually amazing solution! compact and full. Thank you!

Something like this might help, but depends on the structure of your of application

<?php

$controllers = [];

foreach (glob(APP_PATH . '/src/Controller/*Controller.php') as $controller) {
  $className = 'YourNamespace\Controller\\' . basename($controller, '.php');
  $controllers[$className] = [];
  $methods = (new \ReflectionClass($className))->getMethods(\ReflectionMethod::IS_PUBLIC);

  foreach ($methods as $method) {
      if (\Phalcon\Text::endsWith($method->name, 'Action')) {
          $controllers[$className][] = $method->name;
      }
  }
}

There is another simple way (Using Pattern) for handling permissions without parsing all controllers file like this:

$resources = array(
  array('*/*', '*'),
  array('*/' . $controllerName, '*'),
  array('*/*', $actionName),
  array($moduleName . '/*', '*'),
  array($moduleName . '/' . $controllerName, '*'),
  array($moduleName . '/' . $controllerName, $actionName)
);

for more information see my permission hanlidng plugin:

https://github.com/tartanpro/tartan/blob/master/src/Tartan/Plugin/AclCheckerPlugin.php



45

My realization:

private function _listControllers($application) {
    foreach (glob(APP_PATH . '/app/'.$application.'/controllers/*Controller.php') as $controller) {
        $className = basename($controller, 'Controller.php');
        foreach (get_class_methods("App\\".ucfirst($application)."\\Controllers\\$className"."Controller") as $actionName) {
            if (preg_match('/^([a-zA-Z]*)Action$/',$actionName,$action)) {
                $controllers[$className][] = $action[1];
            }
        }
    }
    return $controllers;
}