Merge branch 'MDL-40833-master' of git://github.com/phalacee/moodle
[moodle.git] / course / format / renderer.php
CommitLineData
1804b7c1
DP
1<?php
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/>.
16
17/**
18 * Base renderer for outputting course formats.
19 *
20 * @package core
21 * @copyright 2012 Dan Poltawski
22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23 * @since Moodle 2.3
24 */
25
26defined('MOODLE_INTERNAL') || die();
27
28
29/**
a8f02a34 30 * This is a convenience renderer which can be used by section based formats
3df72f8c 31 * to reduce code duplication. It is not necessary for all course formats to
a8f02a34 32 * use this and its likely to change in future releases.
1804b7c1
DP
33 *
34 * @package core
35 * @copyright 2012 Dan Poltawski
36 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
37 * @since Moodle 2.3
38 */
a8f02a34 39abstract class format_section_renderer_base extends plugin_renderer_base {
1804b7c1 40
9a36be73
MG
41 /** @var contains instance of core course renderer */
42 protected $courserenderer;
43
44 /**
45 * Constructor method, calls the parent constructor
46 *
47 * @param moodle_page $page
48 * @param string $target one of rendering target constants
49 */
50 public function __construct(moodle_page $page, $target) {
51 parent::__construct($page, $target);
52 $this->courserenderer = $this->page->get_renderer('core', 'course');
53 }
54
1804b7c1
DP
55 /**
56 * Generate the starting container html for a list of sections
57 * @return string HTML to output.
58 */
cbf44997 59 abstract protected function start_section_list();
1804b7c1
DP
60
61 /**
62 * Generate the closing container html for a list of sections
63 * @return string HTML to output.
64 */
cbf44997 65 abstract protected function end_section_list();
1804b7c1
DP
66
67 /**
68 * Generate the title for this section page
69 * @return string the page title
70 */
cbf44997 71 abstract protected function page_title();
1804b7c1 72
9f3015ec
RK
73 /**
74 * Generate the section title
75 *
76 * @param stdClass $section The course_section entry from DB
77 * @param stdClass $course The course entry from DB
78 * @return string HTML to output.
79 */
80 public function section_title($section, $course) {
81 $title = get_section_name($course, $section);
923451c5
MG
82 $url = course_get_url($course, $section->section, array('navigation' => true));
83 if ($url) {
84 $title = html_writer::link($url, $title);
9f3015ec
RK
85 }
86 return $title;
87 }
88
a830d866
DP
89 /**
90 * Generate the content to displayed on the right part of a section
a830d866 91 * before course modules are included
96e12851 92 *
a830d866
DP
93 * @param stdClass $section The course_section entry from DB
94 * @param stdClass $course The course entry from DB
95 * @param bool $onsectionpage true if being printed on a section page
96 * @return string HTML to output.
97 */
cbf44997 98 protected function section_right_content($section, $course, $onsectionpage) {
a830d866
DP
99 $o = $this->output->spacer();
100
101 if ($section->section != 0) {
102 $controls = $this->section_edit_controls($course, $section, $onsectionpage);
103 if (!empty($controls)) {
104 $o = implode('<br />', $controls);
105 }
106 }
107
108 return $o;
109 }
110
111 /**
112 * Generate the content to displayed on the left part of a section
a830d866 113 * before course modules are included
96e12851 114 *
a830d866
DP
115 * @param stdClass $section The course_section entry from DB
116 * @param stdClass $course The course entry from DB
117 * @param bool $onsectionpage true if being printed on a section page
118 * @return string HTML to output.
119 */
cbf44997 120 protected function section_left_content($section, $course, $onsectionpage) {
a830d866
DP
121 $o = $this->output->spacer();
122
123 if ($section->section != 0) {
124 // Only in the non-general sections.
081c8f7f 125 if (course_get_format($course)->is_section_current($section)) {
a830d866
DP
126 $o = get_accesshide(get_string('currentsection', 'format_'.$course->format));
127 }
128 }
129
130 return $o;
131 }
132
1804b7c1
DP
133 /**
134 * Generate the display of the header part of a section before
135 * course modules are included
136 *
137 * @param stdClass $section The course_section entry from DB
138 * @param stdClass $course The course entry from DB
9f3015ec 139 * @param bool $onsectionpage true if being printed on a single-section page
b8514b6a 140 * @param int $sectionreturn The section to return to after an action
1804b7c1
DP
141 * @return string HTML to output.
142 */
923451c5 143 protected function section_header($section, $course, $onsectionpage, $sectionreturn=null) {
1804b7c1
DP
144 global $PAGE;
145
146 $o = '';
147 $currenttext = '';
148 $sectionstyle = '';
1804b7c1 149
96e12851 150 if ($section->section != 0) {
1804b7c1
DP
151 // Only in the non-general sections.
152 if (!$section->visible) {
153 $sectionstyle = ' hidden';
081c8f7f 154 } else if (course_get_format($course)->is_section_current($section)) {
1804b7c1 155 $sectionstyle = ' current';
1804b7c1 156 }
1804b7c1
DP
157 }
158
159 $o.= html_writer::start_tag('li', array('id' => 'section-'.$section->section,
160 'class' => 'section main clearfix'.$sectionstyle));
a830d866
DP
161
162 $leftcontent = $this->section_left_content($section, $course, $onsectionpage);
1804b7c1 163 $o.= html_writer::tag('div', $leftcontent, array('class' => 'left side'));
a830d866
DP
164
165 $rightcontent = $this->section_right_content($section, $course, $onsectionpage);
1804b7c1
DP
166 $o.= html_writer::tag('div', $rightcontent, array('class' => 'right side'));
167 $o.= html_writer::start_tag('div', array('class' => 'content'));
168
5946d376
FM
169 // When not on a section page, we display the section titles except the general section if null
170 $hasnamenotsecpg = (!$onsectionpage && ($section->section != 0 || !is_null($section->name)));
171
172 // When on a section page, we only display the general section title, if title is not the default one
173 $hasnamesecpg = ($onsectionpage && ($section->section == 0 && !is_null($section->name)));
174
bbb483b2 175 $classes = ' accesshide';
5946d376 176 if ($hasnamenotsecpg || $hasnamesecpg) {
bbb483b2 177 $classes = '';
1804b7c1 178 }
bbb483b2 179 $o.= $this->output->heading($this->section_title($section, $course), 3, 'sectionname' . $classes);
1804b7c1
DP
180
181 $o.= html_writer::start_tag('div', array('class' => 'summary'));
7cb8bfdb 182 $o.= $this->format_summary_text($section);
1804b7c1 183
7cb8bfdb 184 $context = context_course::instance($course->id);
1804b7c1 185 if ($PAGE->user_is_editing() && has_capability('moodle/course:update', $context)) {
b8514b6a 186 $url = new moodle_url('/course/editsection.php', array('id'=>$section->id, 'sr'=>$sectionreturn));
1804b7c1 187 $o.= html_writer::link($url,
aad982aa 188 html_writer::empty_tag('img', array('src' => $this->output->pix_url('t/edit'),
38cdfab3 189 'class' => 'iconsmall edit', 'alt' => get_string('edit'))),
1804b7c1
DP
190 array('title' => get_string('editsummary')));
191 }
192 $o.= html_writer::end_tag('div');
193
e81da154 194 $o .= $this->section_availability_message($section,
195 has_capability('moodle/course:viewhiddensections', $context));
ce4dfd27 196
1804b7c1
DP
197 return $o;
198 }
199
200 /**
201 * Generate the display of the footer part of a section
202 *
203 * @return string HTML to output.
204 */
cbf44997 205 protected function section_footer() {
1804b7c1
DP
206 $o = html_writer::end_tag('div');
207 $o.= html_writer::end_tag('li');
208
209 return $o;
210 }
211
212 /**
213 * Generate the edit controls of a section
214 *
215 * @param stdClass $course The course entry from DB
216 * @param stdClass $section The course_section entry from DB
217 * @param bool $onsectionpage true if being printed on a section page
218 * @return array of links with edit controls
219 */
cbf44997 220 protected function section_edit_controls($course, $section, $onsectionpage = false) {
1804b7c1
DP
221 global $PAGE;
222
223 if (!$PAGE->user_is_editing()) {
224 return array();
225 }
226
643b1de8 227 $coursecontext = context_course::instance($course->id);
1804b7c1
DP
228
229 if ($onsectionpage) {
230 $baseurl = course_get_url($course, $section->section);
231 } else {
232 $baseurl = course_get_url($course);
233 }
234 $baseurl->param('sesskey', sesskey());
235
236 $controls = array();
237
238 $url = clone($baseurl);
643b1de8
FM
239 if (has_capability('moodle/course:sectionvisibility', $coursecontext)) {
240 if ($section->visible) { // Show the hide/show eye.
241 $strhidefromothers = get_string('hidefromothers', 'format_'.$course->format);
242 $url->param('hide', $section->section);
243 $controls[] = html_writer::link($url,
244 html_writer::empty_tag('img', array('src' => $this->output->pix_url('i/hide'),
245 'class' => 'icon hide', 'alt' => $strhidefromothers)),
246 array('title' => $strhidefromothers, 'class' => 'editing_showhide'));
247 } else {
248 $strshowfromothers = get_string('showfromothers', 'format_'.$course->format);
249 $url->param('show', $section->section);
250 $controls[] = html_writer::link($url,
251 html_writer::empty_tag('img', array('src' => $this->output->pix_url('i/show'),
252 'class' => 'icon hide', 'alt' => $strshowfromothers)),
253 array('title' => $strshowfromothers, 'class' => 'editing_showhide'));
254 }
1804b7c1
DP
255 }
256
ad778c84 257 if (!$onsectionpage && has_capability('moodle/course:movesections', $coursecontext)) {
1804b7c1
DP
258 $url = clone($baseurl);
259 if ($section->section > 1) { // Add a arrow to move section up.
260 $url->param('section', $section->section);
261 $url->param('move', -1);
262 $strmoveup = get_string('moveup');
263
264 $controls[] = html_writer::link($url,
06b7ed0a 265 html_writer::empty_tag('img', array('src' => $this->output->pix_url('i/up'),
1804b7c1
DP
266 'class' => 'icon up', 'alt' => $strmoveup)),
267 array('title' => $strmoveup, 'class' => 'moveup'));
268 }
269
270 $url = clone($baseurl);
271 if ($section->section < $course->numsections) { // Add a arrow to move section down.
272 $url->param('section', $section->section);
273 $url->param('move', 1);
274 $strmovedown = get_string('movedown');
275
276 $controls[] = html_writer::link($url,
06b7ed0a 277 html_writer::empty_tag('img', array('src' => $this->output->pix_url('i/down'),
1804b7c1
DP
278 'class' => 'icon down', 'alt' => $strmovedown)),
279 array('title' => $strmovedown, 'class' => 'movedown'));
280 }
281 }
282
283 return $controls;
284 }
285
286 /**
287 * Generate a summary of a section for display on the 'coruse index page'
288 *
289 * @param stdClass $section The course_section entry from DB
290 * @param stdClass $course The course entry from DB
eda43c7d 291 * @param array $mods (argument not used)
1804b7c1
DP
292 * @return string HTML to output.
293 */
d87debaa 294 protected function section_summary($section, $course, $mods) {
76055f5d
FM
295 $classattr = 'section main section-summary clearfix';
296 $linkclasses = '';
297
bcf7175f 298 // If section is hidden then display grey section link
76055f5d
FM
299 if (!$section->visible) {
300 $classattr .= ' hidden';
301 $linkclasses .= ' dimmed_text';
081c8f7f 302 } else if (course_get_format($course)->is_section_current($section)) {
76055f5d 303 $classattr .= ' current';
bcf7175f 304 }
1804b7c1
DP
305
306 $o = '';
76055f5d 307 $o .= html_writer::start_tag('li', array('id' => 'section-'.$section->section, 'class' => $classattr));
1804b7c1 308
76055f5d
FM
309 $o .= html_writer::tag('div', '', array('class' => 'left side'));
310 $o .= html_writer::tag('div', '', array('class' => 'right side'));
311 $o .= html_writer::start_tag('div', array('class' => 'content'));
312
e0735653 313 $title = get_section_name($course, $section);
bd43383d 314 if ($section->uservisible) {
e0735653 315 $title = html_writer::tag('a', $title,
bd43383d 316 array('href' => course_get_url($course, $section->section), 'class' => $linkclasses));
bd43383d 317 }
e0735653 318 $o .= $this->output->heading($title, 3, 'section-title');
1804b7c1
DP
319
320 $o.= html_writer::start_tag('div', array('class' => 'summarytext'));
7cb8bfdb 321 $o.= $this->format_summary_text($section);
1804b7c1 322 $o.= html_writer::end_tag('div');
eda43c7d 323 $o.= $this->section_activity_summary($section, $course, null);
ce4dfd27 324
e81da154 325 $context = context_course::instance($course->id);
326 $o .= $this->section_availability_message($section,
327 has_capability('moodle/course:viewhiddensections', $context));
ce4dfd27 328
76055f5d
FM
329 $o .= html_writer::end_tag('div');
330 $o .= html_writer::end_tag('li');
1804b7c1
DP
331
332 return $o;
333 }
334
d87debaa
DP
335 /**
336 * Generate a summary of the activites in a section
337 *
338 * @param stdClass $section The course_section entry from DB
7c05cd0e 339 * @param stdClass $course the course record from DB
eda43c7d 340 * @param array $mods (argument not used)
d87debaa
DP
341 * @return string HTML to output.
342 */
3f435f89 343 protected function section_activity_summary($section, $course, $mods) {
eda43c7d
MG
344 $modinfo = get_fast_modinfo($course);
345 if (empty($modinfo->sections[$section->section])) {
d87debaa
DP
346 return '';
347 }
348
349 // Generate array with count of activities in this section:
350 $sectionmods = array();
7c05cd0e
AA
351 $total = 0;
352 $complete = 0;
0e5533b6
SH
353 $cancomplete = isloggedin() && !isguestuser();
354 $completioninfo = new completion_info($course);
eda43c7d
MG
355 foreach ($modinfo->sections[$section->section] as $cmid) {
356 $thismod = $modinfo->cms[$cmid];
d87debaa 357
00c41b40
DP
358 if ($thismod->modname == 'label') {
359 // Labels are special (not interesting for students)!
360 continue;
361 }
362
d87debaa
DP
363 if ($thismod->uservisible) {
364 if (isset($sectionmods[$thismod->modname])) {
eda43c7d 365 $sectionmods[$thismod->modname]['name'] = $thismod->modplural;
d87debaa
DP
366 $sectionmods[$thismod->modname]['count']++;
367 } else {
eda43c7d 368 $sectionmods[$thismod->modname]['name'] = $thismod->modfullname;
d87debaa
DP
369 $sectionmods[$thismod->modname]['count'] = 1;
370 }
0e5533b6 371 if ($cancomplete && $completioninfo->is_enabled($thismod) != COMPLETION_TRACKING_NONE) {
7c05cd0e 372 $total++;
0e5533b6 373 $completiondata = $completioninfo->get_data($thismod, true);
7c05cd0e
AA
374 if ($completiondata->completionstate == COMPLETION_COMPLETE) {
375 $complete++;
376 }
377 }
d87debaa
DP
378 }
379 }
380
381 if (empty($sectionmods)) {
382 // No sections
383 return '';
384 }
385
386 // Output section activities summary:
387 $o = '';
388 $o.= html_writer::start_tag('div', array('class' => 'section-summary-activities mdl-right'));
389 foreach ($sectionmods as $mod) {
390 $o.= html_writer::start_tag('span', array('class' => 'activity-count'));
391 $o.= $mod['name'].': '.$mod['count'];
392 $o.= html_writer::end_tag('span');
393 }
dce49c1c 394 $o.= html_writer::end_tag('div');
7c05cd0e
AA
395
396 // Output section completion data
0e5533b6
SH
397 if ($total > 0) {
398 $a = new stdClass;
399 $a->complete = $complete;
400 $a->total = $total;
401
dce49c1c 402 $o.= html_writer::start_tag('div', array('class' => 'section-summary-activities mdl-right'));
0e5533b6 403 $o.= html_writer::tag('span', get_string('progresstotal', 'completion', $a), array('class' => 'activity-count'));
dce49c1c 404 $o.= html_writer::end_tag('div');
7c05cd0e 405 }
dce49c1c 406
d87debaa
DP
407 return $o;
408 }
409
ce4dfd27 410 /**
e81da154 411 * If section is not visible, display the message about that ('Not available
412 * until...', that sort of thing). Otherwise, returns blank.
413 *
414 * For users with the ability to view hidden sections, it shows the
415 * information even though you can view the section and also may include
416 * slightly fuller information (so that teachers can tell when sections
417 * are going to be unavailable etc). This logic is the same as for
418 * activities.
ce4dfd27 419 *
420 * @param stdClass $section The course_section entry from DB
e81da154 421 * @param bool $canviewhidden True if user can view hidden sections
ce4dfd27 422 * @return string HTML to output
423 */
e81da154 424 protected function section_availability_message($section, $canviewhidden) {
425 global $CFG;
ce4dfd27 426 $o = '';
e81da154 427 if (!$section->uservisible) {
ce4dfd27 428 $o .= html_writer::start_tag('div', array('class' => 'availabilityinfo'));
e81da154 429 // Note: We only get to this function if availableinfo is non-empty,
430 // so there is definitely something to print.
431 $o .= $section->availableinfo;
ce4dfd27 432 $o .= html_writer::end_tag('div');
e81da154 433 } else if ($canviewhidden && !empty($CFG->enableavailability) && $section->visible) {
434 $ci = new condition_info_section($section);
435 $fullinfo = $ci->get_full_information();
436 if ($fullinfo) {
437 $o .= html_writer::start_tag('div', array('class' => 'availabilityinfo'));
438 $o .= get_string(
439 ($section->showavailability ? 'userrestriction_visible' : 'userrestriction_hidden'),
440 'condition', $fullinfo);
441 $o .= html_writer::end_tag('div');
442 }
ce4dfd27 443 }
444 return $o;
445 }
446
1804b7c1
DP
447 /**
448 * Show if something is on on the course clipboard (moving around)
449 *
450 * @param stdClass $course The course entry from DB
451 * @param int $sectionno The section number in the coruse which is being dsiplayed
452 * @return string HTML to output.
453 */
923451c5 454 protected function course_activity_clipboard($course, $sectionno = null) {
1804b7c1
DP
455 global $USER;
456
457 $o = '';
458 // If currently moving a file then show the current clipboard.
459 if (ismoving($course->id)) {
460 $url = new moodle_url('/course/mod.php',
461 array('sesskey' => sesskey(),
462 'cancelcopy' => true,
463 'sr' => $sectionno,
464 )
465 );
466
76055f5d 467 $o.= html_writer::start_tag('div', array('class' => 'clipboard'));
1804b7c1
DP
468 $o.= strip_tags(get_string('activityclipboard', '', $USER->activitycopyname));
469 $o.= ' ('.html_writer::link($url, get_string('cancel')).')';
76055f5d 470 $o.= html_writer::end_tag('div');
1804b7c1
DP
471 }
472
473 return $o;
474 }
475
476 /**
477 * Generate next/previous section links for naviation
478 *
479 * @param stdClass $course The course entry from DB
480 * @param array $sections The course_sections entries from the DB
481 * @param int $sectionno The section number in the coruse which is being dsiplayed
36be7e14 482 * @return array associative array with previous and next section link
1804b7c1 483 */
cbf44997 484 protected function get_nav_links($course, $sections, $sectionno) {
1804b7c1 485 // FIXME: This is really evil and should by using the navigation API.
b5cf83f0 486 $course = course_get_format($course)->get_course();
1804b7c1
DP
487 $canviewhidden = has_capability('moodle/course:viewhiddensections', context_course::instance($course->id))
488 or !$course->hiddensections;
489
490 $links = array('previous' => '', 'next' => '');
491 $back = $sectionno - 1;
492 while ($back > 0 and empty($links['previous'])) {
569747fa 493 if ($canviewhidden || $sections[$back]->uservisible) {
bcf7175f
RT
494 $params = array();
495 if (!$sections[$back]->visible) {
496 $params = array('class' => 'dimmed_text');
497 }
36be7e14
RT
498 $previouslink = html_writer::tag('span', $this->output->larrow(), array('class' => 'larrow'));
499 $previouslink .= get_section_name($course, $sections[$back]);
bcf7175f 500 $links['previous'] = html_writer::link(course_get_url($course, $back), $previouslink, $params);
1804b7c1
DP
501 }
502 $back--;
503 }
504
505 $forward = $sectionno + 1;
506 while ($forward <= $course->numsections and empty($links['next'])) {
569747fa 507 if ($canviewhidden || $sections[$forward]->uservisible) {
bcf7175f
RT
508 $params = array();
509 if (!$sections[$forward]->visible) {
510 $params = array('class' => 'dimmed_text');
511 }
36be7e14
RT
512 $nextlink = get_section_name($course, $sections[$forward]);
513 $nextlink .= html_writer::tag('span', $this->output->rarrow(), array('class' => 'rarrow'));
bcf7175f 514 $links['next'] = html_writer::link(course_get_url($course, $forward), $nextlink, $params);
1804b7c1
DP
515 }
516 $forward++;
517 }
518
36be7e14 519 return $links;
1804b7c1
DP
520 }
521
522 /**
523 * Generate the header html of a stealth section
524 *
525 * @param int $sectionno The section number in the coruse which is being dsiplayed
526 * @return string HTML to output.
527 */
cbf44997 528 protected function stealth_section_header($sectionno) {
1804b7c1
DP
529 $o = '';
530 $o.= html_writer::start_tag('li', array('id' => 'section-'.$sectionno, 'class' => 'section main clearfix orphaned hidden'));
531 $o.= html_writer::tag('div', '', array('class' => 'left side'));
532 $o.= html_writer::tag('div', '', array('class' => 'right side'));
533 $o.= html_writer::start_tag('div', array('class' => 'content'));
534 $o.= $this->output->heading(get_string('orphanedactivities'), 3, 'sectionname');
535 return $o;
536 }
537
538 /**
539 * Generate footer html of a stealth section
540 *
541 * @return string HTML to output.
542 */
cbf44997 543 protected function stealth_section_footer() {
1804b7c1
DP
544 $o = html_writer::end_tag('div');
545 $o.= html_writer::end_tag('li');
546 return $o;
547 }
548
549 /**
550 * Generate the html for a hidden section
551 *
552 * @param int $sectionno The section number in the coruse which is being dsiplayed
553 * @return string HTML to output.
554 */
cbf44997 555 protected function section_hidden($sectionno) {
1804b7c1
DP
556 $o = '';
557 $o.= html_writer::start_tag('li', array('id' => 'section-'.$sectionno, 'class' => 'section main clearfix hidden'));
558 $o.= html_writer::tag('div', '', array('class' => 'left side'));
559 $o.= html_writer::tag('div', '', array('class' => 'right side'));
560 $o.= html_writer::start_tag('div', array('class' => 'content'));
561 $o.= get_string('notavailable');
562 $o.= html_writer::end_tag('div');
563 $o.= html_writer::end_tag('li');
564 return $o;
565 }
566
d46e26f6
GB
567 /**
568 * Generate the html for the 'Jump to' menu on a single section page.
569 *
570 * @param stdClass $course The course entry from DB
571 * @param array $sections The course_sections entries from the DB
572 * @param $displaysection the current displayed section number.
573 *
574 * @return string HTML to output.
575 */
576 protected function section_nav_selection($course, $sections, $displaysection) {
577 global $CFG;
578 $o = '';
579 $sectionmenu = array();
580 $sectionmenu[course_get_url($course)->out(false)] = get_string('maincoursepage');
581 $modinfo = get_fast_modinfo($course);
582 $section = 1;
583 while ($section <= $course->numsections) {
584 $thissection = $modinfo->get_section_info($section);
585 $showsection = $thissection->uservisible or !$course->hiddensections;
586 if (($showsection) && ($section != $displaysection) && ($url = course_get_url($course, $section))) {
587 $sectionmenu[$url->out(false)] = get_section_name($course, $section);
588 }
589 $section++;
590 }
591
592 $select = new url_select($sectionmenu, '', array('' => get_string('jumpto')));
593 $select->class = 'jumpmenu';
594 $select->formid = 'sectionmenu';
595 $o .= $this->output->render($select);
596
597 return $o;
598 }
599
1804b7c1
DP
600 /**
601 * Output the html for a single section page .
602 *
603 * @param stdClass $course The course entry from DB
eda43c7d
MG
604 * @param array $sections (argument not used)
605 * @param array $mods (argument not used)
606 * @param array $modnames (argument not used)
607 * @param array $modnamesused (argument not used)
1804b7c1
DP
608 * @param int $displaysection The section number in the course which is being displayed
609 */
610 public function print_single_section_page($course, $sections, $mods, $modnames, $modnamesused, $displaysection) {
611 global $PAGE;
612
eda43c7d 613 $modinfo = get_fast_modinfo($course);
b5cf83f0 614 $course = course_get_format($course)->get_course();
1804b7c1 615
eda43c7d
MG
616 // Can we view the section in question?
617 if (!($sectioninfo = $modinfo->get_section_info($displaysection))) {
0c053c53
ARN
618 // This section doesn't exist
619 print_error('unknowncoursesection', 'error', null, $course->fullname);
620 return;
621 }
622
eda43c7d 623 if (!$sectioninfo->uservisible) {
1804b7c1
DP
624 if (!$course->hiddensections) {
625 echo $this->start_section_list();
626 echo $this->section_hidden($displaysection);
627 echo $this->end_section_list();
1804b7c1
DP
628 }
629 // Can't view this section.
630 return;
631 }
632
76055f5d
FM
633 // Copy activity clipboard..
634 echo $this->course_activity_clipboard($course, $displaysection);
eda43c7d
MG
635 $thissection = $modinfo->get_section_info(0);
636 if ($thissection->summary or !empty($modinfo->sections[0]) or $PAGE->user_is_editing()) {
243b7003 637 echo $this->start_section_list();
b8514b6a 638 echo $this->section_header($thissection, $course, true, $displaysection);
9a36be73
MG
639 echo $this->courserenderer->course_section_cm_list($course, $thissection, $displaysection);
640 echo $this->courserenderer->course_section_add_cm_control($course, 0, $displaysection);
243b7003
DP
641 echo $this->section_footer();
642 echo $this->end_section_list();
643 }
644
c129f430
RT
645 // Start single-section div
646 echo html_writer::start_tag('div', array('class' => 'single-section'));
647
eda43c7d
MG
648 // The requested section page.
649 $thissection = $modinfo->get_section_info($displaysection);
650
36be7e14 651 // Title with section navigation links.
eda43c7d 652 $sectionnavlinks = $this->get_nav_links($course, $modinfo->get_section_info_all(), $displaysection);
36be7e14 653 $sectiontitle = '';
c129f430 654 $sectiontitle .= html_writer::start_tag('div', array('class' => 'section-navigation header headingblock'));
36be7e14
RT
655 $sectiontitle .= html_writer::tag('span', $sectionnavlinks['previous'], array('class' => 'mdl-left'));
656 $sectiontitle .= html_writer::tag('span', $sectionnavlinks['next'], array('class' => 'mdl-right'));
bcf7175f 657 // Title attributes
2e2d0f75 658 $classes = 'sectionname';
eda43c7d 659 if (!$thissection->visible) {
2e2d0f75 660 $classes .= ' dimmed_text';
bcf7175f 661 }
2e2d0f75
JF
662 $sectiontitle .= $this->output->heading(get_section_name($course, $displaysection), 3, $classes);
663
36be7e14
RT
664 $sectiontitle .= html_writer::end_tag('div');
665 echo $sectiontitle;
666
1804b7c1
DP
667 // Now the list of sections..
668 echo $this->start_section_list();
669
b8514b6a 670 echo $this->section_header($thissection, $course, true, $displaysection);
c129f430
RT
671 // Show completion help icon.
672 $completioninfo = new completion_info($course);
673 echo $completioninfo->display_help_icon();
674
9a36be73
MG
675 echo $this->courserenderer->course_section_cm_list($course, $thissection, $displaysection);
676 echo $this->courserenderer->course_section_add_cm_control($course, $displaysection, $displaysection);
1804b7c1 677 echo $this->section_footer();
1804b7c1 678 echo $this->end_section_list();
36be7e14
RT
679
680 // Display section bottom navigation.
36be7e14
RT
681 $sectionbottomnav = '';
682 $sectionbottomnav .= html_writer::start_tag('div', array('class' => 'section-navigation mdl-bottom'));
683 $sectionbottomnav .= html_writer::tag('span', $sectionnavlinks['previous'], array('class' => 'mdl-left'));
684 $sectionbottomnav .= html_writer::tag('span', $sectionnavlinks['next'], array('class' => 'mdl-right'));
d46e26f6
GB
685 $sectionbottomnav .= html_writer::tag('div', $this->section_nav_selection($course, $sections, $displaysection),
686 array('class' => 'mdl-align'));
36be7e14
RT
687 $sectionbottomnav .= html_writer::end_tag('div');
688 echo $sectionbottomnav;
c129f430 689
d46e26f6 690 // Close single-section div.
c129f430 691 echo html_writer::end_tag('div');
1804b7c1
DP
692 }
693
694 /**
695 * Output the html for a multiple section page
696 *
697 * @param stdClass $course The course entry from DB
eda43c7d
MG
698 * @param array $sections (argument not used)
699 * @param array $mods (argument not used)
700 * @param array $modnames (argument not used)
701 * @param array $modnamesused (argument not used)
1804b7c1
DP
702 */
703 public function print_multiple_section_page($course, $sections, $mods, $modnames, $modnamesused) {
704 global $PAGE;
705
eda43c7d 706 $modinfo = get_fast_modinfo($course);
b5cf83f0 707 $course = course_get_format($course)->get_course();
eda43c7d 708
1804b7c1
DP
709 $context = context_course::instance($course->id);
710 // Title with completion help icon.
711 $completioninfo = new completion_info($course);
712 echo $completioninfo->display_help_icon();
803e36e1 713 echo $this->output->heading($this->page_title(), 2, 'accesshide');
1804b7c1
DP
714
715 // Copy activity clipboard..
923451c5 716 echo $this->course_activity_clipboard($course, 0);
1804b7c1
DP
717
718 // Now the list of sections..
719 echo $this->start_section_list();
720
eda43c7d
MG
721 foreach ($modinfo->get_section_info_all() as $section => $thissection) {
722 if ($section == 0) {
723 // 0-section is displayed a little different then the others
724 if ($thissection->summary or !empty($modinfo->sections[0]) or $PAGE->user_is_editing()) {
725 echo $this->section_header($thissection, $course, false, 0);
31f47259
FM
726 echo $this->courserenderer->course_section_cm_list($course, $thissection, 0);
727 echo $this->courserenderer->course_section_add_cm_control($course, 0, 0);
eda43c7d
MG
728 echo $this->section_footer();
729 }
730 continue;
1804b7c1 731 }
eda43c7d
MG
732 if ($section > $course->numsections) {
733 // activities inside this section are 'orphaned', this section will be printed as 'stealth' below
734 continue;
1804b7c1 735 }
ce4dfd27 736 // Show the section if the user is permitted to access it, OR if it's not available
e81da154 737 // but showavailability is turned on (and there is some available info text).
ce4dfd27 738 $showsection = $thissection->uservisible ||
e81da154 739 ($thissection->visible && !$thissection->available && $thissection->showavailability
740 && !empty($thissection->availableinfo));
ce4dfd27 741 if (!$showsection) {
742 // Hidden section message is overridden by 'unavailable' control
743 // (showavailability option).
744 if (!$course->hiddensections && $thissection->available) {
1804b7c1
DP
745 echo $this->section_hidden($section);
746 }
747
1804b7c1
DP
748 continue;
749 }
750
751 if (!$PAGE->user_is_editing() && $course->coursedisplay == COURSE_DISPLAY_MULTIPAGE) {
752 // Display section summary only.
eda43c7d 753 echo $this->section_summary($thissection, $course, null);
1804b7c1 754 } else {
923451c5 755 echo $this->section_header($thissection, $course, false, 0);
ce4dfd27 756 if ($thissection->uservisible) {
31f47259
FM
757 echo $this->courserenderer->course_section_cm_list($course, $thissection, 0);
758 echo $this->courserenderer->course_section_add_cm_control($course, $section, 0);
1804b7c1
DP
759 }
760 echo $this->section_footer();
761 }
1804b7c1
DP
762 }
763
764 if ($PAGE->user_is_editing() and has_capability('moodle/course:update', $context)) {
765 // Print stealth sections if present.
eda43c7d
MG
766 foreach ($modinfo->get_section_info_all() as $section => $thissection) {
767 if ($section <= $course->numsections or empty($modinfo->sections[$section])) {
768 // this is not stealth section or it is empty
1804b7c1
DP
769 continue;
770 }
771 echo $this->stealth_section_header($section);
31f47259 772 echo $this->courserenderer->course_section_cm_list($course, $thissection, 0);
1804b7c1
DP
773 echo $this->stealth_section_footer();
774 }
1abf1253 775
575826c7
ARN
776 echo $this->end_section_list();
777
54495fe4 778 echo html_writer::start_tag('div', array('id' => 'changenumsections', 'class' => 'mdl-right'));
3a35a9ff
DP
779
780 // Increase number of sections.
781 $straddsection = get_string('increasesections', 'moodle');
782 $url = new moodle_url('/course/changenumsections.php',
783 array('courseid' => $course->id,
784 'increase' => true,
785 'sesskey' => sesskey()));
786 $icon = $this->output->pix_icon('t/switch_plus', $straddsection);
787 echo html_writer::link($url, $icon.get_accesshide($straddsection), array('class' => 'increase-sections'));
788
789 if ($course->numsections > 0) {
790 // Reduce number of sections sections.
791 $strremovesection = get_string('reducesections', 'moodle');
792 $url = new moodle_url('/course/changenumsections.php',
793 array('courseid' => $course->id,
794 'increase' => false,
795 'sesskey' => sesskey()));
796 $icon = $this->output->pix_icon('t/switch_minus', $strremovesection);
797 echo html_writer::link($url, $icon.get_accesshide($strremovesection), array('class' => 'reduce-sections'));
798 }
799
1abf1253 800 echo html_writer::end_tag('div');
575826c7
ARN
801 } else {
802 echo $this->end_section_list();
1804b7c1
DP
803 }
804
1804b7c1 805 }
7cb8bfdb
DP
806
807 /**
808 * Generate html for a section summary text
809 *
810 * @param stdClass $section The course_section entry from DB
811 * @return string HTML to output.
812 */
813 protected function format_summary_text($section) {
814 $context = context_course::instance($section->course);
815 $summarytext = file_rewrite_pluginfile_urls($section->summary, 'pluginfile.php',
816 $context->id, 'course', 'section', $section->id);
817
818 $options = new stdClass();
819 $options->noclean = true;
820 $options->overflowdiv = true;
821 return format_text($summarytext, $section->summaryformat, $options);
822 }
2ea6533a
DP
823
824 /**
081c8f7f
MG
825 * Is the section passed in the current section?
826 *
827 * @deprecated since 2.4
828 * @see format_base::is_section_current()
2ea6533a
DP
829 *
830 * @param stdClass $course The course entry from DB
831 * @param stdClass $section The course_section entry from the DB
832 * @return bool true if the section is current
833 */
081c8f7f
MG
834 protected final function is_section_current($section, $course) {
835 debugging('Function format_section_renderer_base::is_section_current() is deprecated. '.
836 'Use course_get_format($course)->is_section_current($section) instead', DEBUG_DEVELOPER);
837 return course_get_format($course)->is_section_current($section);
2ea6533a 838 }
1804b7c1 839}