Thursday, August 06th, 2009 | Author:

Hey Everyone,

So I went ahead and took up Mark Story on his challenge task and added the node deleting functionality that was missing from the original buildAcl action. I’m not sure if this was the best way to code it….but a few beers, and a lot of coding later I came up with this gem. Feel free to use this wherever you want.


/**
* Rebuild the Acl based on the current controllers in the application
*
* @return void
*/
function buildAcl() {
$log = array();
$methods = array();
$tempChildren = array();

$aco =& $this->Acl->Aco;
$root = $aco->node('controllers');
if (!$root) {
$aco->create(array('parent_id' => null, 'model' => null, 'alias' => 'controllers'));
$root = $aco->save();
$root['Aco']['id'] = $aco->id;
$log[] = 'Created Aco node for controllers';
} else {
$root = $root[0];
}

App::import('Core', 'File');
$Controllers = Configure::listObjects('controller');
$appIndex = array_search('App', $Controllers);
if ($appIndex !== false ) {
unset($Controllers[$appIndex]);
}
$baseMethods = get_class_methods('Controller');
$baseMethods[] = 'buildAcl';

// look at each controller in app/controllers
foreach ($Controllers as $ctrlName) {
App::import('Controller', $ctrlName);
$ctrlclass = $ctrlName . 'Controller';
$methods = get_class_methods($ctrlclass);

// find / make controller node
$controllerNode = $aco->node('controllers/'.$ctrlName);
if (!$controllerNode) {
$aco->create(array('parent_id' => $root['Aco']['id'], 'model' => null, 'alias' => $ctrlName));
$controllerNode = $aco->save();
$controllerNode['Aco']['id'] = $aco->id;
$log[] = 'Created Aco node for '.$ctrlName;
} else {
$controllerNode = $controllerNode[0];
// Get all the children of the current controller node
$children = $this->Acl->Aco->children($controllerNode['Aco']['id']);
$sizeChildren = sizeof($children);
}

//clean the methods. to remove those in Controller and private actions.
foreach ($methods as $k => $method) {
if (strpos($method, '_', 0) === 0) {
unset($methods[$k]);
continue;
}
if (in_array($method, $baseMethods)) {
unset($methods[$k]);
continue;
}
$methodNode = $aco->node('controllers/'.$ctrlName.'/'.$method);
if (!$methodNode) {
$aco->create(array('parent_id' => $controllerNode['Aco']['id'], 'model' => null, 'alias' => $method));
$methodNode = $aco->save();
$log[] = 'Created Aco node for '. $method;
}
}

$sizeMethods = sizeof($methods);

// More Aco's than methods
if($sizeChildren > $sizeMethods) {
foreach($children as $child) {
$tempChildren[] = $child['Aco']['alias'];
}
// Get the difference between Acos and methods
$diff = array_diff($tempChildren, $methods);
foreach($diff as $alias) {
$rogueAco = $aco->find('first',array(
'conditions' => array(
'alias' => $alias,
'parent_id' => $controllerNode['Aco']['id'],
)));
$aco->del($rogueAco['Aco']['id']);
$log[] = 'Deleted Aco node '.$controllerNode['Aco']['alias'].'/'.$alias;
}
}
}
debug($log);
}

Until next time, Laterz

Category: Development
You can follow any responses to this entry through the RSS 2.0 feed. Both comments and pings are currently closed.

3 Responses

  1. 1
    alexis 

    I tested your method. You forgot to initialize $sizeChildren.
    Before :

    if (!$controllerNode) {

    add :

    $sizeChildren = 0 ;

  2. Ah thanks for that….this was a laaaaaaaaaate night coding session!

  3. 3
    Jayakrishnan GK 

    thanks a lot mate….