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 default section controls 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\local\content\section;
  26  
  27  use action_menu;
  28  use action_menu_link_secondary;
  29  use context_course;
  30  use core\output\named_templatable;
  31  use core_courseformat\base as course_format;
  32  use core_courseformat\output\local\courseformat_named_templatable;
  33  use moodle_url;
  34  use pix_icon;
  35  use renderable;
  36  use section_info;
  37  use stdClass;
  38  
  39  /**
  40   * Base class to render section controls.
  41   *
  42   * @package   core_courseformat
  43   * @copyright 2020 Ferran Recio <ferran@moodle.com>
  44   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  45   */
  46  class controlmenu implements named_templatable, renderable {
  47  
  48      use courseformat_named_templatable;
  49  
  50      /** @var course_format the course format class */
  51      protected $format;
  52  
  53      /** @var section_info the course section class */
  54      protected $section;
  55  
  56      /**
  57       * Constructor.
  58       *
  59       * @param course_format $format the course format
  60       * @param section_info $section the section info
  61       */
  62      public function __construct(course_format $format, section_info $section) {
  63          $this->format = $format;
  64          $this->section = $section;
  65      }
  66  
  67      /**
  68       * Export this data so it can be used as the context for a mustache template.
  69       *
  70       * @param renderer_base $output typically, the renderer that's calling this function
  71       * @return array data context for a mustache template
  72       */
  73      public function export_for_template(\renderer_base $output): stdClass {
  74  
  75          $section = $this->section;
  76  
  77          $controls = $this->section_control_items();
  78  
  79          if (empty($controls)) {
  80              return new stdClass();
  81          }
  82  
  83          // Convert control array into an action_menu.
  84          $menu = new action_menu();
  85          $icon = $output->pix_icon('i/menu', get_string('edit'));
  86          $menu->set_menu_trigger($icon, 'btn btn-icon d-flex align-items-center justify-content-center');
  87          $menu->attributes['class'] .= ' section-actions';
  88          foreach ($controls as $value) {
  89              $url = empty($value['url']) ? '' : $value['url'];
  90              $icon = empty($value['icon']) ? '' : $value['icon'];
  91              $name = empty($value['name']) ? '' : $value['name'];
  92              $attr = empty($value['attr']) ? [] : $value['attr'];
  93              $class = empty($value['pixattr']['class']) ? '' : $value['pixattr']['class'];
  94              $al = new action_menu_link_secondary(
  95                  new moodle_url($url),
  96                  new pix_icon($icon, '', null, ['class' => "smallicon " . $class]),
  97                  $name,
  98                  $attr
  99              );
 100              $menu->add($al);
 101          }
 102  
 103          $data = (object)[
 104              'menu' => $output->render($menu),
 105              'hasmenu' => true,
 106              'id' => $section->id,
 107          ];
 108  
 109          return $data;
 110      }
 111  
 112      /**
 113       * Generate the edit control items of a section.
 114       *
 115       * It is not clear this kind of controls are still available in 4.0 so, for now, this
 116       * method is almost a clone of the previous section_control_items from the course/renderer.php.
 117       *
 118       * This method must remain public until the final deprecation of section_edit_control_items.
 119       *
 120       * @return array of edit control items
 121       */
 122      public function section_control_items() {
 123          global $USER;
 124  
 125          $format = $this->format;
 126          $section = $this->section;
 127          $course = $format->get_course();
 128          $sectionreturn = $format->get_section_number();
 129          $user = $USER;
 130  
 131          $usecomponents = $format->supports_components();
 132          $coursecontext = context_course::instance($course->id);
 133          $numsections = $format->get_last_section_number();
 134          $isstealth = $section->section > $numsections;
 135  
 136          $baseurl = course_get_url($course, $sectionreturn);
 137          $baseurl->param('sesskey', sesskey());
 138  
 139          $controls = [];
 140  
 141          if (!$isstealth && has_capability('moodle/course:update', $coursecontext, $user)) {
 142              if ($section->section > 0
 143                  && get_string_manager()->string_exists('editsection', 'format_'.$format->get_format())) {
 144                  $streditsection = get_string('editsection', 'format_'.$format->get_format());
 145              } else {
 146                  $streditsection = get_string('editsection');
 147              }
 148  
 149              $controls['edit'] = [
 150                  'url'   => new moodle_url('/course/editsection.php', ['id' => $section->id, 'sr' => $sectionreturn]),
 151                  'icon' => 'i/settings',
 152                  'name' => $streditsection,
 153                  'pixattr' => ['class' => ''],
 154                  'attr' => ['class' => 'icon edit'],
 155              ];
 156          }
 157  
 158          if ($section->section) {
 159              $url = clone($baseurl);
 160              if (!$isstealth) {
 161                  if (has_capability('moodle/course:sectionvisibility', $coursecontext, $user)) {
 162                      $strhidefromothers = get_string('hidefromothers', 'format_' . $course->format);
 163                      $strshowfromothers = get_string('showfromothers', 'format_' . $course->format);
 164                      if ($section->visible) { // Show the hide/show eye.
 165                          $url->param('hide', $section->section);
 166                          $controls['visiblity'] = [
 167                              'url' => $url,
 168                              'icon' => 'i/hide',
 169                              'name' => $strhidefromothers,
 170                              'pixattr' => ['class' => ''],
 171                              'attr' => [
 172                                  'class' => 'icon editing_showhide',
 173                                  'data-sectionreturn' => $sectionreturn,
 174                                  'data-action' => ($usecomponents) ? 'sectionHide' : 'hide',
 175                                  'data-id' => $section->id,
 176                                  'data-swapname' => $strshowfromothers,
 177                                  'data-swapicon' => 'i/show',
 178                              ],
 179                          ];
 180                      } else {
 181                          $url->param('show',  $section->section);
 182                          $controls['visiblity'] = [
 183                              'url' => $url,
 184                              'icon' => 'i/show',
 185                              'name' => $strshowfromothers,
 186                              'pixattr' => ['class' => ''],
 187                              'attr' => [
 188                                  'class' => 'icon editing_showhide',
 189                                  'data-sectionreturn' => $sectionreturn,
 190                                  'data-action' => ($usecomponents) ? 'sectionShow' : 'show',
 191                                  'data-id' => $section->id,
 192                                  'data-swapname' => $strhidefromothers,
 193                                  'data-swapicon' => 'i/hide',
 194                              ],
 195                          ];
 196                      }
 197                  }
 198  
 199                  if (!$sectionreturn && has_capability('moodle/course:movesections', $coursecontext, $user)) {
 200                      if ($usecomponents) {
 201                          // This tool will appear only when the state is ready.
 202                          $url = clone ($baseurl);
 203                          $url->param('movesection', $section->section);
 204                          $url->param('section', $section->section);
 205                          $controls['movesection'] = [
 206                              'url' => $url,
 207                              'icon' => 'i/dragdrop',
 208                              'name' => get_string('move', 'moodle'),
 209                              'pixattr' => ['class' => ''],
 210                              'attr' => [
 211                                  'class' => 'icon move waitstate',
 212                                  'data-action' => 'moveSection',
 213                                  'data-id' => $section->id,
 214                              ],
 215                          ];
 216                      }
 217                      // Legacy move up and down links for non component-based formats.
 218                      $url = clone($baseurl);
 219                      if ($section->section > 1) { // Add a arrow to move section up.
 220                          $url->param('section', $section->section);
 221                          $url->param('move', -1);
 222                          $strmoveup = get_string('moveup');
 223                          $controls['moveup'] = [
 224                              'url' => $url,
 225                              'icon' => 'i/up',
 226                              'name' => $strmoveup,
 227                              'pixattr' => ['class' => ''],
 228                              'attr' => ['class' => 'icon moveup whilenostate'],
 229                          ];
 230                      }
 231  
 232                      $url = clone($baseurl);
 233                      if ($section->section < $numsections) { // Add a arrow to move section down.
 234                          $url->param('section', $section->section);
 235                          $url->param('move', 1);
 236                          $strmovedown = get_string('movedown');
 237                          $controls['movedown'] = [
 238                              'url' => $url,
 239                              'icon' => 'i/down',
 240                              'name' => $strmovedown,
 241                              'pixattr' => ['class' => ''],
 242                              'attr' => ['class' => 'icon movedown whilenostate'],
 243                          ];
 244                      }
 245                  }
 246              }
 247  
 248              if (course_can_delete_section($course, $section)) {
 249                  if (get_string_manager()->string_exists('deletesection', 'format_'.$course->format)) {
 250                      $strdelete = get_string('deletesection', 'format_'.$course->format);
 251                  } else {
 252                      $strdelete = get_string('deletesection');
 253                  }
 254                  $url = new moodle_url(
 255                      '/course/editsection.php',
 256                      [
 257                          'id' => $section->id,
 258                          'sr' => $sectionreturn,
 259                          'delete' => 1,
 260                          'sesskey' => sesskey(),
 261                      ]
 262                  );
 263                  $controls['delete'] = [
 264                      'url' => $url,
 265                      'icon' => 'i/delete',
 266                      'name' => $strdelete,
 267                      'pixattr' => ['class' => ''],
 268                      'attr' => [
 269                          'class' => 'icon editing_delete',
 270                          'data-action' => 'deleteSection',
 271                          'data-id' => $section->id,
 272                      ],
 273                  ];
 274              }
 275          }
 276  
 277          return $controls;
 278      }
 279  }