views:

1830

answers:

3

I want to create a Zend Controller for ACL management so my problem is: Howe can I get all Module names, Control names and Action names in a Zend application to build a ACL Control?

I use Zend_Navigation and if the resource don't exist in your ACL Zend_Navigation is thrown a exception. And I want to use a database to deny and allow access. So I must build the database first. And if I must do that by hand it's a pain to do that.

Thank you,

Ivo Trompert

A: 

I don't think there is a solution for this in Zend. You will have to do it yourself...

One way to do it, is to list all classes, and check if the classes extend (for example) the Zend_Controller_Action class...

check the php functions get_declared_classes and is_subclass_of

foreach(get_declared_classes() as $c){
  if(is_subclass_of($c, 'Zend_Controller_Action')){
     ...
  }
}
Fortega
+1  A: 

I have created a function that can get all the actions, controllers and modules from a zend application. Here it is:

$module_dir = substr(str_replace("\\","/",$this->getFrontController()->getModuleDirectory()),0,strrpos(str_replace("\\","/",$this->getFrontController()->getModuleDirectory()),'/'));
    $temp = array_diff( scandir( $module_dir), Array( ".", "..", ".svn"));
    $modules = array();
    $controller_directorys = array();
    foreach ($temp as $module) {
     if (is_dir($module_dir . "/" . $module)) {
      array_push($modules,$module);
      array_push($controller_directorys, str_replace("\\","/",$this->getFrontController()->getControllerDirectory($module)));
     }
    }

    foreach ($controller_directorys as $dir) {
     foreach (scandir($dir) as $dirstructure) {
      if (is_file($dir  . "/" . $dirstructure)) {
       if (strstr($dirstructure,"Controller.php") != false) {
        include_once($dir . "/" . $dirstructure);
       }
      }

     }
    }

    $default_module = $this->getFrontController()->getDefaultModule();

    $db_structure = array();

    foreach(get_declared_classes() as $c){
  if(is_subclass_of($c, 'Zend_Controller_Action')){
   $functions = array();
   foreach (get_class_methods($c) as $f) {
    if (strstr($f,"Action") != false) {
     array_push($functions,substr($f,0,strpos($f,"Action")));
    }
   }
   $c = strtolower(substr($c,0,strpos($c,"Controller")));

   if (strstr($c,"_") != false) {
      $db_structure[substr($c,0,strpos($c,"_"))][substr($c,strpos($c,"_") + 1)] = $functions;
   }else{
    $db_structure[$default_module][$c] = $functions;
   }
  }
    }     
}
Ivo Trompert
+7  A: 

This may be an old question but this is how I am doing this...

    $front = $this->getFrontController();
 $acl = array();

 foreach ($front->getControllerDirectory() as $module => $path) {

  foreach (scandir($path) as $file) {

   if (strstr($file, "Controller.php") !== false) {

    include_once $path . DIRECTORY_SEPARATOR . $file;

    foreach (get_declared_classes() as $class) {

     if (is_subclass_of($class, 'Zend_Controller_Action')) {

      $controller = strtolower(substr($class, 0, strpos($class, "Controller")));
      $actions = array();

      foreach (get_class_methods($class) as $action) {

       if (strstr($action, "Action") !== false) {
        $actions[] = $action;
       }
      }
     }
    }

    $acl[$module][$controller] = $actions;
   }
  }
 }
works like a charm!
smoove666