Reputation: 1634
I want to use this Recursive Function to convert a php array into an array of parent and childs.
I have a this Cell:
class MenuCell extends Cell {
public function display($menu) {
$this->loadModel('Menus');
$menus = $this -> Menus -> find('all', [
'contain' => ['MenuItems']
]) -> where(['id' => $menu]);
$menus = $this -> buildTree($menus);
$this -> set(compact('menus'));
$this -> set('_serialize', ['menus']);
}
public function buildTree($ar, $pid = null) {
$op = array();
foreach($ar as $item) {
if ($item['parentId'] == $pid) {
$op[$item['id']] = array(
'name' => $item['name'],
'parentId' => $item['parentId']
);
// using recursion
$children = $this ->buildTree($ar, $item['id']);
if ($children) {
$op[$item['id']]['children'] = $children;
}
}
}
return $op;
}
}
However if i do the samething in controller, It works very fine. Any help would save my day.
Upvotes: 0
Views: 469
Reputation: 1413
If you want create dinamic menu try this:
First check your MenusTable, your table should have field with parent id (parent_id in my example) and create relationship belongsTo, hasMany
Menus Model
class MenusTable extends Table
{
public function initialize(array $config)
{
parent::initialize($config);
$this->table('menus');
$this->displayField('name');
$this->primaryKey('id');
$this->addBehavior('Timestamp');
$this->addBehavior('Tree');
$this->belongsTo('ParentMenus', [
'className' => 'Menus',
'foreignKey' => 'parent_id'
]);
$this->hasMany('ChildMenus', [
'className' => 'Menus',
'foreignKey' => 'parent_id'
]);
}
}
MenuCell
class MenuCell extends Cell {
public function display($menu) {
$this->loadModel('Menus');
$menus = $this->Menus->find('threaded')->where(['id'=>$menu])->toArray();
$menus = $this->buildTree($menus);
$this->set(compact('menus'));
$this->set('_serialize', ['menus']);
}
//Recursive function:
protected function buildTree($menus) {
foreach($menus as $element) {
if(!is_array($element)) {
$element = $element->toArray();
}
//Elements each menu array
$menu['name'] = $element['name'];
$menu['url'] = $element['url'];
foreach($element as $key => $value){
if(is_array($value)) {
$menu[$key] = $this->buildTree($value);
}
}
$resultMenu[] = $menu;
}
if(isset($resultMenu)) {
return $resultMenu;
}
}
}
Example Result:
[
(int) 0 => [
'name' => 'Level_1',
'url' => '/',
'children' => null
],
(int) 1 => [
'name' => 'Level_1',
'url' => '/',
'children' => [
(int) 0 => [
'name' => 'Level_1.1',
'url' => '/',
'children' => [
(int) 0 => [
'name' => 'Level_1.1.1',
'url' => '/',
'children' => null
],
(int) 1 => [
'name' => 'Level_1.1.1',
'url' => '/',
'children' => null
]
]
],
(int) 1 => [
'name' => 'Level_1.1',
'url' => '/',
'children' => null
]
]
],
(int) 2 => [
'name' => 'Level_1',
'url' => '/',
'children' => null
],
(int) 3 => [
'name' => 'Level_1',
'url' => '/',
'children' => null
]
]
Upvotes: 1