See Release Notes
Long Term Support Release
Differences Between: [Versions 400 and 401] [Versions 401 and 402] [Versions 401 and 403]
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 * Contains the default section course format output class. 19 * 20 * @package core_courseformat 21 * @copyright 2020 Ferran Recio <ferran@moodle.com> 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 */ 24 25 namespace core_courseformat\output; 26 27 defined('MOODLE_INTERNAL') || die(); 28 29 global $CFG; 30 require_once($CFG->dirroot . '/course/renderer.php'); 31 32 use action_menu; 33 use action_menu_link_secondary; 34 use cm_info; 35 use coding_exception; 36 use context_course; 37 use core_course_renderer; 38 use core_courseformat\base as course_format; 39 use html_writer; 40 use moodle_page; 41 use moodle_url; 42 use pix_icon; 43 use renderable; 44 use section_info; 45 use templatable; 46 use url_select; 47 48 /** 49 * Base class to render a course add section buttons. 50 * 51 * @package core_courseformat 52 * @copyright 2020 Ferran Recio <ferran@moodle.com> 53 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 54 */ 55 abstract class section_renderer extends core_course_renderer { 56 57 /** 58 * @var core_course_renderer contains an instance of core course renderer 59 * @deprecated since 4.0 - use $this to access course renderer methods 60 */ 61 protected $courserenderer; 62 63 /** 64 * Constructor method, calls the parent constructor. 65 * 66 * @deprecated since 4.0 67 * 68 * Note: this method exists only for compatibilitiy with legacy course formats. Legacy formats 69 * depends on $this->courserenderer to access the course renderer methods. Since Moodle 4.0 70 * core_courseformat\output\section_renderer extends core_course_renderer and all metdhos can be used directly from $this. 71 * 72 * @param moodle_page $page 73 * @param string $target one of rendering target constants 74 */ 75 public function __construct(moodle_page $page, $target) { 76 parent::__construct($page, $target); 77 $this->courserenderer = $this->page->get_renderer('core', 'course'); 78 } 79 80 /** 81 * Renders the provided widget and returns the HTML to display it. 82 * 83 * Course format templates uses a similar subfolder structure to the renderable classes. 84 * This method find out the specific template for a course widget. That's the reason why 85 * this render method is different from the normal plugin renderer one. 86 * 87 * course format templatables can be rendered using the core_course/local/* templates. 88 * Format plugins are free to override the default template location using render_xxx methods as usual. 89 * 90 * @param renderable $widget instance with renderable interface 91 * @return string the widget HTML 92 */ 93 public function render(renderable $widget) { 94 global $CFG; 95 $fullpath = str_replace('\\', '/', get_class($widget)); 96 $classparts = explode('/', $fullpath); 97 // Strip namespaces. 98 $classname = array_pop($classparts); 99 // Remove _renderable suffixes. 100 $classname = preg_replace('/_renderable$/', '', $classname); 101 102 $rendermethod = 'render_' . $classname; 103 if (method_exists($this, $rendermethod)) { 104 return $this->$rendermethod($widget); 105 } 106 107 // If nothing works, let the parent class decide. 108 return parent::render($widget); 109 } 110 111 /** 112 * Generate the section title, wraps it in a link to the section page if page is to be displayed on a separate page 113 * 114 * @param stdClass $section The course_section entry from DB 115 * @param stdClass $course The course entry from DB 116 * @return string HTML to output. 117 */ 118 public function section_title($section, $course) { 119 $title = get_section_name($course, $section); 120 $url = course_get_url($course, $section->section, array('navigation' => true)); 121 if ($url) { 122 $title = html_writer::link($url, $title); 123 } 124 return $title; 125 } 126 127 /** 128 * Generate the section title to be displayed on the section page, without a link 129 * 130 * @param stdClass $section The course_section entry from DB 131 * @param stdClass $course The course entry from DB 132 * @return string HTML to output. 133 */ 134 public function section_title_without_link($section, $course) { 135 return get_section_name($course, $section); 136 } 137 138 /** 139 * Get the updated rendered version of a cm list item. 140 * 141 * This method is used when an activity is duplicated or copied in on the client side without refreshing the page. 142 * It replaces the course renderer course_section_cm_list_item method but it's scope is different. 143 * Note that the previous method is used every time an activity is rendered, independent of it is the initial page 144 * loading or an Ajax update. In this case, course_section_updated_cm_item will only be used when the course editor 145 * requires to get an updated cm item HTML to perform partial page refresh. It will be used for suporting the course 146 * editor webservices. 147 * 148 * By default, the template used for update a cm_item is the same as when it renders initially, but format plugins are 149 * free to override this methos to provide extra affects or so. 150 * 151 * @param course_format $format the course format 152 * @param section_info $section the section info 153 * @param cm_info $cm the course module ionfo 154 * @param array $displayoptions optional extra display options 155 * @return string the rendered element 156 */ 157 public function course_section_updated_cm_item( 158 course_format $format, 159 section_info $section, 160 cm_info $cm, 161 array $displayoptions = [] 162 ) { 163 164 $cmitemclass = $format->get_output_classname('content\\section\\cmitem'); 165 $cmitem = new $cmitemclass($format, $section, $cm, $displayoptions); 166 return $this->render($cmitem); 167 } 168 169 /** 170 * Get the updated rendered version of a section. 171 * 172 * This method will only be used when the course editor requires to get an updated cm item HTML 173 * to perform partial page refresh. It will be used for supporting the course editor webservices. 174 * 175 * By default, the template used for update a section is the same as when it renders initially, 176 * but format plugins are free to override this method to provide extra effects or so. 177 * 178 * @param course_format $format the course format 179 * @param section_info $section the section info 180 * @return string the rendered element 181 */ 182 public function course_section_updated( 183 course_format $format, 184 section_info $section 185 ): string { 186 $sectionclass = $format->get_output_classname('content\\section'); 187 $output = new $sectionclass($format, $section); 188 return $this->render($output); 189 } 190 191 /** 192 * Get the course index drawer with placeholder. 193 * 194 * The default course index is loaded after the page is ready. Format plugins can override 195 * this method to provide an alternative course index. 196 * 197 * If the format is not compatible with the course index, this method will return an empty string. 198 * 199 * @param course_format $format the course format 200 * @return String the course index HTML. 201 */ 202 public function course_index_drawer(course_format $format): ?String { 203 if ($format->uses_course_index()) { 204 include_course_editor($format); 205 return $this->render_from_template('core_courseformat/local/courseindex/drawer', []); 206 } 207 return ''; 208 } 209 210 /** 211 * Generate the edit control action menu 212 * 213 * @deprecated since 4.0 MDL-72656 - use core_course output components instead. 214 * 215 * The section edit controls are now part of the main core_courseformat\output\local\content\section output 216 * and does not use renderer methods anymore. 217 * 218 * @param array $controls The edit control items from section_edit_control_items 219 * @param stdClass $course The course entry from DB (not used) 220 * @param stdClass $section The course_section entry from DB 221 * @return string HTML to output. 222 */ 223 protected function section_edit_control_menu($controls, $course, $section) { 224 debugging('section_edit_control_menu() can not be used anymore. Please use ' . 225 'core_courseformat\\output\\local\\content\\section to render a section. In case you need to modify those controls ' . 226 'override core_courseformat\\output\\local\\content\\section\\controlmenu in your format plugin.', DEBUG_DEVELOPER); 227 228 $o = ""; 229 if (!empty($controls)) { 230 $menu = new action_menu(); 231 $menu->set_menu_trigger(get_string('edit')); 232 $menu->attributes['class'] .= ' section-actions'; 233 foreach ($controls as $value) { 234 $url = empty($value['url']) ? '' : $value['url']; 235 $icon = empty($value['icon']) ? '' : $value['icon']; 236 $name = empty($value['name']) ? '' : $value['name']; 237 $attr = empty($value['attr']) ? array() : $value['attr']; 238 $class = empty($value['pixattr']['class']) ? '' : $value['pixattr']['class']; 239 $al = new action_menu_link_secondary( 240 new moodle_url($url), 241 new pix_icon($icon, '', null, array('class' => "smallicon " . $class)), 242 $name, 243 $attr 244 ); 245 $menu->add($al); 246 } 247 248 $o .= html_writer::div( 249 $this->render($menu), 250 'section_action_menu', 251 array('data-sectionid' => $section->id) 252 ); 253 } 254 255 return $o; 256 } 257 258 /** 259 * Generate the content to displayed on the right part of a section 260 * before course modules are included 261 * 262 * @deprecated since 4.0 MDL-72656 - use core_course output components instead. 263 * 264 * Spatial references like "left" or "right" are limiting the way formats and themes can 265 * extend courses. The elements from this method are now included in the 266 * core_courseformat\output\local\content\section output components. 267 * 268 * @param stdClass $section The course_section entry from DB 269 * @param stdClass $course The course entry from DB 270 * @param bool $onsectionpage true if being printed on a section page 271 * @return string HTML to output. 272 */ 273 protected function section_right_content($section, $course, $onsectionpage) { 274 275 debugging('section_right_content() can not be used anymore. Please use ' . 276 'core_courseformat\\output\\local\\content\\section to render a section.', DEBUG_DEVELOPER); 277 278 $o = $this->output->spacer(); 279 280 $controls = $this->section_edit_control_items($course, $section, $onsectionpage); 281 $o .= $this->section_edit_control_menu($controls, $course, $section); 282 283 return $o; 284 } 285 286 /** 287 * Generate the content to displayed on the left part of a section 288 * before course modules are included 289 * 290 * @deprecated since 4.0 MDL-72656 - use core_course output components instead. 291 * 292 * Spatial references like "left" or "right" are limiting the way formats and themes can 293 * extend courses. The elements from this method are now included in the 294 * core_courseformat\output\local\content\section output components. 295 * 296 * @param stdClass $section The course_section entry from DB 297 * @param stdClass $course The course entry from DB 298 * @param bool $onsectionpage true if being printed on a section page 299 * @return string HTML to output. 300 */ 301 protected function section_left_content($section, $course, $onsectionpage) { 302 303 debugging('section_left_content() can not be used anymore. Please use ' . 304 'core_courseformat\\output\\local\\content\\section to render a section.', DEBUG_DEVELOPER); 305 306 $o = ''; 307 308 if ($section->section != 0) { 309 // Only in the non-general sections. 310 if (course_get_format($course)->is_section_current($section)) { 311 $o = get_accesshide(get_string('currentsection', 'format_' . $course->format)); 312 } 313 } 314 315 return $o; 316 } 317 318 /** 319 * Generate the display of the header part of a section before 320 * course modules are included 321 * 322 * @deprecated since 4.0 MDL-72656 - use core_course output components instead. 323 * 324 * This element is now a core_courseformat\output\content\section output component and it is displayed using 325 * mustache templates instead of a renderer method. 326 * 327 * @param stdClass $section The course_section entry from DB 328 * @param stdClass $course The course entry from DB 329 * @param bool $onsectionpage true if being printed on a single-section page 330 * @param int $sectionreturn The section to return to after an action 331 * @return string HTML to output. 332 */ 333 protected function section_header($section, $course, $onsectionpage, $sectionreturn = null) { 334 debugging('section_header() is deprecated. Please use ' . 335 'core_courseformat\\output\\local\\content\\section to render a section ' . 336 'or core_courseformat\output\\local\\content\\section\\header ' . 337 'to print only the header.', DEBUG_DEVELOPER); 338 339 $o = ''; 340 $sectionstyle = ''; 341 342 if ($section->section != 0) { 343 // Only in the non-general sections. 344 if (!$section->visible) { 345 $sectionstyle = ' hidden'; 346 } 347 if (course_get_format($course)->is_section_current($section)) { 348 $sectionstyle = ' current'; 349 } 350 } 351 352 $o .= html_writer::start_tag('li', [ 353 'id' => 'section-' . $section->section, 354 'class' => 'section main clearfix' . $sectionstyle, 355 'role' => 'region', 356 'aria-labelledby' => "sectionid-{$section->id}-title", 357 'data-sectionid' => $section->section, 358 'data-sectionreturnid' => $sectionreturn 359 ]); 360 361 $leftcontent = $this->section_left_content($section, $course, $onsectionpage); 362 $o .= html_writer::tag('div', $leftcontent, array('class' => 'left side')); 363 364 $rightcontent = $this->section_right_content($section, $course, $onsectionpage); 365 $o .= html_writer::tag('div', $rightcontent, array('class' => 'right side')); 366 $o .= html_writer::start_tag('div', array('class' => 'content')); 367 368 // When not on a section page, we display the section titles except the general section if null. 369 $hasnamenotsecpg = (!$onsectionpage && ($section->section != 0 || !is_null($section->name))); 370 371 // When on a section page, we only display the general section title, if title is not the default one. 372 $hasnamesecpg = ($onsectionpage && ($section->section == 0 && !is_null($section->name))); 373 374 $classes = ' accesshide'; 375 if ($hasnamenotsecpg || $hasnamesecpg) { 376 $classes = ''; 377 } 378 $sectionname = html_writer::tag('span', $this->section_title($section, $course)); 379 $o .= $this->output->heading($sectionname, 3, 'sectionname' . $classes, "sectionid-{$section->id}-title"); 380 381 $o .= $this->section_availability($section); 382 383 $o .= html_writer::start_tag('div', array('class' => 'summary')); 384 if ($section->uservisible || $section->visible) { 385 // Show summary if section is available or has availability restriction information. 386 // Do not show summary if section is hidden but we still display it because of course setting 387 // "Hidden sections are shown as not available". 388 $o .= $this->format_summary_text($section); 389 } 390 $o .= html_writer::end_tag('div'); 391 392 return $o; 393 } 394 395 /** 396 * Generate the display of the footer part of a section. 397 * 398 * @deprecated since 4.0 MDL-72656 - use core_course output components instead. 399 * 400 * This element is integrated into core_courseformat\output\local\content\section output component and it is 401 * displayed using mustache templates instead of a renderer method. 402 * 403 * @return string HTML to output. 404 */ 405 protected function section_footer() { 406 407 debugging('section_footer() is deprecated. Please use ' . 408 'core_courseformat\\output\\local\\content\\section to render individual sections or .' . 409 'core_courseformat\\output\\local\\content to render the full course', DEBUG_DEVELOPER); 410 411 $o = html_writer::end_tag('div'); 412 $o .= html_writer::end_tag('li'); 413 return $o; 414 } 415 416 /** 417 * Generate the starting container html for a list of sections. 418 * 419 * @deprecated since 4.0 MDL-72656 - use core_course output components instead. 420 * 421 * @return string HTML to output. 422 */ 423 protected function start_section_list() { 424 debugging('start_section_list() is deprecated. Please use ' . 425 'core_courseformat\\output\\local\\content\\section to render individual sections or .' . 426 'core_courseformat\\output\\local\\content to render the full course', DEBUG_DEVELOPER); 427 return html_writer::start_tag('ul', ['class' => 'sections']); 428 } 429 430 /** 431 * Generate the closing container html for a list of sections. 432 * 433 * @deprecated since 4.0 MDL-72656 - use core_course output components instead.y 434 * 435 * @return string HTML to output. 436 */ 437 protected function end_section_list() { 438 debugging('end_section_list() is deprecated. Please use ' . 439 'core_courseformat\\output\\local\\content\\section to render individual sections or .' . 440 'core_courseformat\\output\\local\\content to render the full course', DEBUG_DEVELOPER); 441 return html_writer::end_tag('ul'); 442 } 443 444 /** 445 * Old method to print section edit controls. Do not use it! 446 * 447 * @deprecated since Moodle 3.0 MDL-48947 - Use core_courseformat\output\section_renderer::section_edit_control_items() instead 448 */ 449 protected function section_edit_controls() { 450 throw new coding_exception('section_edit_controls() can not be used anymore. Please use ' . 451 'section_edit_control_items() instead.'); 452 } 453 454 /** 455 * Generate the edit control items of a section 456 * 457 * @deprecated since 4.0 MDL-72656 - use core_course output components instead. 458 * 459 * This element is now a core_courseformat\output\content\section output component and it is displayed using 460 * mustache templates instead of a renderer method. 461 * 462 * @param stdClass $course The course entry from DB 463 * @param stdClass $section The course_section entry from DB 464 * @param bool $onsectionpage true if being printed on a section page 465 * @return array of edit control items 466 */ 467 protected function section_edit_control_items($course, $section, $onsectionpage = false) { 468 debugging('section_edit_control_items() is deprecated, please use or extend' . 469 'core_courseformat\output\\local\\content\\section\\controlmenu instead (like topics format does).', DEBUG_DEVELOPER); 470 471 $format = course_get_format($course); 472 $modinfo = $format->get_modinfo(); 473 474 if ($onsectionpage) { 475 $format->set_section_number($section->section); 476 } 477 478 // We need a section_info object, not a record. 479 $section = $modinfo->get_section_info($section->section); 480 481 $widgetclass = $format->get_output_classname('content\\section\\controlmenu'); 482 $widget = new $widgetclass($format, $section); 483 return $widget->section_control_items(); 484 } 485 486 /** 487 * Generate a summary of a section for display on the 'course index page' 488 * 489 * @deprecated since 4.0 MDL-72656 - use core_course output components instead. 490 * 491 * This element is now a core_courseformat\output\content\section output component and it is displayed using 492 * mustache templates instead of a renderer method. 493 * 494 * @param stdClass $section The course_section entry from DB 495 * @param stdClass $course The course entry from DB 496 * @param array $mods (argument not used) 497 * @return string HTML to output. 498 */ 499 protected function section_summary($section, $course, $mods) { 500 debugging('section_summary() is deprecated. Please use ' . 501 'core_courseformat\output\\local\\content\\section to render sections. If you need to modify those summary, extend ' . 502 'core_courseformat\output\\local\\content\\section\\summary in your format plugin.', DEBUG_DEVELOPER); 503 504 $classattr = 'section main section-summary clearfix'; 505 $linkclasses = ''; 506 507 // If section is hidden then display grey section link. 508 if (!$section->visible) { 509 $classattr .= ' hidden'; 510 $linkclasses .= ' dimmed_text'; 511 } else if (course_get_format($course)->is_section_current($section)) { 512 $classattr .= ' current'; 513 } 514 515 $title = get_section_name($course, $section); 516 $o = ''; 517 $o .= html_writer::start_tag('li', [ 518 'id' => 'section-' . $section->section, 519 'class' => $classattr, 520 'role' => 'region', 521 'aria-label' => $title, 522 'data-sectionid' => $section->section 523 ]); 524 525 $o .= html_writer::tag('div', '', array('class' => 'left side')); 526 $o .= html_writer::tag('div', '', array('class' => 'right side')); 527 $o .= html_writer::start_tag('div', array('class' => 'content')); 528 529 if ($section->uservisible) { 530 $title = html_writer::tag( 531 'a', 532 $title, 533 array('href' => course_get_url($course, $section->section), 'class' => $linkclasses) 534 ); 535 } 536 $o .= $this->output->heading($title, 3, 'section-title'); 537 538 $o .= $this->section_availability($section); 539 $o .= html_writer::start_tag('div', array('class' => 'summarytext')); 540 541 if ($section->uservisible || $section->visible) { 542 // Show summary if section is available or has availability restriction information. 543 // Do not show summary if section is hidden but we still display it because of course setting 544 // "Hidden sections are shown as not available". 545 $o .= $this->format_summary_text($section); 546 } 547 $o .= html_writer::end_tag('div'); 548 $o .= $this->section_activity_summary($section, $course, null); 549 550 $o .= html_writer::end_tag('div'); 551 $o .= html_writer::end_tag('li'); 552 553 return $o; 554 } 555 556 /** 557 * Generate a summary of the activites in a section 558 * 559 * @deprecated since 4.0 MDL-72656 - use core_course output components instead. 560 * 561 * This element is now a core_courseformat\output\content\section output component and it is displayed using 562 * mustache templates instead of a renderer method. 563 * 564 * @param stdClass $section The course_section entry from DB 565 * @param stdClass $course the course record from DB 566 * @param array $mods (argument not used) 567 * @return string HTML to output. 568 */ 569 protected function section_activity_summary($section, $course, $mods) { 570 571 debugging('section_activity_summary() is deprecated. Please use ' . 572 'core_courseformat\output\\local\\content\\section to render sections. ' . 573 'If you need to modify those information, extend ' . 574 'core_courseformat\output\\local\\content\\section\\cmsummary in your format plugin.', DEBUG_DEVELOPER); 575 576 $format = course_get_format($course); 577 $widgetclass = $format->get_output_classname('content\\section\\cmsummary'); 578 $widget = new $widgetclass($format, $section); 579 $this->render($widget); 580 } 581 582 /** 583 * If section is not visible, display the message about that ('Not available 584 * until...', that sort of thing). Otherwise, returns blank. 585 * 586 * For users with the ability to view hidden sections, it shows the 587 * information even though you can view the section and also may include 588 * slightly fuller information (so that teachers can tell when sections 589 * are going to be unavailable etc). This logic is the same as for 590 * activities. 591 * 592 * @deprecated since 4.0 MDL-72656 - use core_course output components instead. 593 * 594 * This element is now a core_courseformat\output\content\section output component and it is displayed using 595 * mustache templates instead of a renderer method. 596 * 597 * @param section_info $section The course_section entry from DB 598 * @param bool $canviewhidden True if user can view hidden sections 599 * @return string HTML to output 600 */ 601 protected function section_availability_message($section, $canviewhidden) { 602 global $CFG; 603 604 debugging('section_availability_message() is deprecated. Please use ' . 605 'core_courseformat\output\\local\\content\\section to render sections. If you need to modify this element, extend ' . 606 'core_courseformat\output\\local\\content\\section\\availability in your format plugin.', DEBUG_DEVELOPER); 607 608 $course = $section->course; 609 $format = course_get_format($course); 610 $widgetclass = $format->get_output_classname('content\\section\\availability'); 611 $widget = new $widgetclass($format, $section); 612 $this->render($widget); 613 } 614 615 /** 616 * Displays availability information for the section (hidden, not available unles, etc.) 617 * 618 * @deprecated since 4.0 MDL-72656 - use core_course output components instead. 619 * 620 * This element is now a core_courseformat\output\content\section output component and it is displayed using 621 * mustache templates instead of a renderer method. 622 * 623 * @param section_info $section 624 * @return string 625 */ 626 public function section_availability($section) { 627 debugging('section_availability() is deprecated. Please use ' . 628 'core_courseformat\output\\local\\content\\section to render sections. If you need to modify this element, extend ' . 629 'core_courseformat\output\\local\\content\\section\\availability in your format plugin.', DEBUG_DEVELOPER); 630 631 $context = context_course::instance($section->course); 632 $canviewhidden = has_capability('moodle/course:viewhiddensections', $context); 633 return html_writer::div($this->section_availability_message($section, $canviewhidden), 'section_availability'); 634 } 635 636 /** 637 * Show if something is on on the course clipboard (moving around) 638 * 639 * @deprecated since 4.0 MDL-72656 - use core_course output components instead. 640 * 641 * While the non ajax course eidtion is still supported, the old clipboard will be 642 * emulated by core_courseformat\output\local\content\section\cmlist. 643 * 644 * @param stdClass $course The course entry from DB 645 * @param int $sectionno The section number in the course which is being displayed 646 * @return string HTML to output. 647 */ 648 protected function course_activity_clipboard($course, $sectionno = null) { 649 global $USER; 650 debugging('Non ajax course edition using course_activity_clipboard is not supported anymore.', DEBUG_DEVELOPER); 651 652 $o = ''; 653 // If currently moving a file then show the current clipboard. 654 if (ismoving($course->id)) { 655 $url = new moodle_url( 656 '/course/mod.php', 657 array( 658 'sesskey' => sesskey(), 659 'cancelcopy' => true, 660 'sr' => $sectionno, 661 ) 662 ); 663 664 $o .= html_writer::start_tag('div', array('class' => 'clipboard')); 665 $o .= strip_tags(get_string('activityclipboard', '', $USER->activitycopyname)); 666 $o .= ' (' . html_writer::link($url, get_string('cancel')) . ')'; 667 $o .= html_writer::end_tag('div'); 668 } 669 670 return $o; 671 } 672 673 /** 674 * Generate next/previous section links for naviation. 675 * 676 * @deprecated since 4.0 MDL-72656 - use core_course output components instead. 677 * 678 * This element is now a core_courseformat\output\content\section output component and it is displayed using 679 * mustache templates instead of a renderer method. 680 * 681 * @param stdClass $course The course entry from DB 682 * @param array $sections The course_sections entries from the DB 683 * @param int $sectionno The section number in the course which is being displayed 684 * @return array associative array with previous and next section link 685 */ 686 protected function get_nav_links($course, $sections, $sectionno) { 687 688 debugging('get_nav_links() is deprecated. Please use ' . 689 'core_courseformat\\output\\local\\content to render a course. If you need to modify this element, extend ' . 690 'core_courseformat\\output\\local\\content\\sectionnavigation in your format plugin.', DEBUG_DEVELOPER); 691 692 // FIXME: This is really evil and should by using the navigation API. 693 $course = course_get_format($course)->get_course(); 694 $canviewhidden = has_capability('moodle/course:viewhiddensections', context_course::instance($course->id)) 695 or !$course->hiddensections; 696 697 $links = array('previous' => '', 'next' => ''); 698 $back = $sectionno - 1; 699 while ($back > 0 and empty($links['previous'])) { 700 if ($canviewhidden || $sections[$back]->uservisible) { 701 $params = array(); 702 if (!$sections[$back]->visible) { 703 $params = array('class' => 'dimmed_text'); 704 } 705 $previouslink = html_writer::tag('span', $this->output->larrow(), array('class' => 'larrow')); 706 $previouslink .= get_section_name($course, $sections[$back]); 707 $links['previous'] = html_writer::link(course_get_url($course, $back), $previouslink, $params); 708 } 709 $back--; 710 } 711 712 $forward = $sectionno + 1; 713 $numsections = course_get_format($course)->get_last_section_number(); 714 while ($forward <= $numsections and empty($links['next'])) { 715 if ($canviewhidden || $sections[$forward]->uservisible) { 716 $params = array(); 717 if (!$sections[$forward]->visible) { 718 $params = array('class' => 'dimmed_text'); 719 } 720 $nextlink = get_section_name($course, $sections[$forward]); 721 $nextlink .= html_writer::tag('span', $this->output->rarrow(), array('class' => 'rarrow')); 722 $links['next'] = html_writer::link(course_get_url($course, $forward), $nextlink, $params); 723 } 724 $forward++; 725 } 726 727 return $links; 728 } 729 730 /** 731 * Generate the header html of a stealth section 732 * 733 * @deprecated since 4.0 MDL-72656 - use core_course output components instead. 734 * 735 * This element is now a core_courseformat\output\content\section output component and it is displayed using 736 * mustache templates instead of a renderer method. 737 * 738 * @param int $sectionno The section number in the course which is being displayed 739 * @return string HTML to output. 740 */ 741 protected function stealth_section_header($sectionno) { 742 debugging('stealth_section_header() is deprecated. Please use ' . 743 'core_courseformat\output\\local\\content\\section to render sections.', DEBUG_DEVELOPER); 744 745 $o = ''; 746 $o .= html_writer::start_tag('li', [ 747 'id' => 'section-' . $sectionno, 748 'class' => 'section main clearfix orphaned hidden', 749 'data-sectionid' => $sectionno 750 ]); 751 $o .= html_writer::tag('div', '', array('class' => 'left side')); 752 $course = course_get_format($this->page->course)->get_course(); 753 $section = course_get_format($this->page->course)->get_section($sectionno); 754 $rightcontent = $this->section_right_content($section, $course, false); 755 $o .= html_writer::tag('div', $rightcontent, array('class' => 'right side')); 756 $o .= html_writer::start_tag('div', array('class' => 'content')); 757 $o .= $this->output->heading( 758 get_string('orphanedactivitiesinsectionno', '', $sectionno), 759 3, 760 'sectionname' 761 ); 762 return $o; 763 } 764 765 /** 766 * Generate footer html of a stealth section 767 * 768 * @deprecated since 4.0 MDL-72656 - use core_course output components instead. 769 * 770 * This element is now a core_courseformat\output\content\section output component and it is displayed using 771 * mustache templates instead of a renderer method. 772 * 773 * @return string HTML to output. 774 */ 775 protected function stealth_section_footer() { 776 debugging('stealth_section_footer() is deprecated. Please use ' . 777 'core_courseformat\output\\local\\content\\section to render sections.', DEBUG_DEVELOPER); 778 779 $o = html_writer::end_tag('div'); 780 $o .= html_writer::end_tag('li'); 781 return $o; 782 } 783 784 /** 785 * Generate the html for a hidden section 786 * 787 * @param int $sectionno The section number in the course which is being displayed 788 * @param int|stdClass $courseorid The course to get the section name for (object or just course id) 789 * @return string HTML to output. 790 */ 791 protected function section_hidden($sectionno, $courseorid = null) { 792 if ($courseorid) { 793 $sectionname = get_section_name($courseorid, $sectionno); 794 $strnotavailable = get_string('notavailablecourse', '', $sectionname); 795 } else { 796 $strnotavailable = get_string('notavailable'); 797 } 798 799 $o = ''; 800 $o .= html_writer::start_tag('li', [ 801 'id' => 'section-' . $sectionno, 802 'class' => 'section main clearfix hidden', 803 'data-sectionid' => $sectionno 804 ]); 805 $o .= html_writer::tag('div', '', array('class' => 'left side')); 806 $o .= html_writer::tag('div', '', array('class' => 'right side')); 807 $o .= html_writer::start_tag('div', array('class' => 'content')); 808 $o .= html_writer::tag('div', $strnotavailable); 809 $o .= html_writer::end_tag('div'); 810 $o .= html_writer::end_tag('li'); 811 return $o; 812 } 813 814 /** 815 * Generate the html for the 'Jump to' menu on a single section page. 816 * 817 * @deprecated since 4.0 MDL-72656 - use core_course output components instead. 818 * 819 * This element is now a core_courseformat\output\content\section output component and it is displayed using 820 * mustache templates instead of a renderer method. 821 * 822 * @param stdClass $course The course entry from DB 823 * @param array $sections The course_sections entries from the DB 824 * @param int $displaysection the current displayed section number. 825 * 826 * @return string HTML to output. 827 */ 828 protected function section_nav_selection($course, $sections, $displaysection) { 829 830 debugging('section_nav_selection() can not be used anymore. Please use ' . 831 'core_courseformat\\output\\local\\content to render a course. If you need to modify this element, extend ' . 832 'core_courseformat\\output\\local\\content\\sectionnavigation or ' . 833 'core_courseformat\\output\\local\\content\\sectionselector in your format plugin.', DEBUG_DEVELOPER); 834 835 $o = ''; 836 $sectionmenu = array(); 837 $sectionmenu[course_get_url($course)->out(false)] = get_string('maincoursepage'); 838 $modinfo = get_fast_modinfo($course); 839 $section = 1; 840 $numsections = course_get_format($course)->get_last_section_number(); 841 while ($section <= $numsections) { 842 $thissection = $modinfo->get_section_info($section); 843 if (($thissection->uservisible) && ($section != $displaysection) && ($url = course_get_url($course, $section))) { 844 $sectionmenu[$url->out(false)] = get_section_name($course, $section); 845 } 846 $section++; 847 } 848 849 $select = new url_select($sectionmenu, '', array('' => get_string('jumpto'))); 850 $select->class = 'jumpmenu'; 851 $select->formid = 'sectionmenu'; 852 $o .= $this->output->render($select); 853 854 return $o; 855 } 856 857 /** 858 * Output the html for a single section page. 859 * 860 * @deprecated since 4.0 861 * 862 * This is a deprecated method and it is mantain only for compatibilitiy with legacy course formats. 863 * Please, to render a single section page use: 864 * 865 * $format = course_get_format($course); 866 * // Set the section to display. 867 * $format->set_section_number($displaysection); 868 * $outputclass = $format->get_output_classname('content'); 869 * $widget = new $outputclass($format); 870 * echo $this->render($widget); 871 * 872 * @param stdClass $course The course entry from DB 873 * @param array $sections (argument not used) 874 * @param array $mods (argument not used) 875 * @param array $modnames (argument not used) 876 * @param array $modnamesused (argument not used) 877 * @param int $displaysection The section number in the course which is being displayed 878 */ 879 public function print_single_section_page($course, $sections, $mods, $modnames, $modnamesused, $displaysection) { 880 881 debugging('Method print_single_section_page is deprecated, please use' . 882 'core_courseformat\\output\\local\\content instead ' . 883 'or override render_content method to use a different template', DEBUG_DEVELOPER); 884 885 // Some abstract methods are not needed anymore. We simulate them in case they are not present. 886 if (method_exists($this, 'start_section_list')) { 887 $startlist = $this->start_section_list(); 888 } else { 889 $startlist = html_writer::start_tag('ul', ['class' => '']); 890 } 891 if (method_exists($this, 'end_section_list')) { 892 $endlist = $this->end_section_list(); 893 } else { 894 $endlist = html_writer::end_tag('ul'); 895 } 896 897 $format = course_get_format($course); 898 899 // Set the section to display. 900 $format->set_section_number($displaysection); 901 902 $modinfo = $format->get_modinfo(); 903 $course = $format->get_course(); 904 905 // Can we view the section in question? 906 if (!($sectioninfo = $modinfo->get_section_info($displaysection)) || !$sectioninfo->uservisible) { 907 // This section doesn't exist or is not available for the user. 908 // We actually already check this in course/view.php but just in case exit from this function as well. 909 throw new \moodle_exception( 910 'unknowncoursesection', 911 'error', 912 course_get_url($course), 913 format_string($course->fullname) 914 ); 915 } 916 917 // Copy activity clipboard.. 918 echo $this->course_activity_clipboard($course, $displaysection); 919 $thissection = $modinfo->get_section_info(0); 920 if ($thissection->summary or !empty($modinfo->sections[0]) or $format->show_editor()) { 921 echo $startlist; 922 echo $this->section_header($thissection, $course, true, $displaysection); 923 echo $this->course_section_cm_list($course, $thissection, $displaysection); 924 echo $this->course_section_add_cm_control($course, 0, $displaysection); 925 echo $this->section_footer(); 926 echo $endlist; 927 } 928 929 // Start single-section div. 930 echo html_writer::start_tag('div', array('class' => 'single-section')); 931 932 // The requested section page. 933 $thissection = $modinfo->get_section_info($displaysection); 934 935 // Title with section navigation links. 936 $sectionnavlinks = $this->get_nav_links($course, $modinfo->get_section_info_all(), $displaysection); 937 $sectiontitle = ''; 938 $sectiontitle .= html_writer::start_tag('div', array('class' => 'section-navigation navigationtitle')); 939 $sectiontitle .= html_writer::tag('span', $sectionnavlinks['previous'], array('class' => 'mdl-left')); 940 $sectiontitle .= html_writer::tag('span', $sectionnavlinks['next'], array('class' => 'mdl-right')); 941 // Title attributes. 942 $classes = 'sectionname'; 943 if (!$thissection->visible) { 944 $classes .= ' dimmed_text'; 945 } 946 $sectionname = html_writer::tag('span', $this->section_title_without_link($thissection, $course)); 947 $sectiontitle .= $this->output->heading($sectionname, 3, $classes); 948 949 $sectiontitle .= html_writer::end_tag('div'); 950 echo $sectiontitle; 951 952 // Now the list of sections. 953 echo $startlist; 954 955 echo $this->section_header($thissection, $course, true, $displaysection); 956 957 echo $this->course_section_cm_list($course, $thissection, $displaysection); 958 echo $this->course_section_add_cm_control($course, $displaysection, $displaysection); 959 echo $this->section_footer(); 960 echo $endlist; 961 962 // Display section bottom navigation. 963 $sectionbottomnav = ''; 964 $sectionbottomnav .= html_writer::start_tag('div', array('class' => 'section-navigation mdl-bottom')); 965 $sectionbottomnav .= html_writer::tag('span', $sectionnavlinks['previous'], array('class' => 'mdl-left')); 966 $sectionbottomnav .= html_writer::tag('span', $sectionnavlinks['next'], array('class' => 'mdl-right')); 967 $sectionbottomnav .= html_writer::tag( 968 'div', 969 $this->section_nav_selection($course, $sections, $displaysection), 970 array('class' => 'mdl-align') 971 ); 972 $sectionbottomnav .= html_writer::end_tag('div'); 973 echo $sectionbottomnav; 974 975 // Close single-section div. 976 echo html_writer::end_tag('div'); 977 } 978 979 /** 980 * Output the html for a multiple section page 981 * 982 * @deprecated since 4.0 983 * 984 * This is a deprecated method and it is mantain only for compatibilitiy with legacy course formats. 985 * Please, to render a single section page use: 986 * 987 * $format = course_get_format($course); 988 * $outputclass = $format->get_output_classname('content'); 989 * $widget = new $outputclass($format); 990 * echo $this->render($widget); 991 * 992 * @param stdClass $course The course entry from DB 993 * @param array $sections (argument not used) 994 * @param array $mods (argument not used) 995 * @param array $modnames (argument not used) 996 * @param array $modnamesused (argument not used) 997 */ 998 public function print_multiple_section_page($course, $sections, $mods, $modnames, $modnamesused) { 999 1000 debugging('Method print_multiple_section_page is deprecated, please use' . 1001 'core_courseformat\\output\\local\\content instead ' . 1002 'or override render_content method to use a diferent template', DEBUG_DEVELOPER); 1003 1004 // Some abstract methods are not needed anymore. We simulate them in case they are not present. 1005 if (method_exists($this, 'start_section_list')) { 1006 $startlist = $this->start_section_list(); 1007 } else { 1008 $startlist = html_writer::start_tag('ul', ['class' => '']); 1009 } 1010 if (method_exists($this, 'end_section_list')) { 1011 $endlist = $this->end_section_list(); 1012 } else { 1013 $endlist = html_writer::end_tag('ul'); 1014 } 1015 if (method_exists($this, 'page_title')) { 1016 $pagetitle = $this->page_title(); 1017 } else { 1018 $pagetitle = ''; 1019 } 1020 1021 $format = course_get_format($course); 1022 1023 $modinfo = $format->get_modinfo(); 1024 $course = $format->get_course(); 1025 1026 $context = context_course::instance($course->id); 1027 echo $this->output->heading($pagetitle, 2, 'accesshide'); 1028 1029 // Copy activity clipboard.. 1030 echo $this->course_activity_clipboard($course, 0); 1031 1032 // Now the list of sections.. 1033 echo $startlist; 1034 $numsections = course_get_format($course)->get_last_section_number(); 1035 1036 foreach ($modinfo->get_section_info_all() as $section => $thissection) { 1037 if ($section == 0) { 1038 // 0-section is displayed a little different then the others 1039 if ($thissection->summary or !empty($modinfo->sections[0]) or $format->show_editor()) { 1040 echo $this->section_header($thissection, $course, false, 0); 1041 echo $this->course_section_cm_list($course, $thissection, 0); 1042 echo $this->course_section_add_cm_control($course, 0, 0); 1043 echo $this->section_footer(); 1044 } 1045 continue; 1046 } 1047 if ($section > $numsections) { 1048 // Activities inside this section are 'orphaned', this section will be printed as 'stealth' below. 1049 continue; 1050 } 1051 1052 if (!$format->is_section_visible($thissection)) { 1053 continue; 1054 } 1055 1056 if (!$format->show_editor() && $format->get_course_display() == COURSE_DISPLAY_MULTIPAGE) { 1057 // Display section summary only. 1058 echo $this->section_summary($thissection, $course, null); 1059 } else { 1060 echo $this->section_header($thissection, $course, false, 0); 1061 if ($thissection->uservisible) { 1062 echo $this->course_section_cm_list($course, $thissection, 0); 1063 echo $this->course_section_add_cm_control($course, $section, 0); 1064 } 1065 echo $this->section_footer(); 1066 } 1067 } 1068 1069 if ($format->show_editor()) { 1070 // Print stealth sections if present. 1071 foreach ($modinfo->get_section_info_all() as $section => $thissection) { 1072 if ($section <= $numsections or empty($modinfo->sections[$section])) { 1073 // This is not stealth section or it is empty. 1074 continue; 1075 } 1076 echo $this->stealth_section_header($section); 1077 echo $this->course_section_cm_list($course, $thissection, 0); 1078 echo $this->stealth_section_footer(); 1079 } 1080 1081 echo $endlist; 1082 1083 echo $this->change_number_sections($course, 0); 1084 } else { 1085 echo $endlist; 1086 } 1087 } 1088 1089 /** 1090 * Returns controls in the bottom of the page to increase/decrease number of sections 1091 * 1092 * @deprecated since 4.0 MDL-72656 - use core_course output components instead. 1093 * 1094 * @param stdClass $course 1095 * @param int|null $sectionreturn 1096 */ 1097 protected function change_number_sections($course, $sectionreturn = null) { 1098 debugging('Method change_number_sections is deprecated, please use' . 1099 'core_courseformat\\output\\local\\content\\addsection instead', DEBUG_DEVELOPER); 1100 1101 $format = course_get_format($course); 1102 if ($sectionreturn) { 1103 $format->set_section_number($sectionreturn); 1104 } 1105 $outputclass = $format->get_output_classname('content\\addsection'); 1106 $widget = new $outputclass($format); 1107 echo $this->render($widget); 1108 } 1109 1110 /** 1111 * Generate html for a section summary text 1112 * 1113 * @deprecated since 4.0 MDL-72656 - use core_course output components instead. 1114 * 1115 * @param stdClass $section The course_section entry from DB 1116 * @return string HTML to output. 1117 */ 1118 protected function format_summary_text($section) { 1119 debugging('Method format_summary_text is deprecated, please use' . 1120 'core_courseformat\output\\local\\content\\section\\summary::format_summary_text instead', DEBUG_DEVELOPER); 1121 1122 $format = course_get_format($section->course); 1123 if (!($section instanceof section_info)) { 1124 $modinfo = $format->get_modinfo(); 1125 $section = $modinfo->get_section_info($section->section); 1126 } 1127 $summaryclass = $format->get_output_classname('content\\section\\summary'); 1128 $summary = new $summaryclass($format, $section); 1129 return $summary->format_summary_text(); 1130 } 1131 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body