Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.

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 main course format out 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\local;
  26  
  27  use core\output\named_templatable;
  28  use core_courseformat\base as course_format;
  29  use course_modinfo;
  30  use renderable;
  31  
  32  /**
  33   * Base class to render a course format.
  34   *
  35   * @package   core_courseformat
  36   * @copyright 2020 Ferran Recio <ferran@moodle.com>
  37   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  38   */
  39  class content implements named_templatable, renderable {
  40      use courseformat_named_templatable;
  41  
  42      /** @var core_courseformat\base the course format class */
  43      protected $format;
  44  
  45      /** @var string the section format class */
  46      protected $sectionclass;
  47  
  48      /** @var string the add section output class name */
  49      protected $addsectionclass;
  50  
  51      /** @var string section navigation class name */
  52      protected $sectionnavigationclass;
  53  
  54      /** @var string section selector class name */
  55      protected $sectionselectorclass;
  56  
  57      /** @var bool if uses add section */
  58      protected $hasaddsection = true;
  59  
  60      /**
  61       * Constructor.
  62       *
  63       * @param course_format $format the coruse format
  64       */
  65      public function __construct(course_format $format) {
  66          $this->format = $format;
  67  
  68          // Load output classes names from format.
  69          $this->sectionclass = $format->get_output_classname('content\\section');
  70          $this->addsectionclass = $format->get_output_classname('content\\addsection');
  71          $this->sectionnavigationclass = $format->get_output_classname('content\\sectionnavigation');
  72          $this->sectionselectorclass = $format->get_output_classname('content\\sectionselector');
  73      }
  74  
  75      /**
  76       * Export this data so it can be used as the context for a mustache template (core/inplace_editable).
  77       *
  78       * @param renderer_base $output typically, the renderer that's calling this function
  79       * @return stdClass data context for a mustache template
  80       */
  81      public function export_for_template(\renderer_base $output) {
  82          global $PAGE;
  83          $format = $this->format;
  84  
  85          // Most formats uses section 0 as a separate section so we remove from the list.
  86          $sections = $this->export_sections($output);
  87          $initialsection = '';
  88          if (!empty($sections)) {
  89              $initialsection = array_shift($sections);
  90          }
  91  
  92          $data = (object)[
  93              'title' => $format->page_title(), // This method should be in the course_format class.
  94              'initialsection' => $initialsection,
  95              'sections' => $sections,
  96              'format' => $format->get_format(),
  97              'sectionreturn' => 0,
  98          ];
  99  
 100          // The single section format has extra navigation.
 101          $singlesection = $this->format->get_section_number();
 102          if ($singlesection) {
 103              if (!$PAGE->theme->usescourseindex) {
 104                  $sectionnavigation = new $this->sectionnavigationclass($format, $singlesection);
 105                  $data->sectionnavigation = $sectionnavigation->export_for_template($output);
 106  
 107                  $sectionselector = new $this->sectionselectorclass($format, $sectionnavigation);
 108                  $data->sectionselector = $sectionselector->export_for_template($output);
 109              }
 110              $data->hasnavigation = true;
 111              $data->singlesection = array_shift($data->sections);
 112              $data->sectionreturn = $singlesection;
 113          }
 114  
 115          if ($this->hasaddsection) {
 116              $addsection = new $this->addsectionclass($format);
 117              $data->numsections = $addsection->export_for_template($output);
 118          }
 119  
 120          return $data;
 121      }
 122  
 123      /**
 124       * Export sections array data.
 125       *
 126       * @param renderer_base $output typically, the renderer that's calling this function
 127       * @return array data context for a mustache template
 128       */
 129      protected function export_sections(\renderer_base $output): array {
 130  
 131          $format = $this->format;
 132          $course = $format->get_course();
 133          $modinfo = $this->format->get_modinfo();
 134  
 135          // Generate section list.
 136          $sections = [];
 137          $stealthsections = [];
 138          $numsections = $format->get_last_section_number();
 139          foreach ($this->get_sections_to_display($modinfo) as $sectionnum => $thissection) {
 140              // The course/view.php check the section existence but the output can be called
 141              // from other parts so we need to check it.
 142              if (!$thissection) {
 143                  throw new \moodle_exception('unknowncoursesection', 'error', course_get_url($course),
 144                      format_string($course->fullname));
 145              }
 146  
 147              $section = new $this->sectionclass($format, $thissection);
 148  
 149              if ($sectionnum > $numsections) {
 150                  // Activities inside this section are 'orphaned', this section will be printed as 'stealth' below.
 151                  if (!empty($modinfo->sections[$sectionnum])) {
 152                      $stealthsections[] = $section->export_for_template($output);
 153                  }
 154                  continue;
 155              }
 156  
 157              if (!$format->is_section_visible($thissection)) {
 158                  continue;
 159              }
 160  
 161              $sections[] = $section->export_for_template($output);
 162          }
 163          if (!empty($stealthsections)) {
 164              $sections = array_merge($sections, $stealthsections);
 165          }
 166          return $sections;
 167      }
 168  
 169      /**
 170       * Return an array of sections to display.
 171       *
 172       * This method is used to differentiate between display a specific section
 173       * or a list of them.
 174       *
 175       * @param course_modinfo $modinfo the current course modinfo object
 176       * @return section_info[] an array of section_info to display
 177       */
 178      private function get_sections_to_display(course_modinfo $modinfo): array {
 179          $singlesection = $this->format->get_section_number();
 180          if ($singlesection) {
 181              return [
 182                  $modinfo->get_section_info(0),
 183                  $modinfo->get_section_info($singlesection),
 184              ];
 185          }
 186  
 187          return $modinfo->get_section_info_all();
 188      }
 189  }