How to show the child nodes of drupal menu - php

In my admin, I have enabled the Show As Expanded tick, but the submenus do not show.
Here is my code in template.php:
$trail = menu_get_active_trail();
$leaf = $trail[1];
if(!empty($leaf['has_children'])) {
$parameters = array(
'active_trail' => array($leaf['plid']),
'only_active_trail' => FALSE,
'min_depth' => $leaf['depth'] + 1,
'max_depth' => $leaf['depth'] + 2,
'conditions' => array('plid' => $leaf['mlid']),
);
$children = menu_build_tree($leaf['menu_name'], $parameters);
$vars['submenu'] = menu_tree_output($children);
}
EDIT:
The right code is:
$trail = menu_get_active_trail();
$leaf = $trail[1];
if(!empty($leaf['has_children'])) {
$parameters = array(
'active_trail' => array($leaf['plid']),
'min_depth' => $leaf['depth'] + 1,
'max_depth' => $leaf['depth'] + 3,
'conditions' => array('p1' => $leaf['mlid']),
);
$children = menu_build_tree($leaf['menu_name'], $parameters);
$vars['submenu'] = menu_tree_output($children);
}
Thanks.

'conditions' => array('plid' => $leaf['mlid']), may be the problem. You should use p1, p2, ... to filter the parent

Related

Recursive function to build an array

Can anyone see why this isn't working?
private static function traverseTree($tree,$node)
{
$nodes = array();
$results = array();
$children = $tree->where('parent_id',$node->id)->where('type',UserGroup::DEPARTMENT_TYPE);
foreach($children as $child){
$nodes[] = $child->id;
$children = self::traverseTree($tree,$child);
$results = array_merge ($nodes,$children);
}
return $results;
}
I am stepping through it and I can see that the children are getting found but they are not included in the final results.
The final results just contain the top level.
Detail added:
$tree is a Laravel Collection, if I pipe this to an array I get:
array (
0 =>
array (
'id' => 21,
'name' => 'Top',
'type' => 1,
'parent_id' => 0,
),
1 =>
array (
'id' => 33,
'name' => 'UKDept',
'type' => 2,
'parent_id' => 21,
),
2 =>
array (
'id' => 36,
'name' => 'UKSubDept',
'parent_id' => 33,
),
3 =>
array (
'id' => 37,
'name' => 'USDept',
'type' => 2,
'parent_id' => 21,
),
)
$node:
array (
'id' => 21,
'name' => 'Top',
'type' => 1,
'parent_id' => 0,
),
The first call to populate $children gives:
array (
0 =>
array (
'id' => 33,
'name' => 'UKDept',
'type' => 2,
'parent_id' => 21,
),
1 =>
array (
'id' => 37,
'name' => 'USDept',
'type' => 2,
'parent_id' => 21,
),
)
Try taking the array outside the function.
$nodes = array();
$results = array();
private static function traverseTree($tree,$node)
{
$children = $tree->where('parent_id',$node->id)->where('type',UserGroup::DEPARTMENT_TYPE);
foreach($children as $child){
$nodes[] = $child->id;
$children = self::traverseTree($tree,$child);
$results = array_merge ($nodes,$children);
}
return $results;
}
It will not reinitialize them each time you call the function.Check if it works?
Looks like $child is an array but you are treating it like an object. Try changing:
$nodes[] = $child->id;
to
$nodes[] = $child['id'];
I have this working now, one stupid mistake I made was:
foreach($children as $child){
$nodes[] = $child->id;
$children = self::traverseTree($tree,$child);
$results = array_merge ($nodes,$children);
Using $children as a variable name twice!
This is the complete function:
private static function traverseTree($tree,$node)
{
$initialId = array();
$results = array();
$results[] = $node->id;
$children = $tree->where('parent_id',$node->id);
foreach($children as $node){
//if this is a department, then we need to go deeper
if($node->type == DEPARTMENT) {
$nodesChildren = self::traverseTree($tree, $node);
$results = array_merge ($results,$nodesChildren);
}else{
//just add this node to the results array
$results[] = $node->id;
}
}
return $results;
}

different colors for each records in laravel 5

I just want to add different colors for each records within foreach loop.I tried to add but I couldn't make it. Given below is my function.
public function service()
{
$result = Order::getService();
$out = array();
foreach($result as $row) {
$out[] = array(
'id' => $row['orderID'],
'class'=>'event-special',
'title' => $row['customer_name'].' - '.$row['order_number'],
'url' => URL::to('/').'/customer/'.$row['customerID'].'/order/'.$row['orderID'].'/edit',
'start' => strtotime($row['start_date']) . '000',
'end' => strtotime($row['end_date']) .'000'
);
}
return json_encode(array('success' => 1, 'result' => $out));
}
Can anyone please help me with this?
You could create yourself a set of event-special css classes i.e. event-special1, event-special2 ......
And then amend the code to add a number to your existing class
public function service()
{
$result = Order::getService();
$out = array();
$color = 1;
foreach($result as $row) {
$out[] = array(
'id' => $row['orderID'],
'class'=>'event-special' . $color,
'title' => $row['customer_name'].' - '.$row['order_number'],
'url' => URL::to('/').'/customer/'.$row['customerID'].'/order/'.$row['orderID'].'/edit',
'start' => strtotime($row['start_date']) . '000',
'end' => strtotime($row['end_date']) .'000'
);
$color++;
}
return json_encode(array('success' => 1, 'result' => $out));
}

PHP generate a tree by specified depth and rules

I'm stuck with a tree generating algorithm:
There's no parent-child params, only starting node value
Every node has 2 children (except the last children)
Array example:
$start = 1;
$depth = 3;
$s = array(
'name' => 1, // taken from $start
'children' => array(
array(
'name' => 2,
'children => array(
array( 'name' => 3 ), /* No children for last node $depth */
array( 'name' => 3 ), /* No children for last node $depth */
)
),
array(
'name' => 2,
'children => array(
// same as above
)
),
)
);
At this point I've come up with a very ugly function and would appreciate any help or suggestions to build more nice algorithm.
this should be helpful
function generateTree($depth, $level = 0)
{
$result = array();
if ($depth == $level) {
$result = array('name' => $level);
} else {
$result = array('name' => $level, 'children' => array(generateTree($depth, $level + 1), generateTree($depth, $level + 1)));
}
return $result;
}
print_r(generateTree(3, 1));

