Ok, here the full method, that works fine at all but…:
/**
*
* @desc recursive method that generates an Array with the complete RBAC Tree
* @param array $tree Part of or empty array as main RBAC Tree container
* @param integer $depth the Tree depth, which is needed only for the debug Renderer
* @return array with RBAC AuthItem Tree
*
*/
private function _buildItemTree($tree, $depth)
{
if(count($tree) < 1)
{
/*
* find the Top Level Items with its childs
*
* SELECT
* `t`.`parent` AS `t0_c0`,
* `t`.`parent` AS `t0_c0`,
* `t`.`child` AS `t0_c1`,
* `parents`.`parent` AS `t1_c0`,
* `parents`.`child` AS `t1_c1`,
* `items`.`name` AS `t2_c0`,
* `items`.`type` AS `t2_c1`,
* `items`.`description` AS `t2_c2`,
* `items`.`bizrule` AS `t2_c3`,
* `items`.`data` AS `t2_c4`
* FROM `AuthItemChild` `t`
* LEFT OUTER JOIN `AuthItemChild` `parents`
* ON (`parents`.`child`=`t`.`parent`)
* LEFT OUTER JOIN `AuthItem` `items`
* ON (`t`.`child`=`items`.`name`)
* WHERE (parents.parent IS NULL)
* ORDER BY t.parent
*/
$result = $this->findAll(array(
'with' => array('parents', 'childs'),
'condition' => 'parents.parent IS NULL',
'order' => 'parents.parent DESC'
)
);
$depth++;
$tree['depth'] = 0;
$tree['parent-name'] = null;
$tree['this-name'] = null;
$tree['this'] = null;
$tree['childs'] = array();
$modelAuthItem = new AuthItem();
foreach($result as $row)
{
$cnt = count($tree['childs']) - 1;
if(isset($tree['childs'][0]) && $tree['childs'][$cnt]['this-name'] == $row->parent)
{
// build second depth in existing first depth
$tree['childs'][$cnt]['childs'][] = $this->_buildItemTree(array(
'depth' => $depth + 1,
'parent-name' => $row->parent,
'this-name' => $row->childs->name,
'this' => $row->childs,
'childs' => array()), $depth + 1
);
}else{
// build new first depth and included second depth
$tree['childs'][] = array(
'depth' => $depth,
'parent-name' => null,
'this-name' => $row->parent,
'this' => $modelAuthItem->findByAttributes(array('name'=>$row->parent)),
'childs' => array($this->_buildItemTree(array(
'depth' => $depth + 1,
'parent-name' => $row->parent,
'this-name' => $row->childs->name,
'this' => $row->childs,
'childs' => array()), $depth + 1)
)
);
}
}
// add unbound items
$model = new AuthItem();
$unboundItems = $model->findUnboundItems();
foreach($unboundItems as $item)
{
$child = array(
'depth' => 1,
'parent-name' => null,
'this-name' => $item->name,
'this' => $item,
'childs' => array(),
);
array_unshift($tree['childs'], $child);
}
return $tree;
}else{
/* find Childs from current parent with its AuthItem object
* SELECT
* `t`.`parent` AS `t0_c0`,
* `t`.`child` AS `t0_c1`,
* `childs`.`name` AS `t1_c0`,
* `childs`.`type` AS `t1_c1`,
* `childs`.`description` AS `t1_c2`,
* `childs`.`bizrule` AS `t1_c3`,
* `childs`.`data` AS `t1_c4`
* FROM `AuthItemChild` `t`
* LEFT OUTER JOIN `AuthItem` `childs`
* ON (`t`.`child`=`childs`.`name`)
* WHERE (`t`.`parent`=:yp0)
* ORDER BY childs.name
*/
$result = $this->findAllByAttributes(
array('parent'=>$tree['this']->name), // <--- that is secure but works only on main Table and not on joined Tables
array(
'with' => 'childs',
'order' => 'childs.name',
)
);
/*
$result = $this->findAll(
array(
'with' => 'childs',
'condition' => "t.parent' = '{$tree['this']->name}'",// <--- works on joined Tables but is unsecure and dont works with values like "'´`
'order' => 'childs.name',
)
);
*/
$depth++;
if (count($result) > 0)
{
foreach($result as $row){
$tree['childs'][] = $this->_buildItemTree(
array(
'depth' => $depth,
'parent-name' => $row->parent,
'this-name' => $row->childs->name,
'this' => $row->childs,
'childs' => array()
), $depth
);
}
}
return $tree;
}
The problem is the ‘condition’ with findAll method where the condition works fine on joined tables
findAll...
'condition' => "t.parent = $userInput"
...
Bit if $userInput contains chars like ´`" or ’ this fine example crashes.
Iif I Use findAllByAttributes like this:
$result = $this->findAllByAttributes(
array('t.parent' => $userInput),
array(
'with' => array('parents', 'childs'),
'order' => 'parents.parent DESC'
)
);
there are no Problems with special chars like ´`" or ’
but the condition don’t works on joined Tables
So I can use a unsecure version (findAll)that provides conditions in joined tables (I don’t want that)
or I can use a secure version (findAllByAttributes) that do NOT provide conditions in joined tables (I do not want that too)
But I want a secure version that provides condtions in joined tables and I don’t know how to do that!