Differences Between: [Versions 400 and 402] [Versions 401 and 402] [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 activity list from a section. 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; 26 27 use cm_info; 28 use context_course; 29 use core\activity_dates; 30 use core\output\named_templatable; 31 use core_availability\info_module; 32 use core_completion\cm_completion_details; 33 use core_course\output\activity_information; 34 use core_courseformat\base as course_format; 35 use core_courseformat\output\local\courseformat_named_templatable; 36 use renderable; 37 use renderer_base; 38 use section_info; 39 use stdClass; 40 41 /** 42 * Base class to render a course module inside a course format. 43 * 44 * @package core_courseformat 45 * @copyright 2020 Ferran Recio <ferran@moodle.com> 46 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 47 */ 48 class cm implements named_templatable, renderable { 49 use courseformat_named_templatable; 50 51 /** @var course_format the course format */ 52 protected $format; 53 54 /** @var section_info the section object */ 55 private $section; 56 57 /** @var cm_info the course module instance */ 58 protected $mod; 59 60 /** @var array optional display options */ 61 protected $displayoptions; 62 63 /** @var string the activity name output class name */ 64 protected $cmnameclass; 65 66 /** @var string the activity control menu class name */ 67 protected $controlmenuclass; 68 69 /** @var string the activity availability class name */ 70 protected $availabilityclass; 71 72 /** 73 * Constructor. 74 * 75 * @param course_format $format the course format 76 * @param section_info $section the section info 77 * @param cm_info $mod the course module ionfo 78 * @param array $displayoptions optional extra display options 79 */ 80 public function __construct(course_format $format, section_info $section, cm_info $mod, array $displayoptions = []) { 81 $this->format = $format; 82 $this->section = $section; 83 $this->mod = $mod; 84 85 // Add extra display options. 86 $this->displayoptions = $displayoptions; 87 $this->load_classes(); 88 89 // Get the necessary classes. 90 $this->cmnameclass = $format->get_output_classname('content\\cm\\cmname'); 91 $this->controlmenuclass = $format->get_output_classname('content\\cm\\controlmenu'); 92 $this->availabilityclass = $format->get_output_classname('content\\cm\\availability'); 93 } 94 95 /** 96 * Export this data so it can be used as the context for a mustache template. 97 * 98 * @param renderer_base $output typically, the renderer that's calling this function 99 * @return stdClass data context for a mustache template 100 */ 101 public function export_for_template(renderer_base $output): stdClass { 102 $mod = $this->mod; 103 $displayoptions = $this->displayoptions; 104 105 $data = (object)[ 106 'grouping' => $mod->get_grouping_label($displayoptions['textclasses']), 107 'modname' => get_string('pluginname', 'mod_' . $mod->modname), 108 'url' => $mod->url, 109 'activityname' => $mod->get_formatted_name(), 110 'textclasses' => $displayoptions['textclasses'], 111 'classlist' => [], 112 'cmid' => $mod->id, 113 ]; 114 115 // Add partial data segments. 116 $haspartials = []; 117 $haspartials['cmname'] = $this->add_cm_name_data($data, $output); 118 $haspartials['availability'] = $this->add_availability_data($data, $output); 119 $haspartials['alternative'] = $this->add_alternative_content_data($data, $output); 120 $haspartials['completion'] = $this->add_completion_data($data, $output); 121 $haspartials['editor'] = $this->add_editor_data($data, $output); 122 $this->add_format_data($data, $haspartials, $output); 123 124 // Calculated fields. 125 if (!empty($data->url)) { 126 $data->hasurl = true; 127 } 128 129 return $data; 130 } 131 132 /** 133 * Add course module name attributes to the data structure. 134 * 135 * @param stdClass $data the current cm data reference 136 * @param renderer_base $output typically, the renderer that's calling this function 137 * @return bool if the cm has name data 138 */ 139 protected function add_cm_name_data(stdClass &$data, renderer_base $output): bool { 140 // Mod inplace name editable. 141 $cmname = new $this->cmnameclass( 142 $this->format, 143 $this->section, 144 $this->mod, 145 null, 146 $this->displayoptions 147 ); 148 $data->cmname = $cmname->export_for_template($output); 149 $data->hasname = $cmname->has_name(); 150 return $data->hasname; 151 } 152 153 /** 154 * Add the module availability to the data structure. 155 * 156 * @param stdClass $data the current cm data reference 157 * @param renderer_base $output typically, the renderer that's calling this function 158 * @return bool if the cm has mod availability 159 */ 160 protected function add_availability_data(stdClass &$data, renderer_base $output): bool { 161 if (!$this->mod->visible) { 162 $data->modavailability = null; 163 return false; 164 } 165 // Mod availability output class. 166 $availability = new $this->availabilityclass( 167 $this->format, 168 $this->section, 169 $this->mod, 170 $this->displayoptions 171 ); 172 $modavailability = $availability->export_for_template($output); 173 $data->modavailability = $modavailability; 174 return $availability->has_availability($output); 175 } 176 177 /** 178 * Add the alternative content to the data structure. 179 * 180 * @param stdClass $data the current cm data reference 181 * @param renderer_base $output typically, the renderer that's calling this function 182 * @return bool if the cm has alternative content 183 */ 184 protected function add_alternative_content_data(stdClass &$data, renderer_base $output): bool { 185 $altcontent = $this->mod->get_formatted_content( 186 ['overflowdiv' => true, 'noclean' => true] 187 ); 188 $data->altcontent = (empty($altcontent)) ? false : $altcontent; 189 $data->afterlink = $this->mod->afterlink; 190 return !empty($data->altcontent); 191 } 192 193 /** 194 * Add activity completion information to the data structure. 195 * 196 * @param stdClass $data the current cm data reference 197 * @param renderer_base $output typically, the renderer that's calling this function 198 * @return bool the module has completion information 199 */ 200 protected function add_completion_data(stdClass &$data, renderer_base $output): bool { 201 global $USER; 202 $course = $this->mod->get_course(); 203 // Fetch completion details. 204 $showcompletionconditions = $course->showcompletionconditions == COMPLETION_SHOW_CONDITIONS; 205 $completiondetails = cm_completion_details::get_instance($this->mod, $USER->id, $showcompletionconditions); 206 207 // Fetch activity dates. 208 $activitydates = []; 209 if ($course->showactivitydates) { 210 $activitydates = activity_dates::get_dates_for_module($this->mod, $USER->id); 211 } 212 213 $activityinfodata = (object) ['hasdates' => false, 'hascompletion' => false]; 214 // There are activity dates to be shown; or 215 // Completion info needs to be displayed 216 // * The activity tracks completion; AND 217 // * The showcompletionconditions setting is enabled OR an activity that tracks manual 218 // completion needs the manual completion button to be displayed on the course homepage. 219 $showcompletioninfo = $completiondetails->has_completion() && ($showcompletionconditions || 220 (!$completiondetails->is_automatic() && $completiondetails->show_manual_completion())); 221 if ($showcompletioninfo || !empty($activitydates)) { 222 $activityinfo = new activity_information($this->mod, $completiondetails, $activitydates); 223 $activityinfodata = $activityinfo->export_for_template($output); 224 } 225 226 $data->activityinfo = $activityinfodata; 227 return $activityinfodata->hascompletion; 228 } 229 230 /** 231 * Add activity information to the data structure. 232 * 233 * @param stdClass $data the current cm data reference 234 * @param bool[] $haspartials the result of loading partial data elements 235 * @param renderer_base $output typically, the renderer that's calling this function 236 * @return bool if the cm has format data 237 */ 238 protected function add_format_data(stdClass &$data, array $haspartials, renderer_base $output): bool { 239 $result = false; 240 // Legacy indentation. 241 if (!empty($this->mod->indent) && $this->format->uses_indentation()) { 242 $data->indent = $this->mod->indent; 243 if ($this->mod->indent > 15) { 244 $data->hugeindent = true; 245 $result = true; 246 } 247 } 248 // Stealth and hidden from student. 249 if (!$this->mod->visible) { 250 // This module is hidden but current user has capability to see it. 251 $data->modhiddenfromstudents = true; 252 $result = true; 253 } else if ($this->mod->is_stealth()) { 254 // This module is available but is normally not displayed on the course page 255 // (this user can see it because they can manage it). 256 $data->modstealth = true; 257 $result = true; 258 } 259 // Special inline activity format. 260 if ( 261 $this->mod->has_custom_cmlist_item() && 262 !$haspartials['availability'] && 263 !$haspartials['completion'] && 264 !isset($data->modhiddenfromstudents) && 265 !isset($data->modstealth) && 266 !$this->format->show_editor() 267 ) { 268 $data->modinline = true; 269 $result = true; 270 } 271 return $result; 272 } 273 274 /** 275 * Add course editor attributes to the data structure. 276 * 277 * @param stdClass $data the current cm data reference 278 * @param renderer_base $output typically, the renderer that's calling this function 279 * @return bool if the cm has editor data 280 */ 281 protected function add_editor_data(stdClass &$data, renderer_base $output): bool { 282 $course = $this->format->get_course(); 283 $coursecontext = context_course::instance($course->id); 284 $editcaps = []; 285 if (has_capability('moodle/course:activityvisibility', $coursecontext)) { 286 $editcaps = ['moodle/course:activityvisibility']; 287 } 288 if (!$this->format->show_editor($editcaps)) { 289 return false; 290 } 291 $returnsection = $this->format->get_section_number(); 292 // Edit actions. 293 $controlmenu = new $this->controlmenuclass( 294 $this->format, 295 $this->section, 296 $this->mod, 297 $this->displayoptions 298 ); 299 $data->controlmenu = $controlmenu->export_for_template($output); 300 if (!$this->format->supports_components()) { 301 // Add the legacy YUI move link. 302 $data->moveicon = course_get_cm_move($this->mod, $returnsection); 303 } 304 return true; 305 } 306 307 /** 308 * Returns the CSS classes for the activity name/content 309 * 310 */ 311 protected function load_classes() { 312 $mod = $this->mod; 313 314 $linkclasses = ''; 315 $textclasses = ''; 316 if ($mod->uservisible) { 317 $info = new info_module($mod); 318 $conditionalhidden = !$info->is_available_for_all(); 319 $accessiblebutdim = (!$mod->visible || $conditionalhidden) && 320 has_capability('moodle/course:viewhiddenactivities', $mod->context); 321 if ($accessiblebutdim && $conditionalhidden) { 322 $linkclasses .= ' conditionalhidden'; 323 $textclasses .= ' conditionalhidden'; 324 } 325 } 326 $this->displayoptions['linkclasses'] = $linkclasses; 327 $this->displayoptions['textclasses'] = $textclasses; 328 $this->displayoptions['onclick'] = htmlspecialchars_decode($mod->onclick, ENT_QUOTES);; 329 } 330 331 /** 332 * Get the activity link classes. 333 * 334 * @return string the activity link classes. 335 */ 336 public function get_link_classes(): string { 337 return $this->displayoptions['linkclasses'] ?? ''; 338 } 339 340 /** 341 * Get the activity text/description classes. 342 * 343 * @return string the activity text classes. 344 */ 345 public function get_text_classes(): string { 346 return $this->displayoptions['textclasses'] ?? ''; 347 } 348 349 /** 350 * Get the activity onclick code. 351 * 352 * @return string the activity onclick. 353 */ 354 public function get_onclick_code(): string { 355 return $this->displayoptions['onclick']; 356 } 357 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body