Know the element level in multidimensional array

Well, I am here again dealing with arrays in php. I need your hand to guide me in the right direction. Suppose the following array:
-fruits
--green
---limon
---mango
--red
---apple
-cars
--ferrari
---enzo
----blue
----black
---318
--lamborg
---spider
---gallardo
----gallado-96
-----blue
-----red
-----gallado-98
The - (hyphen) symbol only illustrates the deep level.
Well, I need to build another array (or whatever), because it should be printed as an HTML select as below:
-fruits
--green
---limon
---mango
--red
---apple
-cars
--ferrari
---enzo
----blue
----black
---318
--lamborg
---spider
---gallardo
----gallado-96
-----blue
-----red
-----gallado-98
Looks that for each level element, it should add a space, or hyphen to determinate that it belongs to a particular parent.
EDIT
The have provide an answer provideng my final code. The html select element will display each level as string (repeating the "-" at the begging of the text instead multi-level elements.
Here's a simple recursive function to build a select dropdown given an array. Unfortunately I'm not able to test it, but let me know if it works. Usage would be as follows:
function generateDropdown($array, $level = 1)
{
if ($level == 1)
{
$menu = '<select>';
}
foreach ($array as $a)
{
if (is_array($a))
{
$menu .= generateDropdown($a, $level+1);
}
else
{
$menu .= '<option>'.str_pad('',$level,'-').$a.'</option>'."\n";
}
}
if ($level == 1)
{
$menu = '</select>';
}
return $menu;
}
OK, I got it with the help of #jmgardhn2.
The data
This is my array:
$temp = array(
array(
'name' => 'fruits',
'sons' => array(
array(
'name' => 'green',
'sons' => array(
array(
'name' => 'mango'
),
array(
'name' => 'banana',
)
)
)
)
),
array(
'name' => 'cars',
'sons' => array(
array(
'name' => 'italy',
'sons' => array(
array(
'name' => 'ferrari',
'sons' => array(
array(
'name' => 'red'
),
array(
'name' => 'black'
),
)
),
array(
'name' => 'fiat',
)
)
),
array(
'name' => 'germany',
'sons' => array(
array(
'name' => 'bmw',
)
)
),
)
)
);
Recursive function
Now, the following function will provide an array with items like [level] => [name]:
function createSelect($tree, $items, $level)
{
foreach ($tree as $key)
{
if (is_array($key))
{
$items = createSelect($key, $items, $level + 1);
}
else
{
$items[] = array('level' => $level, 'text' => $key);
}
}
return $items;
}
Calling the funcion
Now, call the function as below:
$items = createSelect($temp, array(), 0);
Output
If you iterate the final $items array it will look like:
1fruits
2green
3mango
3banana
1cars
2italy
3ferrari
4red
4black
3fiat
2germany
3bmw

Array - custom foreach function

I have an array in this form:
$data = array(
array(
'id' => '1',
'bar' => 'foo',
'page' => 'front',
),
array(
'id' => 'bar',
'bar' => 'foo',
'page' => 'front',
),
array(
'id' => 'different,
'bar' => 'bar',
'page' => 'back',
),
array(
'id' => 'another',
'title' => __("Custom CSS",'solidstyle_admin'),
'foo' => 'bar',
'page' => 'back',
),
);
And I want to list all ids grouped by pages and saved as variables, so if the above array is an input then output will look just like this one:
$front = array('1','bar');
$back = array('different','another');
//$data['page'] = array($id1, $id2, (...));
I was trying to do that using foreach and this is how it starts:
function my_output() {
foreach($data as $something) {
$id = $something['id'];
$page = $something['page'];
}
return $output;
}
I was trying multiple foreach loops, and the best result I got was:
front = 1
front = bar
back = different
back = another
But I have absolutely no idea how to achieve what I want to do, I don't want anyone to do my job, just any hints? Keep in mind I'm a bit new to PHP and I don't know too much about arrays.
Thank you!
Sounds like you want:
$ids = array();
foreach ($data as $page) {
$pageName = $page['page'];
// create an empty array for your IDs
if (!isset($ids[$pageName])) {
$ids[$pageName] = array();
}
// add to the array of IDs
$ids[$pageName][] = $page['id'];
}
var_dump($ids); // array('front' => array('1', 'bar'), ...
Stick with the loop idea and do a conditional check.
function my_output() {
$front = array();
$back = array();
foreach($data as $something) {
$id = $something['id'];
$page = $something['page'];
if ($page === 'front') {
$front[] = $id;
} else if ($page === 'back') {
$back[] = $id;
}
}
// Not sure what you want to return here, but you could return an array of pages
$output = array('front' => $front, 'back' => $back);
return $output;
}
This will return something similar to:
$output = array(
'front' => array(
0 => '1',
1 => 'bar',
),
'back' => array(
0 => 'something',
1 => 'another',
)
)
Edit: Keep in mind that my answer only accounts for the two pages you listed in your answer. If you have more pages you can also use what cbuckley's answer showed.

Categories