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
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;
}
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));
}
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));
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
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.