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.
   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  namespace core_courseformat\output\local\content\cm;
  18  
  19  use cm_info;
  20  use core_courseformat\base as course_format;
  21  use core_courseformat\output\local\courseformat_named_templatable;
  22  use core\output\named_templatable;
  23  use core\output\choicelist;
  24  use core\output\local\dropdown\status;
  25  use pix_icon;
  26  use renderable;
  27  use section_info;
  28  use stdClass;
  29  
  30  /**
  31   * Base class to render an activity group mode badge.
  32   *
  33   * @package   core_courseformat
  34   * @copyright 2023 Ferran Recio <ferran@moodle.com>
  35   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  36   */
  37  class groupmode implements named_templatable, renderable {
  38  
  39      use courseformat_named_templatable;
  40  
  41      /** @var course_format the course format */
  42      protected $format;
  43  
  44      /** @var section_info the section object */
  45      private $section;
  46  
  47      /** @var cm_info the course module instance */
  48      protected $mod;
  49  
  50      /**
  51       * Constructor.
  52       *
  53       * @param course_format $format the course format
  54       * @param section_info $section the section info
  55       * @param cm_info $mod the course module ionfo
  56       */
  57      public function __construct(
  58          course_format $format,
  59          section_info $section,
  60          cm_info $mod,
  61      ) {
  62          $this->format = $format;
  63          $this->section = $section;
  64          $this->mod = $mod;
  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 stdClass|null data context for a mustache template
  72       */
  73      public function export_for_template(\renderer_base $output): ?stdClass {
  74          if (!$this->format->show_groupmode($this->mod)) {
  75              return null;
  76          }
  77          if ($this->format->show_editor() && $this->format->supports_components()) {
  78              return $this->build_editor_data($output);
  79          }
  80          // If the group mode is not editable, the no groups badge is not displayed.
  81          if ($this->mod->effectivegroupmode === NOGROUPS) {
  82              return null;
  83          }
  84          return $this->build_static_data($output);
  85      }
  86  
  87      /**
  88       * Build the data for the static badge.
  89       * @param \renderer_base $output
  90       * @return stdClass
  91       */
  92      protected function build_static_data(\renderer_base $output): stdClass {
  93          switch ($this->mod->effectivegroupmode) {
  94              case SEPARATEGROUPS:
  95                  $groupalt = get_string('groupsseparate', 'group');
  96                  $groupicon = $this->get_action_icon('cmSeparateGroups', $groupalt);
  97                  break;
  98              case VISIBLEGROUPS:
  99                  $groupalt = get_string('groupsvisible', 'group');
 100                  $groupicon = $this->get_action_icon('cmVisibleGroups', $groupalt);
 101                  break;
 102              case NOGROUPS:
 103              default:
 104                  $groupalt = get_string('groupsnone', 'group');
 105                  $groupicon = $this->get_action_icon('cmNoGroups', $groupalt);
 106                  break;
 107          }
 108          $data = (object) [
 109              'groupicon' => $output->render($groupicon),
 110              'groupalt' => $groupalt,
 111              'isInteractive' => false,
 112          ];
 113          return $data;
 114      }
 115  
 116      /**
 117       * Build the data for the interactive dropdown.
 118       * @param \renderer_base $output
 119       * @return stdClass
 120       */
 121      protected function build_editor_data(\renderer_base $output): stdClass {
 122          $choice = $this->get_choice_list();
 123          $result = $this->get_dropdown_data($output, $choice);
 124          $result->autohide = ($this->mod->effectivegroupmode === NOGROUPS);
 125          return $result;
 126      }
 127  
 128      /**
 129       * Build the data for the interactive dropdown.
 130       * @param \renderer_base $output
 131       * @param choicelist $choice the choice list
 132       * @return stdClass
 133       */
 134      protected function get_dropdown_data(\renderer_base $output, choicelist $choice): stdClass {
 135          $buttondata = $this->build_static_data($output);
 136          $dropdown = new status(
 137              $buttondata->groupicon,
 138              $choice,
 139              ['dialogwidth' => status::WIDTH['big']],
 140          );
 141          $dropdown->set_dialog_width(status::WIDTH['small']);
 142          $dropdown->set_position(status::POSITION['end']);
 143          return (object) [
 144              'isInteractive' => true,
 145              'groupicon' => $buttondata->groupicon,
 146              'groupalt' => $buttondata->groupalt,
 147              'dropwdown' => $dropdown->export_for_template($output),
 148          ];
 149      }
 150  
 151      /**
 152       * Create a choice list for the dropdown.
 153       * @return choicelist the choice list
 154       */
 155      public function get_choice_list(): choicelist {
 156          $choice = new choicelist();
 157          $choice->add_option(
 158              NOGROUPS,
 159              get_string('groupsnone', 'group'),
 160              $this->get_option_data(null, 'cmNoGroups', $this->mod->id)
 161          );
 162          $choice->add_option(
 163              SEPARATEGROUPS,
 164              get_string('groupsseparate', 'group'),
 165              $this->get_option_data('groupsseparate', 'cmSeparateGroups', $this->mod->id)
 166          );
 167          $choice->add_option(
 168              VISIBLEGROUPS,
 169              get_string('groupsvisible', 'group'),
 170              $this->get_option_data('groupsvisible', 'cmVisibleGroups', $this->mod->id)
 171          );
 172          $choice->set_selected_value($this->mod->effectivegroupmode);
 173          return $choice;
 174      }
 175  
 176      /**
 177       * Get the data for the option.
 178       * @param string|null $name the name of the option
 179       * @param string $action the state action of the option
 180       * @param int $id the id of the module
 181       * @return array
 182       */
 183      private function get_option_data(?string $name, string $action, int $id): array {
 184          return [
 185              'description' => ($name) ? get_string("groupmode_{$name}_help", 'group') : null,
 186              // The dropdown icons are decorative, so we don't need to provide alt text.
 187              'icon' => $this->get_action_icon($action),
 188              'extras' => [
 189                  'data-id' => $id,
 190                  'data-action' => $action,
 191              ]
 192          ];
 193      }
 194  
 195      /**
 196       * Get the group mode icon.
 197       * @param string $groupmode the group mode
 198       * @param string $groupalt the alt text
 199       * @return pix_icon
 200       */
 201      protected function get_action_icon(string $groupmode, string $groupalt = ''): pix_icon {
 202          $icons = [
 203              'cmNoGroups' => 'i/groupn',
 204              'cmSeparateGroups' => 'i/groups',
 205              'cmVisibleGroups' => 'i/groupv',
 206          ];
 207          return new pix_icon($icons[$groupmode], $groupalt);
 208      }
 209  }