Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.3.x will end 7 October 2024 (12 months).
  • Bug fixes for security issues in 4.3.x will end 21 April 2025 (18 months).
  • PHP version: minimum PHP 8.0.0 Note: minimum PHP version has increased since Moodle 4.1. PHP 8.2.x is supported too.

Differences Between: [Versions 400 and 403] [Versions 401 and 403] [Versions 402 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          $menu->set_kebab_trigger(get_string('edit'));
  86          $menu->attributes['class'] .= ' section-actions';
  87          foreach ($controls as $value) {
  88              $url = empty($value['url']) ? '' : $value['url'];
  89              $icon = empty($value['icon']) ? '' : $value['icon'];
  90              $name = empty($value['name']) ? '' : $value['name'];
  91              $attr = empty($value['attr']) ? [] : $value['attr'];
  92              $class = empty($value['pixattr']['class']) ? '' : $value['pixattr']['class'];
  93              $al = new action_menu_link_secondary(
  94                  new moodle_url($url),
  95                  new pix_icon($icon, '', null, ['class' => "smallicon " . $class]),
  96                  $name,
  97                  $attr
  98              );
  99              $menu->add($al);
 100          }
 101  
 102          $data = (object)[
 103              'menu' => $output->render($menu),
 104              'hasmenu' => true,
 105              'id' => $section->id,
 106          ];
 107  
 108          return $data;
 109      }
 110  
 111      /**
 112       * Generate the edit control items of a section.
 113       *
 114       * It is not clear this kind of controls are still available in 4.0 so, for now, this
 115       * method is almost a clone of the previous section_control_items from the course/renderer.php.
 116       *
 117       * This method must remain public until the final deprecation of section_edit_control_items.
 118       *
 119       * @return array of edit control items
 120       */
 121      public function section_control_items() {
 122          global $USER;
 123  
 124          $format = $this->format;
 125          $section = $this->section;
 126          $course = $format->get_course();
 127          $sectionreturn = $format->get_section_number();
 128          $user = $USER;
 129  
 130          $usecomponents = $format->supports_components();
 131          $coursecontext = context_course::instance($course->id);
 132          $numsections = $format->get_last_section_number();
 133          $isstealth = $section->section > $numsections;
 134  
 135          $baseurl = course_get_url($course, $sectionreturn);
 136          $baseurl->param('sesskey', sesskey());
 137  
 138          $controls = [];
 139  
 140          if (!$isstealth && has_capability('moodle/course:update', $coursecontext, $user)) {
 141              if ($section->section > 0
 142                  && get_string_manager()->string_exists('editsection', 'format_'.$format->get_format())) {
 143                  $streditsection = get_string('editsection', 'format_'.$format->get_format());
 144              } else {
 145                  $streditsection = get_string('editsection');
 146              }
 147  
 148              $controls['edit'] = [
 149                  'url'   => new moodle_url('/course/editsection.php', ['id' => $section->id, 'sr' => $sectionreturn]),
 150                  'icon' => 'i/settings',
 151                  'name' => $streditsection,
 152                  'pixattr' => ['class' => ''],
 153                  'attr' => ['class' => 'icon edit'],
 154              ];
 155  
 156              $duplicatesectionurl = clone($baseurl);
 157              $duplicatesectionurl->param('section', $section->section);
 158              $duplicatesectionurl->param('duplicatesection', $section->section);
 159              $controls['duplicate'] = [
 160                  'url' => $duplicatesectionurl,
 161                  'icon' => 't/copy',
 162                  'name' => get_string('duplicate'),
 163                  'pixattr' => ['class' => ''],
 164                  'attr' => ['class' => 'icon duplicate'],
 165              ];
 166          }
 167  
 168          if ($section->section) {
 169              $url = clone($baseurl);
 170              if (!$isstealth) {
 171                  if (has_capability('moodle/course:sectionvisibility', $coursecontext, $user)) {
 172                      $strhidefromothers = get_string('hidefromothers', 'format_' . $course->format);
 173                      $strshowfromothers = get_string('showfromothers', 'format_' . $course->format);
 174                      if ($section->visible) { // Show the hide/show eye.
 175                          $url->param('hide', $section->section);
 176                          $controls['visiblity'] = [
 177                              'url' => $url,
 178                              'icon' => 'i/hide',
 179                              'name' => $strhidefromothers,
 180                              'pixattr' => ['class' => ''],
 181                              'attr' => [
 182                                  'class' => 'icon editing_showhide',
 183                                  'data-sectionreturn' => $sectionreturn,
 184                                  'data-action' => ($usecomponents) ? 'sectionHide' : 'hide',
 185                                  'data-id' => $section->id,
 186                                  'data-swapname' => $strshowfromothers,
 187                                  'data-swapicon' => 'i/show',
 188                              ],
 189                          ];
 190                      } else {
 191                          $url->param('show',  $section->section);
 192                          $controls['visiblity'] = [
 193                              'url' => $url,
 194                              'icon' => 'i/show',
 195                              'name' => $strshowfromothers,
 196                              'pixattr' => ['class' => ''],
 197                              'attr' => [
 198                                  'class' => 'icon editing_showhide',
 199                                  'data-sectionreturn' => $sectionreturn,
 200                                  'data-action' => ($usecomponents) ? 'sectionShow' : 'show',
 201                                  'data-id' => $section->id,
 202                                  'data-swapname' => $strhidefromothers,
 203                                  'data-swapicon' => 'i/hide',
 204                              ],
 205                          ];
 206                      }
 207                  }
 208  
 209                  if (!$sectionreturn && has_capability('moodle/course:movesections', $coursecontext, $user)) {
 210                      if ($usecomponents) {
 211                          // This tool will appear only when the state is ready.
 212                          $url = clone ($baseurl);
 213                          $url->param('movesection', $section->section);
 214                          $url->param('section', $section->section);
 215                          $controls['movesection'] = [
 216                              'url' => $url,
 217                              'icon' => 'i/dragdrop',
 218                              'name' => get_string('move', 'moodle'),
 219                              'pixattr' => ['class' => ''],
 220                              'attr' => [
 221                                  'class' => 'icon move waitstate',
 222                                  'data-action' => 'moveSection',
 223                                  'data-id' => $section->id,
 224                              ],
 225                          ];
 226                      }
 227                      // Legacy move up and down links for non component-based formats.
 228                      $url = clone($baseurl);
 229                      if ($section->section > 1) { // Add a arrow to move section up.
 230                          $url->param('section', $section->section);
 231                          $url->param('move', -1);
 232                          $strmoveup = get_string('moveup');
 233                          $controls['moveup'] = [
 234                              'url' => $url,
 235                              'icon' => 'i/up',
 236                              'name' => $strmoveup,
 237                              'pixattr' => ['class' => ''],
 238                              'attr' => ['class' => 'icon moveup whilenostate'],
 239                          ];
 240                      }
 241  
 242                      $url = clone($baseurl);
 243                      if ($section->section < $numsections) { // Add a arrow to move section down.
 244                          $url->param('section', $section->section);
 245                          $url->param('move', 1);
 246                          $strmovedown = get_string('movedown');
 247                          $controls['movedown'] = [
 248                              'url' => $url,
 249                              'icon' => 'i/down',
 250                              'name' => $strmovedown,
 251                              'pixattr' => ['class' => ''],
 252                              'attr' => ['class' => 'icon movedown whilenostate'],
 253                          ];
 254                      }
 255                  }
 256              }
 257  
 258              if (course_can_delete_section($course, $section)) {
 259                  if (get_string_manager()->string_exists('deletesection', 'format_'.$course->format)) {
 260                      $strdelete = get_string('deletesection', 'format_'.$course->format);
 261                  } else {
 262                      $strdelete = get_string('deletesection');
 263                  }
 264                  $url = new moodle_url(
 265                      '/course/editsection.php',
 266                      [
 267                          'id' => $section->id,
 268                          'sr' => $sectionreturn,
 269                          'delete' => 1,
 270                          'sesskey' => sesskey(),
 271                      ]
 272                  );
 273                  $controls['delete'] = [
 274                      'url' => $url,
 275                      'icon' => 'i/delete',
 276                      'name' => $strdelete,
 277                      'pixattr' => ['class' => ''],
 278                      'attr' => [
 279                          'class' => 'icon editing_delete text-danger',
 280                          'data-action' => 'deleteSection',
 281                          'data-id' => $section->id,
 282                      ],
 283                  ];
 284              }
 285          }
 286          if (
 287              has_any_capability([
 288                  'moodle/course:movesections',
 289                  'moodle/course:update',
 290                  'moodle/course:sectionvisibility',
 291              ], $coursecontext)
 292          ) {
 293              $sectionlink = new moodle_url(
 294                  '/course/view.php',
 295                  ['id' => $course->id],
 296                  "sectionid-{$section->id}-title"
 297              );
 298              $controls['permalink'] = [
 299                  'url' => $sectionlink,
 300                  'icon' => 'i/link',
 301                  'name' => get_string('sectionlink', 'course'),
 302                  'pixattr' => ['class' => ''],
 303                  'attr' => [
 304                      'class' => 'icon',
 305                      'data-action' => 'permalink',
 306                  ],
 307              ];
 308          }
 309  
 310          return $controls;
 311      }
 312  }