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