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