weekly release 2.9dev
[moodle.git] / blocks / navigation / renderer.php
CommitLineData
3406acde 1<?php
31fde54f
AG
2// This file is part of Moodle - http://moodle.org/
3//
4// Moodle is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// Moodle is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
3406acde 16
31fde54f
AG
17/**
18 * Outputs the navigation tree.
19 *
5bcfd504 20 * @since Moodle 2.0
31fde54f
AG
21 * @package block_navigation
22 * @copyright 2009 Sam Hemelryk
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24 */
25
26/**
27 * Renderer for block navigation
28 *
29 * @package block_navigation
30 * @category navigation
31 * @copyright 2009 Sam Hemelryk
32 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
33 */
3406acde 34class block_navigation_renderer extends plugin_renderer_base {
31fde54f
AG
35 /**
36 * Returns the content of the navigation tree.
37 *
38 * @param global_navigation $navigation
39 * @param int $expansionlimit
40 * @param array $options
41 * @return string $content
42 */
480f906e 43 public function navigation_tree(global_navigation $navigation, $expansionlimit, array $options = array()) {
d2401694 44 $navigation->add_class('navigation_node');
480f906e 45 $content = $this->navigation_node(array($navigation), array('class'=>'block_tree list'), $expansionlimit, $options);
3406acde
SH
46 if (isset($navigation->id) && !is_numeric($navigation->id) && !empty($content)) {
47 $content = $this->output->box($content, 'block_tree_box', $navigation->id);
48 }
49 return $content;
50 }
31fde54f
AG
51 /**
52 * Produces a navigation node for the navigation tree
53 *
54 * @param array $items
55 * @param array $attrs
56 * @param int $expansionlimit
57 * @param array $options
58 * @param int $depth
59 * @return string
60 */
480f906e 61 protected function navigation_node($items, $attrs=array(), $expansionlimit=null, array $options = array(), $depth=1) {
3406acde
SH
62
63 // exit if empty, we don't want an empty ul element
64 if (count($items)==0) {
65 return '';
66 }
67
68 // array of nested li elements
69 $lis = array();
70 foreach ($items as $item) {
8e5c23e0 71 if (!$item->display && !$item->contains_active_node()) {
3406acde
SH
72 continue;
73 }
74 $content = $item->get_content();
75 $title = $item->get_title();
8e5c23e0
SH
76
77 $isexpandable = (empty($expansionlimit) || ($item->type > navigation_node::TYPE_ACTIVITY || $item->type < $expansionlimit) || ($item->contains_active_node() && $item->children->count() > 0));
78 $isbranch = $isexpandable && ($item->children->count() > 0 || ($item->has_children() && (isloggedin() || $item->type <= navigation_node::TYPE_CATEGORY)));
79
65dcd906
ARN
80 // Skip elements which have no content and no action - no point in showing them
81 if (!$isexpandable && empty($item->action)) {
82 continue;
83 }
84
13915f89 85 $hasicon = ((!$isbranch || $item->type == navigation_node::TYPE_ACTIVITY || $item->type == navigation_node::TYPE_RESOURCE) && $item->icon instanceof renderable);
7081714d
SH
86
87 if ($hasicon) {
3406acde 88 $icon = $this->output->render($item->icon);
13915f89
SH
89 } else {
90 $icon = '';
3406acde 91 }
13915f89 92 $content = $icon.$content; // use CSS for spacing of icons
3406acde
SH
93 if ($item->helpbutton !== null) {
94 $content = trim($item->helpbutton).html_writer::tag('span', $content, array('class'=>'clearhelpbutton'));
95 }
96
97 if ($content === '') {
98 continue;
99 }
100
480f906e
SH
101 $attributes = array();
102 if ($title !== '') {
103 $attributes['title'] = $title;
104 }
105 if ($item->hidden) {
106 $attributes['class'] = 'dimmed_text';
107 }
3b42c973
MG
108 if (is_string($item->action) || empty($item->action) ||
109 (($item->type === navigation_node::TYPE_CATEGORY || $item->type === navigation_node::TYPE_MY_CATEGORY) &&
110 empty($options['linkcategories']))) {
32561caf 111 $attributes['tabindex'] = '0'; //add tab support to span but still maintain character stream sequence.
480f906e
SH
112 $content = html_writer::tag('span', $content, $attributes);
113 } else if ($item->action instanceof action_link) {
3406acde
SH
114 //TODO: to be replaced with something else
115 $link = $item->action;
13915f89 116 $link->text = $icon.$link->text;
480f906e 117 $link->attributes = array_merge($link->attributes, $attributes);
3406acde 118 $content = $this->output->render($link);
480f906e 119 $linkrendered = true;
3406acde 120 } else if ($item->action instanceof moodle_url) {
3406acde 121 $content = html_writer::link($item->action, $content, $attributes);
3406acde
SH
122 }
123
124 // this applies to the li item which contains all child lists too
d2401694 125 $liclasses = array($item->get_css_type(), 'depth_'.$depth);
e5c46b54 126 $liexpandable = array();
3406acde
SH
127 if ($item->has_children() && (!$item->forceopen || $item->collapse)) {
128 $liclasses[] = 'collapsed';
129 }
7081714d
SH
130 if ($isbranch) {
131 $liclasses[] = 'contains_branch';
e5c46b54 132 $liexpandable = array('aria-expanded' => in_array('collapsed', $liclasses) ? "false" : "true");
7081714d
SH
133 } else if ($hasicon) {
134 $liclasses[] = 'item_with_icon';
135 }
3406acde
SH
136 if ($item->isactive === true) {
137 $liclasses[] = 'current_branch';
138 }
e5c46b54 139 $liattr = array('class' => join(' ',$liclasses)) + $liexpandable;
3406acde
SH
140 // class attribute on the div item which only contains the item content
141 $divclasses = array('tree_item');
7081714d 142 if ($isbranch) {
3406acde
SH
143 $divclasses[] = 'branch';
144 } else {
145 $divclasses[] = 'leaf';
146 }
7081714d
SH
147 if ($hasicon) {
148 $divclasses[] = 'hasicon';
149 }
3406acde
SH
150 if (!empty($item->classes) && count($item->classes)>0) {
151 $divclasses[] = join(' ', $item->classes);
152 }
153 $divattr = array('class'=>join(' ', $divclasses));
154 if (!empty($item->id)) {
155 $divattr['id'] = $item->id;
156 }
8e5c23e0
SH
157 $content = html_writer::tag('p', $content, $divattr);
158 if ($isexpandable) {
159 $content .= $this->navigation_node($item->children, array(), $expansionlimit, $options, $depth+1);
160 }
3406acde
SH
161 if (!empty($item->preceedwithhr) && $item->preceedwithhr===true) {
162 $content = html_writer::empty_tag('hr') . $content;
163 }
164 $content = html_writer::tag('li', $content, $liattr);
165 $lis[] = $content;
166 }
6c721bbf
SH
167
168 if (count($lis)) {
169 return html_writer::tag('ul', implode("\n", $lis), $attrs);
170 } else {
171 return '';
172 }
3406acde
SH
173 }
174
5dbfbacc 175}