e8d1418b42c99cb7ca19c2e85dfe06da18ea02de
[moodle.git] / course / format / renderer.php
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/>.
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  */
26 defined('MOODLE_INTERNAL') || die();
29 /**
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.
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  */
39 abstract class format_section_renderer_base extends plugin_renderer_base {
41     /**
42      * Generate the starting container html for a list of sections
43      * @return string HTML to output.
44      */
45     abstract protected function start_section_list();
47     /**
48      * Generate the closing container html for a list of sections
49      * @return string HTML to output.
50      */
51     abstract protected function end_section_list();
53     /**
54      * Generate the title for this section page
55      * @return string the page title
56      */
57     abstract protected function page_title();
59     /**
60      * Generate the section title
61      *
62      * @param stdClass $section The course_section entry from DB
63      * @param stdClass $course The course entry from DB
64      * @return string HTML to output.
65      */
66     public function section_title($section, $course) {
67         $title = get_section_name($course, $section);
68         if ($section->section != 0 && $course->coursedisplay == COURSE_DISPLAY_MULTIPAGE) {
69             $title = html_writer::link(course_get_url($course, $section->section), $title);
70         }
71         return $title;
72     }
74     /**
75      * Generate the content to displayed on the right part of a section
76      * before course modules are included
77      *
78      * @param stdClass $section The course_section entry from DB
79      * @param stdClass $course The course entry from DB
80      * @param bool $onsectionpage true if being printed on a section page
81      * @return string HTML to output.
82      */
83     protected function section_right_content($section, $course, $onsectionpage) {
84         $o = $this->output->spacer();
86         if ($section->section != 0) {
87             $controls = $this->section_edit_controls($course, $section, $onsectionpage);
88             if (!empty($controls)) {
89                 $o = implode('<br />', $controls);
90             }
91         }
93         return $o;
94     }
96     /**
97      * Generate the content to displayed on the left part of a section
98      * before course modules are included
99      *
100      * @param stdClass $section The course_section entry from DB
101      * @param stdClass $course The course entry from DB
102      * @param bool $onsectionpage true if being printed on a section page
103      * @return string HTML to output.
104      */
105     protected function section_left_content($section, $course, $onsectionpage) {
106         $o = $this->output->spacer();
108         if ($section->section != 0) {
109             // Only in the non-general sections.
110             if ($this->is_section_current($section, $course)) {
111                 $o = get_accesshide(get_string('currentsection', 'format_'.$course->format));
112             }
113         }
115         return $o;
116     }
118     /**
119      * Generate the display of the header part of a section before
120      * course modules are included
121      *
122      * @param stdClass $section The course_section entry from DB
123      * @param stdClass $course The course entry from DB
124      * @param bool $onsectionpage true if being printed on a single-section page
125      * @return string HTML to output.
126      */
127     protected function section_header($section, $course, $onsectionpage) {
128         global $PAGE;
130         $o = '';
131         $currenttext = '';
132         $sectionstyle = '';
134         if ($section->section != 0) {
135             // Only in the non-general sections.
136             if (!$section->visible) {
137                 $sectionstyle = ' hidden';
138             } else if ($this->is_section_current($section, $course)) {
139                 $sectionstyle = ' current';
140             }
141         }
143         $o.= html_writer::start_tag('li', array('id' => 'section-'.$section->section,
144             'class' => 'section main clearfix'.$sectionstyle));
146         $leftcontent = $this->section_left_content($section, $course, $onsectionpage);
147         $o.= html_writer::tag('div', $leftcontent, array('class' => 'left side'));
149         $rightcontent = $this->section_right_content($section, $course, $onsectionpage);
150         $o.= html_writer::tag('div', $rightcontent, array('class' => 'right side'));
151         $o.= html_writer::start_tag('div', array('class' => 'content'));
153         if (!$onsectionpage) {
154             $o.= $this->output->heading($this->section_title($section, $course), 3, 'sectionname');
155         }
157         $o.= html_writer::start_tag('div', array('class' => 'summary'));
158         $o.= $this->format_summary_text($section);
160         $context = context_course::instance($course->id);
161         if ($PAGE->user_is_editing() && has_capability('moodle/course:update', $context)) {
162             $url = new moodle_url('/course/editsection.php', array('id'=>$section->id));
164             if ($onsectionpage) {
165                 $url->param('sectionreturn', 1);
166             }
168             $o.= html_writer::link($url,
169                 html_writer::empty_tag('img', array('src' => $this->output->pix_url('t/edit'), 'class' => 'iconsmall edit')),
170                 array('title' => get_string('editsummary')));
171         }
172         $o.= html_writer::end_tag('div');
174         $o .= $this->section_availability_message($section);
176         return $o;
177     }
179     /**
180      * Generate the display of the footer part of a section
181      *
182      * @return string HTML to output.
183      */
184     protected function section_footer() {
185         $o = html_writer::end_tag('div');
186         $o.= html_writer::end_tag('li');
188         return $o;
189     }
191     /**
192      * Generate the edit controls of a section
193      *
194      * @param stdClass $course The course entry from DB
195      * @param stdClass $section The course_section entry from DB
196      * @param bool $onsectionpage true if being printed on a section page
197      * @return array of links with edit controls
198      */
199     protected function section_edit_controls($course, $section, $onsectionpage = false) {
200         global $PAGE;
202         if (!$PAGE->user_is_editing()) {
203             return array();
204         }
206         if (!has_capability('moodle/course:update', context_course::instance($course->id))) {
207             return array();
208         }
210         if ($onsectionpage) {
211             $baseurl = course_get_url($course, $section->section);
212         } else {
213             $baseurl = course_get_url($course);
214         }
215         $baseurl->param('sesskey', sesskey());
217         $controls = array();
219         $url = clone($baseurl);
220         if ($section->visible) { // Show the hide/show eye.
221             $strhidefromothers = get_string('hidefromothers', 'format_'.$course->format);
222             $url->param('hide', $section->section);
223             $controls[] = html_writer::link($url,
224                 html_writer::empty_tag('img', array('src' => $this->output->pix_url('i/hide'),
225                 'class' => 'icon hide', 'alt' => $strhidefromothers)),
226                 array('title' => $strhidefromothers, 'class' => 'editing_showhide'));
227         } else {
228             $strshowfromothers = get_string('showfromothers', 'format_'.$course->format);
229             $url->param('show',  $section->section);
230             $controls[] = html_writer::link($url,
231                 html_writer::empty_tag('img', array('src' => $this->output->pix_url('i/show'),
232                 'class' => 'icon hide', 'alt' => $strshowfromothers)),
233                 array('title' => $strshowfromothers, 'class' => 'editing_showhide'));
234         }
236         if (!$onsectionpage) {
237             $url = clone($baseurl);
238             if ($section->section > 1) { // Add a arrow to move section up.
239                 $url->param('section', $section->section);
240                 $url->param('move', -1);
241                 $strmoveup = get_string('moveup');
243                 $controls[] = html_writer::link($url,
244                     html_writer::empty_tag('img', array('src' => $this->output->pix_url('t/up'),
245                     'class' => 'icon up', 'alt' => $strmoveup)),
246                     array('title' => $strmoveup, 'class' => 'moveup'));
247             }
249             $url = clone($baseurl);
250             if ($section->section < $course->numsections) { // Add a arrow to move section down.
251                 $url->param('section', $section->section);
252                 $url->param('move', 1);
253                 $strmovedown =  get_string('movedown');
255                 $controls[] = html_writer::link($url,
256                     html_writer::empty_tag('img', array('src' => $this->output->pix_url('t/down'),
257                     'class' => 'icon down', 'alt' => $strmovedown)),
258                     array('title' => $strmovedown, 'class' => 'movedown'));
259             }
260         }
262         return $controls;
263     }
265     /**
266      * Generate a summary of a section for display on the 'coruse index page'
267      *
268      * @param stdClass $section The course_section entry from DB
269      * @param stdClass $course The course entry from DB
270      * @param array    $mods course modules indexed by id (from get_all_mods)
271      * @return string HTML to output.
272      */
273     protected function section_summary($section, $course, $mods) {
274         // If section is hidden then display grey section link
275         $classattr = 'section-summary clearfix';
276         If (!$section->visible) {
277             $classattr .= ' dimmed_text';
278         }
280         $o = '';
281         $o.= html_writer::start_tag('li', array('id' => 'section-'.$section->section,
282             'class' => $classattr));
284         $title = get_section_name($course, $section);
285         $o.= html_writer::start_tag('a', array('href' => course_get_url($course, $section->section)));
286         $o.= $this->output->heading($title, 3, 'header section-title');
287         $o.= html_writer::end_tag('a');
289         $o.= html_writer::start_tag('div', array('class' => 'summarytext'));
290         $o.= $this->format_summary_text($section);
291         $o.= html_writer::end_tag('div');
292         $o.= $this->section_activity_summary($section, $mods);
294         $o.= $this->section_availability_message($section);
296         $o.= html_writer::end_tag('li');
298         return $o;
299     }
301     /**
302      * Generate a summary of the activites in a section
303      *
304      * @param stdClass $section The course_section entry from DB
305      * @param array    $mods course modules indexed by id (from get_all_mods)
306      * @return string HTML to output.
307      */
308     private function section_activity_summary($section, $mods) {
309         if (empty($section->sequence)) {
310             return '';
311         }
313         // Generate array with count of activities in this section:
314         $sectionmods = array();
315         $modsequence = explode(',', $section->sequence);
316         foreach ($modsequence as $cmid) {
317             $thismod = $mods[$cmid];
319             if ($thismod->uservisible) {
320                 if (isset($sectionmods[$thismod->modname])) {
321                     $sectionmods[$thismod->modname]['count']++;
322                 } else {
323                     $sectionmods[$thismod->modname]['name'] = $thismod->modplural;
324                     $sectionmods[$thismod->modname]['count'] = 1;
325                 }
326             }
327         }
329         if (empty($sectionmods)) {
330             // No sections
331             return '';
332         }
334         // Output section activities summary:
335         $o = '';
336         $o.= html_writer::start_tag('div', array('class' => 'section-summary-activities mdl-right'));
337         foreach ($sectionmods as $mod) {
338             $o.= html_writer::start_tag('span', array('class' => 'activity-count'));
339             $o.= $mod['name'].': '.$mod['count'];
340             $o.= html_writer::end_tag('span');
341         }
342         $o.= html_writer::end_tag('div');
343         return $o;
344     }
346     /**
347      * If section is not visible to current user, display the message about that
348      * ('Not available until...', that sort of thing). Otherwise, returns blank.
349      *
350      * @param stdClass $section The course_section entry from DB
351      * @return string HTML to output
352      */
353     protected function section_availability_message($section) {
354         $o = '';
355         if (!$section->uservisible || $section->availableinfo) {
356             $o .= html_writer::start_tag('div', array('class' => 'availabilityinfo'));
357             if (!empty($section->availableinfo)) {
358                 $o .= $section->availableinfo;
359             } else {
360                 $o .= get_string('notavailable');
361             }
362             $o .= html_writer::end_tag('div');
363         }
364         return $o;
365     }
367     /**
368      * Show if something is on on the course clipboard (moving around)
369      *
370      * @param stdClass $course The course entry from DB
371      * @param int $sectionno The section number in the coruse which is being dsiplayed
372      * @return string HTML to output.
373      */
374     protected function course_activity_clipboard($course, $sectionno = 0) {
375         global $USER;
377         $o = '';
378         // If currently moving a file then show the current clipboard.
379         if (ismoving($course->id)) {
380             $url = new moodle_url('/course/mod.php',
381                 array('sesskey' => sesskey(),
382                       'cancelcopy' => true,
383                       'sr' => $sectionno,
384                 )
385             );
387             $strcancel= get_string('cancel');
389             $o.= html_writer::start_tag('li', array('class' => 'clipboard'));
390             $o.= strip_tags(get_string('activityclipboard', '', $USER->activitycopyname));
391             $o.= ' ('.html_writer::link($url, get_string('cancel')).')';
392             $o.= html_writer::end_tag('li');
393         }
395         return $o;
396     }
398     /**
399      * Generate next/previous section links for naviation
400      *
401      * @param stdClass $course The course entry from DB
402      * @param array $sections The course_sections entries from the DB
403      * @param int $sectionno The section number in the coruse which is being dsiplayed
404      * @return array associative array with previous and next section link
405      */
406     protected function get_nav_links($course, $sections, $sectionno) {
407         // FIXME: This is really evil and should by using the navigation API.
408         $canviewhidden = has_capability('moodle/course:viewhiddensections', context_course::instance($course->id))
409             or !$course->hiddensections;
411         $links = array('previous' => '', 'next' => '');
412         $back = $sectionno - 1;
413         while ($back > 0 and empty($links['previous'])) {
414             if ($canviewhidden || $sections[$back]->visible) {
415                 $params = array();
416                 if (!$sections[$back]->visible) {
417                     $params = array('class' => 'dimmed_text');
418                 }
419                 $previouslink = html_writer::tag('span', $this->output->larrow(), array('class' => 'larrow'));
420                 $previouslink .= get_section_name($course, $sections[$back]);
421                 $links['previous'] = html_writer::link(course_get_url($course, $back), $previouslink, $params);
422             }
423             $back--;
424         }
426         $forward = $sectionno + 1;
427         while ($forward <= $course->numsections and empty($links['next'])) {
428             if ($canviewhidden || $sections[$forward]->visible) {
429                 $params = array();
430                 if (!$sections[$forward]->visible) {
431                     $params = array('class' => 'dimmed_text');
432                 }
433                 $nextlink = get_section_name($course, $sections[$forward]);
434                 $nextlink .= html_writer::tag('span', $this->output->rarrow(), array('class' => 'rarrow'));
435                 $links['next'] = html_writer::link(course_get_url($course, $forward), $nextlink, $params);
436             }
437             $forward++;
438         }
440         return $links;
441     }
443     /**
444      * Generate the header html of a stealth section
445      *
446      * @param int $sectionno The section number in the coruse which is being dsiplayed
447      * @return string HTML to output.
448      */
449     protected function stealth_section_header($sectionno) {
450         $o = '';
451         $o.= html_writer::start_tag('li', array('id' => 'section-'.$sectionno, 'class' => 'section main clearfix orphaned hidden'));
452         $o.= html_writer::tag('div', '', array('class' => 'left side'));
453         $o.= html_writer::tag('div', '', array('class' => 'right side'));
454         $o.= html_writer::start_tag('div', array('class' => 'content'));
455         $o.= $this->output->heading(get_string('orphanedactivities'), 3, 'sectionname');
456         return $o;
457     }
459     /**
460      * Generate footer html of a stealth section
461      *
462      * @return string HTML to output.
463      */
464     protected function stealth_section_footer() {
465         $o = html_writer::end_tag('div');
466         $o.= html_writer::end_tag('li');
467         return $o;
468     }
470     /**
471      * Generate the html for a hidden section
472      *
473      * @param int $sectionno The section number in the coruse which is being dsiplayed
474      * @return string HTML to output.
475      */
476     protected function section_hidden($sectionno) {
477         $o = '';
478         $o.= html_writer::start_tag('li', array('id' => 'section-'.$sectionno, 'class' => 'section main clearfix hidden'));
479         $o.= html_writer::tag('div', '', array('class' => 'left side'));
480         $o.= html_writer::tag('div', '', array('class' => 'right side'));
481         $o.= html_writer::start_tag('div', array('class' => 'content'));
482         $o.= get_string('notavailable');
483         $o.= html_writer::end_tag('div');
484         $o.= html_writer::end_tag('li');
485         return $o;
486     }
488     /**
489      * Output the html for a single section page .
490      *
491      * @param stdClass $course The course entry from DB
492      * @param array $sections The course_sections entries from the DB
493      * @param array $mods used for print_section()
494      * @param array $modnames used for print_section()
495      * @param array $modnamesused used for print_section()
496      * @param int $displaysection The section number in the course which is being displayed
497      */
498     public function print_single_section_page($course, $sections, $mods, $modnames, $modnamesused, $displaysection) {
499         global $PAGE;
501         // Can we view the section in question?
502         $context = context_course::instance($course->id);
503         $canviewhidden = has_capability('moodle/course:viewhiddensections', $context);
505         if (!isset($sections[$displaysection])) {
506             // This section doesn't exist
507             print_error('unknowncoursesection', 'error', null, $course->fullname);
508             return;
509         }
511         if (!$sections[$displaysection]->visible && !$canviewhidden) {
512             if (!$course->hiddensections) {
513                 echo $this->start_section_list();
514                 echo $this->section_hidden($displaysection);
515                 echo $this->end_section_list();
516             }
517             // Can't view this section.
518             return;
519         }
521         // General section if non-empty.
522         $thissection = $sections[0];
523         if ($thissection->summary or $thissection->sequence or $PAGE->user_is_editing()) {
524             echo $this->start_section_list();
525             echo $this->section_header($thissection, $course, true);
526             print_section($course, $thissection, $mods, $modnamesused, true);
527             if ($PAGE->user_is_editing()) {
528                 print_section_add_menus($course, 0, $modnames);
529             }
530             echo $this->section_footer();
531             echo $this->end_section_list();
532         }
534         // Start single-section div
535         echo html_writer::start_tag('div', array('class' => 'single-section'));
537         // Title with section navigation links.
538         $sectionnavlinks = $this->get_nav_links($course, $sections, $displaysection);
539         $sectiontitle = '';
540         $sectiontitle .= html_writer::start_tag('div', array('class' => 'section-navigation header headingblock'));
541         $sectiontitle .= html_writer::tag('span', $sectionnavlinks['previous'], array('class' => 'mdl-left'));
542         $sectiontitle .= html_writer::tag('span', $sectionnavlinks['next'], array('class' => 'mdl-right'));
543         // Title attributes
544         $titleattr = 'mdl-align title';
545         if (!$sections[$displaysection]->visible) {
546             $titleattr .= ' dimmed_text';
547         }
548         $sectiontitle .= html_writer::tag('div', get_section_name($course, $sections[$displaysection]), array('class' => $titleattr));
549         $sectiontitle .= html_writer::end_tag('div');
550         echo $sectiontitle;
552         // Copy activity clipboard..
553         echo $this->course_activity_clipboard($course, $displaysection);
555         // Now the list of sections..
556         echo $this->start_section_list();
558         // The requested section page.
559         $thissection = $sections[$displaysection];
560         echo $this->section_header($thissection, $course, true);
561         // Show completion help icon.
562         $completioninfo = new completion_info($course);
563         echo $completioninfo->display_help_icon();
565         print_section($course, $thissection, $mods, $modnamesused, true, '100%', false, true);
566         if ($PAGE->user_is_editing()) {
567             print_section_add_menus($course, $displaysection, $modnames);
568         }
569         echo $this->section_footer();
570         echo $this->end_section_list();
572         // Display section bottom navigation.
573         $courselink = html_writer::link(course_get_url($course), get_string('returntomaincoursepage'));
574         $sectionbottomnav = '';
575         $sectionbottomnav .= html_writer::start_tag('div', array('class' => 'section-navigation mdl-bottom'));
576         $sectionbottomnav .= html_writer::tag('span', $sectionnavlinks['previous'], array('class' => 'mdl-left'));
577         $sectionbottomnav .= html_writer::tag('span', $sectionnavlinks['next'], array('class' => 'mdl-right'));
578         $sectionbottomnav .= html_writer::tag('div', $courselink, array('class' => 'mdl-align'));
579         $sectionbottomnav .= html_writer::end_tag('div');
580         echo $sectionbottomnav;
582         // close single-section div.
583         echo html_writer::end_tag('div');
584     }
586     /**
587      * Output the html for a multiple section page
588      *
589      * @param stdClass $course The course entry from DB
590      * @param array $sections The course_sections entries from the DB
591      * @param array $mods used for print_section()
592      * @param array $modnames used for print_section()
593      * @param array $modnamesused used for print_section()
594      */
595     public function print_multiple_section_page($course, $sections, $mods, $modnames, $modnamesused) {
596         global $PAGE;
598         $context = context_course::instance($course->id);
599         // Title with completion help icon.
600         $completioninfo = new completion_info($course);
601         echo $completioninfo->display_help_icon();
602         echo $this->output->heading($this->page_title(), 2, 'accesshide');
604         // Copy activity clipboard..
605         echo $this->course_activity_clipboard($course);
607         // Now the list of sections..
608         echo $this->start_section_list();
610         // General section if non-empty.
611         $thissection = $sections[0];
612         unset($sections[0]);
613         if ($thissection->summary or $thissection->sequence or $PAGE->user_is_editing()) {
614             echo $this->section_header($thissection, $course, true);
615             print_section($course, $thissection, $mods, $modnamesused, true);
616             if ($PAGE->user_is_editing()) {
617                 print_section_add_menus($course, 0, $modnames);
618             }
619             echo $this->section_footer();
620         }
622         $canviewhidden = has_capability('moodle/course:viewhiddensections', $context);
623         for ($section = 1; $section <= $course->numsections; $section++) {
624             if (!empty($sections[$section])) {
625                 $thissection = $sections[$section];
626             } else {
627                 // This will create a course section if it doesn't exist..
628                 $thissection = get_course_section($section, $course->id);
630                 // The returned section is only a bare database object rather than
631                 // a section_info object - we will need at least the uservisible
632                 // field in it.
633                 $thissection->uservisible = true;
634                 $thissection->availableinfo = null;
635                 $thissection->showavailability = 0;
636             }
637             // Show the section if the user is permitted to access it, OR if it's not available
638             // but showavailability is turned on
639             $showsection = $thissection->uservisible ||
640                     ($thissection->visible && !$thissection->available && $thissection->showavailability);
641             if (!$showsection) {
642                 // Hidden section message is overridden by 'unavailable' control
643                 // (showavailability option).
644                 if (!$course->hiddensections && $thissection->available) {
645                     echo $this->section_hidden($section);
646                 }
648                 unset($sections[$section]);
649                 continue;
650             }
652             if (!$PAGE->user_is_editing() && $course->coursedisplay == COURSE_DISPLAY_MULTIPAGE) {
653                 // Display section summary only.
654                 echo $this->section_summary($thissection, $course, $mods);
655             } else {
656                 echo $this->section_header($thissection, $course, false);
657                 if ($thissection->uservisible) {
658                     print_section($course, $thissection, $mods, $modnamesused);
659                     if ($PAGE->user_is_editing()) {
660                         print_section_add_menus($course, $section, $modnames);
661                     }
662                 }
663                 echo $this->section_footer();
664             }
666             unset($sections[$section]);
667         }
669         if ($PAGE->user_is_editing() and has_capability('moodle/course:update', $context)) {
670             // Print stealth sections if present.
671             $modinfo = get_fast_modinfo($course);
672             foreach ($sections as $section => $thissection) {
673                 if (empty($modinfo->sections[$section])) {
674                     continue;
675                 }
676                 echo $this->stealth_section_header($section);
677                 print_section($course, $thissection, $mods, $modnamesused);
678                 echo $this->stealth_section_footer();
679             }
681             echo $this->end_section_list();
683             echo html_writer::start_tag('div', array('id' => 'changenumsections', 'class' => 'mdl-right'));
685             // Increase number of sections.
686             $straddsection = get_string('increasesections', 'moodle');
687             $url = new moodle_url('/course/changenumsections.php',
688                 array('courseid' => $course->id,
689                       'increase' => true,
690                       'sesskey' => sesskey()));
691             $icon = $this->output->pix_icon('t/switch_plus', $straddsection);
692             echo html_writer::link($url, $icon.get_accesshide($straddsection), array('class' => 'increase-sections'));
694             if ($course->numsections > 0) {
695                 // Reduce number of sections sections.
696                 $strremovesection = get_string('reducesections', 'moodle');
697                 $url = new moodle_url('/course/changenumsections.php',
698                     array('courseid' => $course->id,
699                           'increase' => false,
700                           'sesskey' => sesskey()));
701                 $icon = $this->output->pix_icon('t/switch_minus', $strremovesection);
702                 echo html_writer::link($url, $icon.get_accesshide($strremovesection), array('class' => 'reduce-sections'));
703             }
705             echo html_writer::end_tag('div');
706         } else {
707             echo $this->end_section_list();
708         }
710     }
712     /**
713      * Generate html for a section summary text
714      *
715      * @param stdClass $section The course_section entry from DB
716      * @return string HTML to output.
717      */
718     protected function format_summary_text($section) {
719         $context = context_course::instance($section->course);
720         $summarytext = file_rewrite_pluginfile_urls($section->summary, 'pluginfile.php',
721             $context->id, 'course', 'section', $section->id);
723         $options = new stdClass();
724         $options->noclean = true;
725         $options->overflowdiv = true;
726         return format_text($summarytext, $section->summaryformat, $options);
727     }
729     /**
730      * Is the section passed in the current section? (Note this isn't strictly
731      * a renderering method, but neater here).
732      *
733      * @param stdClass $course The course entry from DB
734      * @param stdClass $section The course_section entry from the DB
735      * @return bool true if the section is current
736      */
737     protected function is_section_current($section, $course) {
738         return ($course->marker == $section->section);
739     }