2 // This file is part of Moodle - http://moodle.org/
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.
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.
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/>.
18 * Base renderer for outputting course formats.
21 * @copyright 2012 Dan Poltawski
22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
26 defined('MOODLE_INTERNAL') || die();
30 * This is a convenience renderer which can be used by section based formats
31 * to reduce code duplication. It is not necessary for all course formats to
32 * use this and its likely to change in future releases.
35 * @copyright 2012 Dan Poltawski
36 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
39 abstract class format_section_renderer_base extends plugin_renderer_base {
41 /** @var contains instance of core course renderer */
42 protected $courserenderer;
45 * Constructor method, calls the parent constructor
47 * @param moodle_page $page
48 * @param string $target one of rendering target constants
50 public function __construct(moodle_page $page, $target) {
51 parent::__construct($page, $target);
52 $this->courserenderer = $this->page->get_renderer('core', 'course');
56 * Generate the starting container html for a list of sections
57 * @return string HTML to output.
59 abstract protected function start_section_list();
62 * Generate the closing container html for a list of sections
63 * @return string HTML to output.
65 abstract protected function end_section_list();
68 * Generate the title for this section page
69 * @return string the page title
71 abstract protected function page_title();
74 * Generate the section title
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.
80 public function section_title($section, $course) {
81 $title = get_section_name($course, $section);
82 $url = course_get_url($course, $section->section, array('navigation' => true));
84 $title = html_writer::link($url, $title);
90 * Generate the content to displayed on the right part of a section
91 * before course modules are included
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.
98 protected function section_right_content($section, $course, $onsectionpage) {
99 $o = $this->output->spacer();
101 if ($section->section != 0) {
102 $controls = $this->section_edit_controls($course, $section, $onsectionpage);
103 if (!empty($controls)) {
104 $o = implode('<br />', $controls);
112 * Generate the content to displayed on the left part of a section
113 * before course modules are included
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.
120 protected function section_left_content($section, $course, $onsectionpage) {
121 $o = $this->output->spacer();
123 if ($section->section != 0) {
124 // Only in the non-general sections.
125 if (course_get_format($course)->is_section_current($section)) {
126 $o = get_accesshide(get_string('currentsection', 'format_'.$course->format));
134 * Generate the display of the header part of a section before
135 * course modules are included
137 * @param stdClass $section The course_section entry from DB
138 * @param stdClass $course The course entry from DB
139 * @param bool $onsectionpage true if being printed on a single-section page
140 * @param int $sectionreturn The section to return to after an action
141 * @return string HTML to output.
143 protected function section_header($section, $course, $onsectionpage, $sectionreturn=null) {
150 if ($section->section != 0) {
151 // Only in the non-general sections.
152 if (!$section->visible) {
153 $sectionstyle = ' hidden';
154 } else if (course_get_format($course)->is_section_current($section)) {
155 $sectionstyle = ' current';
159 $o.= html_writer::start_tag('li', array('id' => 'section-'.$section->section,
160 'class' => 'section main clearfix'.$sectionstyle, 'role'=>'region',
161 'aria-label'=> get_section_name($course, $section)));
163 $leftcontent = $this->section_left_content($section, $course, $onsectionpage);
164 $o.= html_writer::tag('div', $leftcontent, array('class' => 'left side'));
166 $rightcontent = $this->section_right_content($section, $course, $onsectionpage);
167 $o.= html_writer::tag('div', $rightcontent, array('class' => 'right side'));
168 $o.= html_writer::start_tag('div', array('class' => 'content'));
170 // When not on a section page, we display the section titles except the general section if null
171 $hasnamenotsecpg = (!$onsectionpage && ($section->section != 0 || !is_null($section->name)));
173 // When on a section page, we only display the general section title, if title is not the default one
174 $hasnamesecpg = ($onsectionpage && ($section->section == 0 && !is_null($section->name)));
176 $classes = ' accesshide';
177 if ($hasnamenotsecpg || $hasnamesecpg) {
180 $o.= $this->output->heading($this->section_title($section, $course), 3, 'sectionname' . $classes);
182 $o.= html_writer::start_tag('div', array('class' => 'summary'));
183 $o.= $this->format_summary_text($section);
185 $context = context_course::instance($course->id);
186 if ($PAGE->user_is_editing() && has_capability('moodle/course:update', $context)) {
187 $url = new moodle_url('/course/editsection.php', array('id'=>$section->id, 'sr'=>$sectionreturn));
188 $o.= html_writer::link($url,
189 html_writer::empty_tag('img', array('src' => $this->output->pix_url('t/edit'),
190 'class' => 'iconsmall edit', 'alt' => get_string('edit'))),
191 array('title' => get_string('editsummary')));
193 $o.= html_writer::end_tag('div');
195 $o .= $this->section_availability_message($section,
196 has_capability('moodle/course:viewhiddensections', $context));
202 * Generate the display of the footer part of a section
204 * @return string HTML to output.
206 protected function section_footer() {
207 $o = html_writer::end_tag('div');
208 $o.= html_writer::end_tag('li');
214 * Generate the edit controls of a section
216 * @param stdClass $course The course entry from DB
217 * @param stdClass $section The course_section entry from DB
218 * @param bool $onsectionpage true if being printed on a section page
219 * @return array of links with edit controls
221 protected function section_edit_controls($course, $section, $onsectionpage = false) {
224 if (!$PAGE->user_is_editing()) {
228 $coursecontext = context_course::instance($course->id);
230 if ($onsectionpage) {
231 $baseurl = course_get_url($course, $section->section);
233 $baseurl = course_get_url($course);
235 $baseurl->param('sesskey', sesskey());
239 $url = clone($baseurl);
240 if (has_capability('moodle/course:sectionvisibility', $coursecontext)) {
241 if ($section->visible) { // Show the hide/show eye.
242 $strhidefromothers = get_string('hidefromothers', 'format_'.$course->format);
243 $url->param('hide', $section->section);
244 $controls[] = html_writer::link($url,
245 html_writer::empty_tag('img', array('src' => $this->output->pix_url('i/hide'),
246 'class' => 'icon hide', 'alt' => $strhidefromothers)),
247 array('title' => $strhidefromothers, 'class' => 'editing_showhide'));
249 $strshowfromothers = get_string('showfromothers', 'format_'.$course->format);
250 $url->param('show', $section->section);
251 $controls[] = html_writer::link($url,
252 html_writer::empty_tag('img', array('src' => $this->output->pix_url('i/show'),
253 'class' => 'icon hide', 'alt' => $strshowfromothers)),
254 array('title' => $strshowfromothers, 'class' => 'editing_showhide'));
258 if (!$onsectionpage && has_capability('moodle/course:movesections', $coursecontext)) {
259 $url = clone($baseurl);
260 if ($section->section > 1) { // Add a arrow to move section up.
261 $url->param('section', $section->section);
262 $url->param('move', -1);
263 $strmoveup = get_string('moveup');
265 $controls[] = html_writer::link($url,
266 html_writer::empty_tag('img', array('src' => $this->output->pix_url('i/up'),
267 'class' => 'icon up', 'alt' => $strmoveup)),
268 array('title' => $strmoveup, 'class' => 'moveup'));
271 $url = clone($baseurl);
272 if ($section->section < $course->numsections) { // Add a arrow to move section down.
273 $url->param('section', $section->section);
274 $url->param('move', 1);
275 $strmovedown = get_string('movedown');
277 $controls[] = html_writer::link($url,
278 html_writer::empty_tag('img', array('src' => $this->output->pix_url('i/down'),
279 'class' => 'icon down', 'alt' => $strmovedown)),
280 array('title' => $strmovedown, 'class' => 'movedown'));
288 * Generate a summary of a section for display on the 'coruse index page'
290 * @param stdClass $section The course_section entry from DB
291 * @param stdClass $course The course entry from DB
292 * @param array $mods (argument not used)
293 * @return string HTML to output.
295 protected function section_summary($section, $course, $mods) {
296 $classattr = 'section main section-summary clearfix';
299 // If section is hidden then display grey section link
300 if (!$section->visible) {
301 $classattr .= ' hidden';
302 $linkclasses .= ' dimmed_text';
303 } else if (course_get_format($course)->is_section_current($section)) {
304 $classattr .= ' current';
307 $title = get_section_name($course, $section);
309 $o .= html_writer::start_tag('li', array('id' => 'section-'.$section->section,
310 'class' => $classattr, 'role'=>'region', 'aria-label'=> $title));
312 $o .= html_writer::tag('div', '', array('class' => 'left side'));
313 $o .= html_writer::tag('div', '', array('class' => 'right side'));
314 $o .= html_writer::start_tag('div', array('class' => 'content'));
316 if ($section->uservisible) {
317 $title = html_writer::tag('a', $title,
318 array('href' => course_get_url($course, $section->section), 'class' => $linkclasses));
320 $o .= $this->output->heading($title, 3, 'section-title');
322 $o.= html_writer::start_tag('div', array('class' => 'summarytext'));
323 $o.= $this->format_summary_text($section);
324 $o.= html_writer::end_tag('div');
325 $o.= $this->section_activity_summary($section, $course, null);
327 $context = context_course::instance($course->id);
328 $o .= $this->section_availability_message($section,
329 has_capability('moodle/course:viewhiddensections', $context));
331 $o .= html_writer::end_tag('div');
332 $o .= html_writer::end_tag('li');
338 * Generate a summary of the activites in a section
340 * @param stdClass $section The course_section entry from DB
341 * @param stdClass $course the course record from DB
342 * @param array $mods (argument not used)
343 * @return string HTML to output.
345 protected function section_activity_summary($section, $course, $mods) {
346 $modinfo = get_fast_modinfo($course);
347 if (empty($modinfo->sections[$section->section])) {
351 // Generate array with count of activities in this section:
352 $sectionmods = array();
355 $cancomplete = isloggedin() && !isguestuser();
356 $completioninfo = new completion_info($course);
357 foreach ($modinfo->sections[$section->section] as $cmid) {
358 $thismod = $modinfo->cms[$cmid];
360 if ($thismod->modname == 'label') {
361 // Labels are special (not interesting for students)!
365 if ($thismod->uservisible) {
366 if (isset($sectionmods[$thismod->modname])) {
367 $sectionmods[$thismod->modname]['name'] = $thismod->modplural;
368 $sectionmods[$thismod->modname]['count']++;
370 $sectionmods[$thismod->modname]['name'] = $thismod->modfullname;
371 $sectionmods[$thismod->modname]['count'] = 1;
373 if ($cancomplete && $completioninfo->is_enabled($thismod) != COMPLETION_TRACKING_NONE) {
375 $completiondata = $completioninfo->get_data($thismod, true);
376 if ($completiondata->completionstate == COMPLETION_COMPLETE) {
383 if (empty($sectionmods)) {
388 // Output section activities summary:
390 $o.= html_writer::start_tag('div', array('class' => 'section-summary-activities mdl-right'));
391 foreach ($sectionmods as $mod) {
392 $o.= html_writer::start_tag('span', array('class' => 'activity-count'));
393 $o.= $mod['name'].': '.$mod['count'];
394 $o.= html_writer::end_tag('span');
396 $o.= html_writer::end_tag('div');
398 // Output section completion data
401 $a->complete = $complete;
404 $o.= html_writer::start_tag('div', array('class' => 'section-summary-activities mdl-right'));
405 $o.= html_writer::tag('span', get_string('progresstotal', 'completion', $a), array('class' => 'activity-count'));
406 $o.= html_writer::end_tag('div');
413 * If section is not visible, display the message about that ('Not available
414 * until...', that sort of thing). Otherwise, returns blank.
416 * For users with the ability to view hidden sections, it shows the
417 * information even though you can view the section and also may include
418 * slightly fuller information (so that teachers can tell when sections
419 * are going to be unavailable etc). This logic is the same as for
422 * @param stdClass $section The course_section entry from DB
423 * @param bool $canviewhidden True if user can view hidden sections
424 * @return string HTML to output
426 protected function section_availability_message($section, $canviewhidden) {
429 if (!$section->uservisible) {
430 $o .= html_writer::start_tag('div', array('class' => 'availabilityinfo'));
431 // Note: We only get to this function if availableinfo is non-empty,
432 // so there is definitely something to print.
433 $o .= $section->availableinfo;
434 $o .= html_writer::end_tag('div');
435 } else if ($canviewhidden && !empty($CFG->enableavailability) && $section->visible) {
436 $ci = new condition_info_section($section);
437 $fullinfo = $ci->get_full_information();
439 $o .= html_writer::start_tag('div', array('class' => 'availabilityinfo'));
441 ($section->showavailability ? 'userrestriction_visible' : 'userrestriction_hidden'),
442 'condition', $fullinfo);
443 $o .= html_writer::end_tag('div');
450 * Show if something is on on the course clipboard (moving around)
452 * @param stdClass $course The course entry from DB
453 * @param int $sectionno The section number in the coruse which is being dsiplayed
454 * @return string HTML to output.
456 protected function course_activity_clipboard($course, $sectionno = null) {
460 // If currently moving a file then show the current clipboard.
461 if (ismoving($course->id)) {
462 $url = new moodle_url('/course/mod.php',
463 array('sesskey' => sesskey(),
464 'cancelcopy' => true,
469 $o.= html_writer::start_tag('div', array('class' => 'clipboard'));
470 $o.= strip_tags(get_string('activityclipboard', '', $USER->activitycopyname));
471 $o.= ' ('.html_writer::link($url, get_string('cancel')).')';
472 $o.= html_writer::end_tag('div');
479 * Generate next/previous section links for naviation
481 * @param stdClass $course The course entry from DB
482 * @param array $sections The course_sections entries from the DB
483 * @param int $sectionno The section number in the coruse which is being dsiplayed
484 * @return array associative array with previous and next section link
486 protected function get_nav_links($course, $sections, $sectionno) {
487 // FIXME: This is really evil and should by using the navigation API.
488 $course = course_get_format($course)->get_course();
489 $canviewhidden = has_capability('moodle/course:viewhiddensections', context_course::instance($course->id))
490 or !$course->hiddensections;
492 $links = array('previous' => '', 'next' => '');
493 $back = $sectionno - 1;
494 while ($back > 0 and empty($links['previous'])) {
495 if ($canviewhidden || $sections[$back]->uservisible) {
497 if (!$sections[$back]->visible) {
498 $params = array('class' => 'dimmed_text');
500 $previouslink = html_writer::tag('span', $this->output->larrow(), array('class' => 'larrow'));
501 $previouslink .= get_section_name($course, $sections[$back]);
502 $links['previous'] = html_writer::link(course_get_url($course, $back), $previouslink, $params);
507 $forward = $sectionno + 1;
508 while ($forward <= $course->numsections and empty($links['next'])) {
509 if ($canviewhidden || $sections[$forward]->uservisible) {
511 if (!$sections[$forward]->visible) {
512 $params = array('class' => 'dimmed_text');
514 $nextlink = get_section_name($course, $sections[$forward]);
515 $nextlink .= html_writer::tag('span', $this->output->rarrow(), array('class' => 'rarrow'));
516 $links['next'] = html_writer::link(course_get_url($course, $forward), $nextlink, $params);
525 * Generate the header html of a stealth section
527 * @param int $sectionno The section number in the coruse which is being dsiplayed
528 * @return string HTML to output.
530 protected function stealth_section_header($sectionno) {
532 $o.= html_writer::start_tag('li', array('id' => 'section-'.$sectionno, 'class' => 'section main clearfix orphaned hidden'));
533 $o.= html_writer::tag('div', '', array('class' => 'left side'));
534 $o.= html_writer::tag('div', '', array('class' => 'right side'));
535 $o.= html_writer::start_tag('div', array('class' => 'content'));
536 $o.= $this->output->heading(get_string('orphanedactivitiesinsectionno', '', $sectionno), 3, 'sectionname');
541 * Generate footer html of a stealth section
543 * @return string HTML to output.
545 protected function stealth_section_footer() {
546 $o = html_writer::end_tag('div');
547 $o.= html_writer::end_tag('li');
552 * Generate the html for a hidden section
554 * @param int $sectionno The section number in the coruse which is being dsiplayed
555 * @return string HTML to output.
557 protected function section_hidden($sectionno) {
559 $o.= html_writer::start_tag('li', array('id' => 'section-'.$sectionno, 'class' => 'section main clearfix hidden'));
560 $o.= html_writer::tag('div', '', array('class' => 'left side'));
561 $o.= html_writer::tag('div', '', array('class' => 'right side'));
562 $o.= html_writer::start_tag('div', array('class' => 'content'));
563 $o.= get_string('notavailable');
564 $o.= html_writer::end_tag('div');
565 $o.= html_writer::end_tag('li');
570 * Generate the html for the 'Jump to' menu on a single section page.
572 * @param stdClass $course The course entry from DB
573 * @param array $sections The course_sections entries from the DB
574 * @param $displaysection the current displayed section number.
576 * @return string HTML to output.
578 protected function section_nav_selection($course, $sections, $displaysection) {
581 $sectionmenu = array();
582 $sectionmenu[course_get_url($course)->out(false)] = get_string('maincoursepage');
583 $modinfo = get_fast_modinfo($course);
585 while ($section <= $course->numsections) {
586 $thissection = $modinfo->get_section_info($section);
587 $showsection = $thissection->uservisible or !$course->hiddensections;
588 if (($showsection) && ($section != $displaysection) && ($url = course_get_url($course, $section))) {
589 $sectionmenu[$url->out(false)] = get_section_name($course, $section);
594 $select = new url_select($sectionmenu, '', array('' => get_string('jumpto')));
595 $select->class = 'jumpmenu';
596 $select->formid = 'sectionmenu';
597 $o .= $this->output->render($select);
603 * Output the html for a single section page .
605 * @param stdClass $course The course entry from DB
606 * @param array $sections (argument not used)
607 * @param array $mods (argument not used)
608 * @param array $modnames (argument not used)
609 * @param array $modnamesused (argument not used)
610 * @param int $displaysection The section number in the course which is being displayed
612 public function print_single_section_page($course, $sections, $mods, $modnames, $modnamesused, $displaysection) {
615 $modinfo = get_fast_modinfo($course);
616 $course = course_get_format($course)->get_course();
618 // Can we view the section in question?
619 if (!($sectioninfo = $modinfo->get_section_info($displaysection))) {
620 // This section doesn't exist
621 print_error('unknowncoursesection', 'error', null, $course->fullname);
625 if (!$sectioninfo->uservisible) {
626 if (!$course->hiddensections) {
627 echo $this->start_section_list();
628 echo $this->section_hidden($displaysection);
629 echo $this->end_section_list();
631 // Can't view this section.
635 // Copy activity clipboard..
636 echo $this->course_activity_clipboard($course, $displaysection);
637 $thissection = $modinfo->get_section_info(0);
638 if ($thissection->summary or !empty($modinfo->sections[0]) or $PAGE->user_is_editing()) {
639 echo $this->start_section_list();
640 echo $this->section_header($thissection, $course, true, $displaysection);
641 echo $this->courserenderer->course_section_cm_list($course, $thissection, $displaysection);
642 echo $this->courserenderer->course_section_add_cm_control($course, 0, $displaysection);
643 echo $this->section_footer();
644 echo $this->end_section_list();
647 // Start single-section div
648 echo html_writer::start_tag('div', array('class' => 'single-section'));
650 // The requested section page.
651 $thissection = $modinfo->get_section_info($displaysection);
653 // Title with section navigation links.
654 $sectionnavlinks = $this->get_nav_links($course, $modinfo->get_section_info_all(), $displaysection);
656 $sectiontitle .= html_writer::start_tag('div', array('class' => 'section-navigation navigationtitle'));
657 $sectiontitle .= html_writer::tag('span', $sectionnavlinks['previous'], array('class' => 'mdl-left'));
658 $sectiontitle .= html_writer::tag('span', $sectionnavlinks['next'], array('class' => 'mdl-right'));
660 $classes = 'sectionname';
661 if (!$thissection->visible) {
662 $classes .= ' dimmed_text';
664 $sectiontitle .= $this->output->heading(get_section_name($course, $displaysection), 3, $classes);
666 $sectiontitle .= html_writer::end_tag('div');
669 // Now the list of sections..
670 echo $this->start_section_list();
672 echo $this->section_header($thissection, $course, true, $displaysection);
673 // Show completion help icon.
674 $completioninfo = new completion_info($course);
675 echo $completioninfo->display_help_icon();
677 echo $this->courserenderer->course_section_cm_list($course, $thissection, $displaysection);
678 echo $this->courserenderer->course_section_add_cm_control($course, $displaysection, $displaysection);
679 echo $this->section_footer();
680 echo $this->end_section_list();
682 // Display section bottom navigation.
683 $sectionbottomnav = '';
684 $sectionbottomnav .= html_writer::start_tag('div', array('class' => 'section-navigation mdl-bottom'));
685 $sectionbottomnav .= html_writer::tag('span', $sectionnavlinks['previous'], array('class' => 'mdl-left'));
686 $sectionbottomnav .= html_writer::tag('span', $sectionnavlinks['next'], array('class' => 'mdl-right'));
687 $sectionbottomnav .= html_writer::tag('div', $this->section_nav_selection($course, $sections, $displaysection),
688 array('class' => 'mdl-align'));
689 $sectionbottomnav .= html_writer::end_tag('div');
690 echo $sectionbottomnav;
692 // Close single-section div.
693 echo html_writer::end_tag('div');
697 * Output the html for a multiple section page
699 * @param stdClass $course The course entry from DB
700 * @param array $sections (argument not used)
701 * @param array $mods (argument not used)
702 * @param array $modnames (argument not used)
703 * @param array $modnamesused (argument not used)
705 public function print_multiple_section_page($course, $sections, $mods, $modnames, $modnamesused) {
708 $modinfo = get_fast_modinfo($course);
709 $course = course_get_format($course)->get_course();
711 $context = context_course::instance($course->id);
712 // Title with completion help icon.
713 $completioninfo = new completion_info($course);
714 echo $completioninfo->display_help_icon();
715 echo $this->output->heading($this->page_title(), 2, 'accesshide');
717 // Copy activity clipboard..
718 echo $this->course_activity_clipboard($course, 0);
720 // Now the list of sections..
721 echo $this->start_section_list();
723 foreach ($modinfo->get_section_info_all() as $section => $thissection) {
725 // 0-section is displayed a little different then the others
726 if ($thissection->summary or !empty($modinfo->sections[0]) or $PAGE->user_is_editing()) {
727 echo $this->section_header($thissection, $course, false, 0);
728 echo $this->courserenderer->course_section_cm_list($course, $thissection, 0);
729 echo $this->courserenderer->course_section_add_cm_control($course, 0, 0);
730 echo $this->section_footer();
734 if ($section > $course->numsections) {
735 // activities inside this section are 'orphaned', this section will be printed as 'stealth' below
738 // Show the section if the user is permitted to access it, OR if it's not available
739 // but showavailability is turned on (and there is some available info text).
740 $showsection = $thissection->uservisible ||
741 ($thissection->visible && !$thissection->available && $thissection->showavailability
742 && !empty($thissection->availableinfo));
744 // Hidden section message is overridden by 'unavailable' control
745 // (showavailability option).
746 if (!$course->hiddensections && $thissection->available) {
747 echo $this->section_hidden($section);
753 if (!$PAGE->user_is_editing() && $course->coursedisplay == COURSE_DISPLAY_MULTIPAGE) {
754 // Display section summary only.
755 echo $this->section_summary($thissection, $course, null);
757 echo $this->section_header($thissection, $course, false, 0);
758 if ($thissection->uservisible) {
759 echo $this->courserenderer->course_section_cm_list($course, $thissection, 0);
760 echo $this->courserenderer->course_section_add_cm_control($course, $section, 0);
762 echo $this->section_footer();
766 if ($PAGE->user_is_editing() and has_capability('moodle/course:update', $context)) {
767 // Print stealth sections if present.
768 foreach ($modinfo->get_section_info_all() as $section => $thissection) {
769 if ($section <= $course->numsections or empty($modinfo->sections[$section])) {
770 // this is not stealth section or it is empty
773 echo $this->stealth_section_header($section);
774 echo $this->courserenderer->course_section_cm_list($course, $thissection, 0);
775 echo $this->stealth_section_footer();
778 echo $this->end_section_list();
780 echo html_writer::start_tag('div', array('id' => 'changenumsections', 'class' => 'mdl-right'));
782 // Increase number of sections.
783 $straddsection = get_string('increasesections', 'moodle');
784 $url = new moodle_url('/course/changenumsections.php',
785 array('courseid' => $course->id,
787 'sesskey' => sesskey()));
788 $icon = $this->output->pix_icon('t/switch_plus', $straddsection);
789 echo html_writer::link($url, $icon.get_accesshide($straddsection), array('class' => 'increase-sections'));
791 if ($course->numsections > 0) {
792 // Reduce number of sections sections.
793 $strremovesection = get_string('reducesections', 'moodle');
794 $url = new moodle_url('/course/changenumsections.php',
795 array('courseid' => $course->id,
797 'sesskey' => sesskey()));
798 $icon = $this->output->pix_icon('t/switch_minus', $strremovesection);
799 echo html_writer::link($url, $icon.get_accesshide($strremovesection), array('class' => 'reduce-sections'));
802 echo html_writer::end_tag('div');
804 echo $this->end_section_list();
810 * Generate html for a section summary text
812 * @param stdClass $section The course_section entry from DB
813 * @return string HTML to output.
815 protected function format_summary_text($section) {
816 $context = context_course::instance($section->course);
817 $summarytext = file_rewrite_pluginfile_urls($section->summary, 'pluginfile.php',
818 $context->id, 'course', 'section', $section->id);
820 $options = new stdClass();
821 $options->noclean = true;
822 $options->overflowdiv = true;
823 return format_text($summarytext, $section->summaryformat, $options);
827 * Is the section passed in the current section?
829 * @deprecated since 2.4
830 * @see format_base::is_section_current()
832 * @param stdClass $course The course entry from DB
833 * @param stdClass $section The course_section entry from the DB
834 * @return bool true if the section is current
836 protected final function is_section_current($section, $course) {
837 debugging('Function format_section_renderer_base::is_section_current() is deprecated. '.
838 'Use course_get_format($course)->is_section_current($section) instead', DEBUG_DEVELOPER);
839 return course_get_format($course)->is_section_current($section);