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  namespace core\output;
  18  
  19  use moodle_page;
  20  use renderer_base;
  21  use url_select;
  22  
  23  /**
  24   * Data structure representing standard components displayed on the activity header.
  25   *
  26   * Consists of title, header, description. In addition, additional_items can be provided which is a url_select
  27   *
  28   * @copyright 2021 Peter
  29   * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  30   * @since Moodle 4.0
  31   * @package core
  32   * @category output
  33   */
  34  class activity_header implements \renderable, \templatable {
  35      /** @var moodle_page $page The current page we are looking at */
  36      protected $page;
  37      /** @var string $title The title to be displayed in the header. Defaults to activityrecord name. */
  38      protected $title;
  39      /** @var string $description The description to be displayed. Defaults to activityrecord intro. */
  40      protected $description;
  41      /** @var \stdClass $user The user we are dealing with */
  42      protected $user;
  43      /** @var url_select $additionalnavitems Any additional custom navigation elements to be injected into template. */
  44      protected $additionalnavitems;
  45      /** @var bool $hidecompletion Whether to show completion criteria, if available, or not */
  46      protected $hidecompletion;
  47      /** @var bool $hideoverflow Whether to show the overflow data or not */
  48      protected $hideoverflow;
  49      /** @var bool $hideheader Whether or not to show the header */
  50      protected $hideheader;
  51  
  52      /**
  53       * Constructor for activity_header
  54       *
  55       * @param moodle_page $page
  56       * @param \stdClass $user
  57       */
  58      public function __construct(moodle_page $page, \stdClass $user) {
  59          $this->page = $page;
  60          $this->user = $user;
  61          $pageoptions = $this->page->theme->activityheaderconfig ?? [];
  62          $layoutoptions = $this->page->layout_options['activityheader'] ?? [];
  63          // Do a basic setup for the header based on theme/page options.
  64          if ($page->activityrecord) {
  65              if (empty($pageoptions['notitle']) && empty($layoutoptions['notitle'])) {
  66                  $this->title = format_string($page->activityrecord->name);
  67              }
  68  
  69              if (empty($layoutoptions['nodescription']) && !empty($page->activityrecord->intro) &&
  70                      trim($page->activityrecord->intro)) {
  71                  $this->description = format_module_intro($this->page->activityname, $page->activityrecord, $page->cm->id);
  72              }
  73          }
  74          $this->hidecompletion = !empty($layoutoptions['nocompletion']);
  75          $this->hideoverflow = false;
  76          $this->hideheader = false;
  77      }
  78  
  79      /**
  80       * Checks if the theme has specified titles to be displayed.
  81       *
  82       * @return bool
  83       */
  84      public function is_title_allowed(): bool {
  85          return empty($this->page->theme->activityheaderconfig['notitle']);
  86      }
  87  
  88      /**
  89       * Bulk set class member variables. Only updates variables which have corresponding setters
  90       *
  91       * @param mixed[] $config Array of variables to set, with keys being their name. Valid names/types as follows:
  92       *      'hidecompletion' => bool
  93       *      'additionalnavitems' => url_select
  94       *      'hideoverflow' => bool
  95       *      'title' => string
  96       *      'description' => string
  97       */
  98      public function set_attrs(array $config): void {
  99          foreach ($config as $key => $value) {
 100              if (method_exists($this, "set_$key")) {
 101                  $this->{"set_$key"}($value);
 102              } else {
 103                  debugging("Invalid class member variable: {$key}", DEBUG_DEVELOPER);
 104              }
 105          }
 106      }
 107  
 108      /**
 109       * Sets the hidecompletion class member variable
 110       *
 111       * @param bool $value
 112       */
 113      public function set_hidecompletion(bool $value): void {
 114          $this->hidecompletion = $value;
 115      }
 116  
 117      /**
 118       * Sets the additionalnavitems class member variable
 119       *
 120       * @param url_select $value
 121       */
 122      public function set_additionalnavitems(url_select $value): void {
 123          $this->additionalnavitems = $value;
 124      }
 125  
 126      /**
 127       * Sets the hideoverflow class member variable
 128       *
 129       * @param bool $value
 130       */
 131      public function set_hideoverflow(bool $value): void {
 132          $this->hideoverflow = $value;
 133      }
 134  
 135      /**
 136       * Sets the title class member variable.
 137       *
 138       * @param string $value
 139       */
 140      public function set_title(string $value): void {
 141          $this->title = preg_replace('/<h2[^>]*>([.\s\S]*)<\/h2>/', '$1', $value);
 142      }
 143  
 144      /**
 145       * Sets the description class member variable
 146       *
 147       * @param string $value
 148       */
 149      public function set_description(string $value): void {
 150          $this->description = $value;
 151      }
 152  
 153      /**
 154       * Disable the activity header completely. Use this if the page has some custom content, headings to be displayed.
 155       */
 156      public function disable(): void {
 157          $this->hideheader = true;
 158      }
 159  
 160      /**
 161       * Export items to be rendered with a template.
 162       *
 163       * @param renderer_base $output
 164       * @return array
 165       */
 166      public function export_for_template(renderer_base $output): array {
 167          // Don't need to show anything if not displaying within an activity context.
 168          if (!$this->page->activityrecord) {
 169              return [];
 170          }
 171  
 172          // If within an activity context but requesting to hide the header,
 173          // then just trigger the render for maincontent div.
 174          if ($this->hideheader) {
 175              return ['title' => ''];
 176          }
 177  
 178          $activityinfo = null;
 179          if (!$this->hidecompletion) {
 180              $completiondetails = \core_completion\cm_completion_details::get_instance($this->page->cm, $this->user->id);
 181              $activitydates = \core\activity_dates::get_dates_for_module($this->page->cm, $this->user->id);
 182  
 183              $activitycompletion = new \core_course\output\activity_completion($this->page->cm, $completiondetails);
 184              $activitycompletiondata = (array) $activitycompletion->export_for_template($output);
 185              $activitydates = new \core_course\output\activity_dates($activitydates);
 186              $activitydatesdata = (array) $activitydates->export_for_template($output);
 187              $data = array_merge($activitycompletiondata, $activitydatesdata);
 188  
 189              $activityinfo = $output->render_from_template('core_course/activity_info', $data);
 190          }
 191  
 192          $format = course_get_format($this->page->course);
 193          if ($format->supports_components()) {
 194              $this->page->requires->js_call_amd(
 195                  'core_courseformat/local/content/activity_header',
 196                  'init'
 197              );
 198          }
 199  
 200          return [
 201              'title' => $this->title,
 202              'description' => $this->description,
 203              'completion' => $activityinfo,
 204              'additional_items' => $this->hideoverflow ? '' : $this->additionalnavitems,
 205          ];
 206      }
 207  
 208      /**
 209       * Get the heading level for a given heading depending on whether the theme's activity header displays a heading
 210       * (usually the activity name).
 211       *
 212       * @param int $defaultlevel The default heading level when the activity header does not display a heading.
 213       * @return int
 214       */
 215      public function get_heading_level(int $defaultlevel = 2): int {
 216          // The heading level depends on whether the theme's activity header displays a heading (usually the activity name).
 217          $headinglevel = $defaultlevel;
 218          if ($this->is_title_allowed() && !empty(trim($this->title))) {
 219              // A heading for the activity name is displayed on this page with a heading level 2.
 220              // Increment the default level for this heading by 1.
 221              $headinglevel++;
 222          }
 223          return $headinglevel;
 224      }
 225  }