See Release Notes
Long Term Support Release
Differences Between: [Versions 310 and 401] [Versions 311 and 401] [Versions 39 and 401] [Versions 400 and 401] [Versions 401 and 402] [Versions 401 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 event class for displaying a calendar event. 19 * 20 * @package core_calendar 21 * @copyright 2017 Ryan Wyllie <ryan@moodle.com> 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 */ 24 25 namespace core_calendar\external; 26 27 defined('MOODLE_INTERNAL') || die(); 28 29 require_once($CFG->dirroot . "/calendar/lib.php"); 30 require_once($CFG->libdir . "/filelib.php"); 31 32 use \core\external\exporter; 33 use \core_calendar\local\event\container; 34 use \core_calendar\local\event\entities\event_interface; 35 use \core_calendar\local\event\entities\action_event_interface; 36 use \core_course\external\course_summary_exporter; 37 use \core\external\coursecat_summary_exporter; 38 use \renderer_base; 39 use moodle_url; 40 41 /** 42 * Class for displaying a calendar event. 43 * 44 * @package core_calendar 45 * @copyright 2017 Ryan Wyllie <ryan@moodle.com> 46 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 47 */ 48 class event_exporter_base extends exporter { 49 50 /** 51 * @var event_interface $event 52 */ 53 protected $event; 54 55 /** 56 * Constructor. 57 * 58 * @param event_interface $event 59 * @param array $related The related data. 60 */ 61 public function __construct(event_interface $event, $related = []) { 62 $this->event = $event; 63 64 $starttimestamp = $event->get_times()->get_start_time()->getTimestamp(); 65 $endtimestamp = $event->get_times()->get_end_time()->getTimestamp(); 66 $groupid = $event->get_group() ? $event->get_group()->get('id') : null; 67 $userid = $event->get_user() ? $event->get_user()->get('id') : null; 68 $categoryid = $event->get_category() ? $event->get_category()->get('id') : null; 69 70 $data = new \stdClass(); 71 $data->id = $event->get_id(); 72 $data->name = $event->get_name(); 73 $data->description = file_rewrite_pluginfile_urls( 74 $event->get_description()->get_value(), 75 'pluginfile.php', 76 $related['context']->id, 77 'calendar', 78 'event_description', 79 $event->get_id() 80 ); 81 $data->descriptionformat = $event->get_description()->get_format(); 82 $data->location = external_format_text($event->get_location(), FORMAT_PLAIN, $related['context']->id)[0]; 83 $data->groupid = $groupid; 84 $data->userid = $userid; 85 $data->categoryid = $categoryid; 86 $data->eventtype = $event->get_type(); 87 $data->timestart = $starttimestamp; 88 $data->timeduration = $endtimestamp - $starttimestamp; 89 $data->timesort = $event->get_times()->get_sort_time()->getTimestamp(); 90 $data->timeusermidnight = $event->get_times()->get_usermidnight_time()->getTimestamp(); 91 $data->visible = $event->is_visible() ? 1 : 0; 92 $data->timemodified = $event->get_times()->get_modified_time()->getTimestamp(); 93 $data->component = $event->get_component(); 94 $data->overdue = $data->timesort < time(); 95 96 if ($repeats = $event->get_repeats()) { 97 $data->repeatid = $repeats->get_id(); 98 $data->eventcount = $repeats->get_num() + 1; 99 } 100 101 if ($cm = $event->get_course_module()) { 102 $data->modulename = $cm->get('modname'); 103 $data->instance = $cm->get('id'); 104 $data->activityname = $cm->get('name'); 105 106 $component = 'mod_' . $data->modulename; 107 if (!component_callback_exists($component, 'core_calendar_get_event_action_string')) { 108 $modulename = get_string('modulename', $data->modulename); 109 $data->activitystr = get_string('requiresaction', 'calendar', $modulename); 110 } else { 111 $data->activitystr = component_callback( 112 $component, 113 'core_calendar_get_event_action_string', 114 [$event->get_type()] 115 ); 116 } 117 } 118 119 parent::__construct($data, $related); 120 } 121 122 /** 123 * Return the list of properties. 124 * 125 * @return array 126 */ 127 protected static function define_properties() { 128 return [ 129 'id' => ['type' => PARAM_INT], 130 'name' => ['type' => PARAM_TEXT], 131 'description' => [ 132 'type' => PARAM_RAW, 133 'optional' => true, 134 'default' => null, 135 'null' => NULL_ALLOWED 136 ], 137 'descriptionformat' => [ 138 'type' => PARAM_INT, 139 'optional' => true, 140 'default' => null, 141 'null' => NULL_ALLOWED 142 ], 143 'location' => [ 144 'type' => PARAM_RAW, 145 'optional' => true, 146 'default' => null, 147 'null' => NULL_ALLOWED 148 ], 149 'categoryid' => [ 150 'type' => PARAM_INT, 151 'optional' => true, 152 'default' => null, 153 'null' => NULL_ALLOWED 154 ], 155 'groupid' => [ 156 'type' => PARAM_INT, 157 'optional' => true, 158 'default' => null, 159 'null' => NULL_ALLOWED 160 ], 161 'userid' => [ 162 'type' => PARAM_INT, 163 'optional' => true, 164 'default' => null, 165 'null' => NULL_ALLOWED 166 ], 167 'repeatid' => [ 168 'type' => PARAM_INT, 169 'optional' => true, 170 'default' => null, 171 'null' => NULL_ALLOWED 172 ], 173 'eventcount' => [ 174 'type' => PARAM_INT, 175 'optional' => true, 176 'default' => null, 177 'null' => NULL_ALLOWED 178 ], 179 'component' => [ 180 'type' => PARAM_COMPONENT, 181 'optional' => true, 182 'default' => null, 183 'null' => NULL_ALLOWED 184 ], 185 'modulename' => [ 186 'type' => PARAM_TEXT, 187 'optional' => true, 188 'default' => null, 189 'null' => NULL_ALLOWED 190 ], 191 'activityname' => [ 192 'type' => PARAM_TEXT, 193 'optional' => true, 194 'default' => null, 195 'null' => NULL_ALLOWED 196 ], 197 'activitystr' => [ 198 'type' => PARAM_TEXT, 199 'optional' => true, 200 'default' => null, 201 'null' => NULL_ALLOWED 202 ], 203 'instance' => [ 204 'type' => PARAM_INT, 205 'optional' => true, 206 'default' => null, 207 'null' => NULL_ALLOWED 208 ], 209 'eventtype' => ['type' => PARAM_TEXT], 210 'timestart' => ['type' => PARAM_INT], 211 'timeduration' => ['type' => PARAM_INT], 212 'timesort' => ['type' => PARAM_INT], 213 'timeusermidnight' => ['type' => PARAM_INT], 214 'visible' => ['type' => PARAM_INT], 215 'timemodified' => ['type' => PARAM_INT], 216 'overdue' => [ 217 'type' => PARAM_BOOL, 218 'optional' => true, 219 'default' => false, 220 'null' => NULL_ALLOWED 221 ], 222 ]; 223 } 224 225 /** 226 * Return the list of additional properties. 227 * 228 * @return array 229 */ 230 protected static function define_other_properties() { 231 return [ 232 'icon' => [ 233 'type' => event_icon_exporter::read_properties_definition(), 234 ], 235 'category' => [ 236 'type' => coursecat_summary_exporter::read_properties_definition(), 237 'optional' => true, 238 ], 239 'course' => [ 240 'type' => course_summary_exporter::read_properties_definition(), 241 'optional' => true, 242 ], 243 'subscription' => [ 244 'type' => event_subscription_exporter::read_properties_definition(), 245 'optional' => true, 246 ], 247 'canedit' => [ 248 'type' => PARAM_BOOL 249 ], 250 'candelete' => [ 251 'type' => PARAM_BOOL 252 ], 253 'deleteurl' => [ 254 'type' => PARAM_URL 255 ], 256 'editurl' => [ 257 'type' => PARAM_URL 258 ], 259 'viewurl' => [ 260 'type' => PARAM_URL 261 ], 262 'formattedtime' => [ 263 'type' => PARAM_RAW, 264 ], 265 'formattedlocation' => [ 266 'type' => PARAM_RAW, 267 ], 268 'isactionevent' => [ 269 'type' => PARAM_BOOL 270 ], 271 'iscourseevent' => [ 272 'type' => PARAM_BOOL 273 ], 274 'iscategoryevent' => [ 275 'type' => PARAM_BOOL 276 ], 277 'groupname' => [ 278 'type' => PARAM_RAW, 279 'optional' => true, 280 'default' => null, 281 'null' => NULL_ALLOWED 282 ], 283 'normalisedeventtype' => [ 284 'type' => PARAM_TEXT 285 ], 286 'normalisedeventtypetext' => [ 287 'type' => PARAM_TEXT 288 ], 289 'action' => [ 290 'type' => event_action_exporter::read_properties_definition(), 291 'optional' => true, 292 ], 293 'purpose' => [ 294 'type' => PARAM_TEXT 295 ], 296 ]; 297 } 298 299 /** 300 * Get the additional values to inject while exporting. 301 * 302 * @param renderer_base $output The renderer. 303 * @return array Keys are the property names, values are their values. 304 */ 305 protected function get_other_values(renderer_base $output) { 306 $values = []; 307 $event = $this->event; 308 $legacyevent = container::get_event_mapper()->from_event_to_legacy_event($event); 309 $context = $this->related['context']; 310 $course = $this->related['course']; 311 $values['isactionevent'] = false; 312 $values['iscourseevent'] = false; 313 $values['iscategoryevent'] = false; 314 $values['normalisedeventtype'] = $event->get_type(); 315 if ($moduleproxy = $event->get_course_module()) { 316 // We need a separate property to flag if an event is action event. 317 // That's required because canedit return true but action action events cannot be edited on the calendar UI. 318 // But they are considered editable because you can drag and drop the event on the month view. 319 $values['isactionevent'] = true; 320 // Activity events are normalised to "look" like course events. 321 $values['normalisedeventtype'] = 'course'; 322 } else if ($event->get_type() == 'course') { 323 $values['iscourseevent'] = true; 324 } else if ($event->get_type() == 'category') { 325 $values['iscategoryevent'] = true; 326 } 327 $timesort = $event->get_times()->get_sort_time()->getTimestamp(); 328 $iconexporter = new event_icon_exporter($event, ['context' => $context]); 329 $identifier = 'type' . $values['normalisedeventtype']; 330 $stringexists = get_string_manager()->string_exists($identifier, 'calendar'); 331 if (!$stringexists) { 332 // Property normalisedeventtype is used to build the name of the CSS class for the events. 333 $values['normalisedeventtype'] = 'other'; 334 } 335 $values['normalisedeventtypetext'] = $stringexists ? get_string($identifier, 'calendar') : ''; 336 337 $purpose = 'none'; 338 if ($moduleproxy) { 339 $purpose = plugin_supports('mod', $moduleproxy->get('modname'), FEATURE_MOD_PURPOSE, 'none'); 340 } 341 $values['purpose'] = $purpose; 342 343 $values['icon'] = $iconexporter->export($output); 344 345 $subscriptionexporter = new event_subscription_exporter($event); 346 $values['subscription'] = $subscriptionexporter->export($output); 347 348 $proxy = $this->event->get_category(); 349 if ($proxy && $proxy->get('id')) { 350 $category = $proxy->get_proxied_instance(); 351 $categorysummaryexporter = new coursecat_summary_exporter($category, ['context' => $context]); 352 $values['category'] = $categorysummaryexporter->export($output); 353 } 354 355 if ($course && $course->id != SITEID) { 356 $coursesummaryexporter = new course_summary_exporter($course, ['context' => $context]); 357 $values['course'] = $coursesummaryexporter->export($output); 358 } 359 360 $courseid = (!$course) ? SITEID : $course->id; 361 362 $values['canedit'] = calendar_edit_event_allowed($legacyevent, true); 363 $values['candelete'] = calendar_delete_event_allowed($legacyevent); 364 365 $deleteurl = new moodle_url('/calendar/delete.php', ['id' => $event->get_id(), 'course' => $courseid]); 366 $values['deleteurl'] = $deleteurl->out(false); 367 368 $editurl = new moodle_url('/calendar/event.php', ['action' => 'edit', 'id' => $event->get_id(), 369 'course' => $courseid]); 370 $values['editurl'] = $editurl->out(false); 371 $viewurl = new moodle_url('/calendar/view.php', ['view' => 'day', 'course' => $courseid, 372 'time' => $timesort]); 373 $viewurl->set_anchor('event_' . $event->get_id()); 374 $values['viewurl'] = $viewurl->out(false); 375 $values['formattedtime'] = calendar_format_event_time($legacyevent, time(), null, false, 376 $timesort); 377 $values['formattedlocation'] = calendar_format_event_location($legacyevent); 378 379 if ($group = $event->get_group()) { 380 $values['groupname'] = format_string($group->get('name'), true, 381 ['context' => \context_course::instance($event->get_course()->get('id'))]); 382 } 383 384 if ($event instanceof action_event_interface) { 385 // Export event action if applicable. 386 $actionrelated = [ 387 'context' => $this->related['context'], 388 'event' => $event 389 ]; 390 $actionexporter = new event_action_exporter($event->get_action(), $actionrelated); 391 $values['action'] = $actionexporter->export($output); 392 } 393 394 return $values; 395 } 396 397 /** 398 * Returns a list of objects that are related. 399 * 400 * @return array 401 */ 402 protected static function define_related() { 403 return [ 404 'context' => 'context', 405 'course' => 'stdClass?', 406 ]; 407 } 408 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body