See Release Notes
Long Term Support Release
Differences Between: [Versions 39 and 400] [Versions 39 and 401] [Versions 39 and 402] [Versions 39 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 class containing the internal calendar API. 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\local; 26 27 defined('MOODLE_INTERNAL') || die(); 28 29 use core_calendar\local\event\container; 30 use core_calendar\local\event\entities\event_interface; 31 use core_calendar\local\event\exceptions\limit_invalid_parameter_exception; 32 33 /** 34 * Class containing the local calendar API. 35 * 36 * This should not be used outside of core_calendar. 37 * 38 * @package core_calendar 39 * @copyright 2017 Ryan Wyllie <ryan@moodle.com> 40 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 41 */ 42 class api { 43 /** 44 * Get all events restricted by various parameters, taking in to account user and group overrides. 45 * 46 * @param int|null $timestartfrom Events with timestart from this value (inclusive). 47 * @param int|null $timestartto Events with timestart until this value (inclusive). 48 * @param int|null $timesortfrom Events with timesort from this value (inclusive). 49 * @param int|null $timesortto Events with timesort until this value (inclusive). 50 * @param int|null $timestartaftereventid Restrict the events in the timestart range to ones after this ID. 51 * @param int|null $timesortaftereventid Restrict the events in the timesort range to ones after this ID. 52 * @param int $limitnum Return at most this number of events. 53 * @param int|null $type Return only events of this type. 54 * @param array|null $usersfilter Return only events for these users. 55 * @param array|null $groupsfilter Return only events for these groups. 56 * @param array|null $coursesfilter Return only events for these courses. 57 * @param bool $withduration If true return only events starting within specified 58 * timestart otherwise return in progress events as well. 59 * @param bool $ignorehidden If true don't return hidden events. 60 * @return \core_calendar\local\event\entities\event_interface[] Array of event_interfaces. 61 */ 62 public static function get_events( 63 $timestartfrom = null, 64 $timestartto = null, 65 $timesortfrom = null, 66 $timesortto = null, 67 $timestartaftereventid = null, 68 $timesortaftereventid = null, 69 $limitnum = 20, 70 $type = null, 71 array $usersfilter = null, 72 array $groupsfilter = null, 73 array $coursesfilter = null, 74 array $categoriesfilter = null, 75 $withduration = true, 76 $ignorehidden = true, 77 callable $filter = null 78 ) { 79 global $USER; 80 81 $vault = \core_calendar\local\event\container::get_event_vault(); 82 83 $timestartafterevent = null; 84 $timesortafterevent = null; 85 86 if ($timestartaftereventid && $event = $vault->get_event_by_id($timestartaftereventid)) { 87 $timestartafterevent = $event; 88 } 89 90 if ($timesortaftereventid && $event = $vault->get_event_by_id($timesortaftereventid)) { 91 $timesortafterevent = $event; 92 } 93 94 return $vault->get_events( 95 $timestartfrom, 96 $timestartto, 97 $timesortfrom, 98 $timesortto, 99 $timestartafterevent, 100 $timesortafterevent, 101 $limitnum, 102 $type, 103 $usersfilter, 104 $groupsfilter, 105 $coursesfilter, 106 $categoriesfilter, 107 $withduration, 108 $ignorehidden, 109 $filter 110 ); 111 } 112 113 /** 114 * Get a list of action events for the logged in user by the given 115 * timesort values. 116 * 117 * @param int|null $timesortfrom The start timesort value (inclusive) 118 * @param int|null $timesortto The end timesort value (inclusive) 119 * @param int|null $aftereventid Only return events after this one 120 * @param int $limitnum Limit results to this amount (between 1 and 50) 121 * @param bool $lmittononsuspendedevents Limit course events to courses the user is active in (not suspended). 122 * @param \stdClass|null $user The user id or false for $USER 123 * @return array A list of action_event_interface objects 124 * @throws \moodle_exception 125 */ 126 public static function get_action_events_by_timesort( 127 $timesortfrom = null, 128 $timesortto = null, 129 $aftereventid = null, 130 $limitnum = 20, 131 $limittononsuspendedevents = false, 132 ?\stdClass $user = null 133 ) { 134 global $USER; 135 136 if (!$user) { 137 $user = $USER; 138 } 139 140 if (is_null($timesortfrom) && is_null($timesortto)) { 141 throw new \moodle_exception("Must provide a timesort to and/or from value"); 142 } 143 144 if ($limitnum < 1 || $limitnum > 50) { 145 throw new \moodle_exception("Limit must be between 1 and 50 (inclusive)"); 146 } 147 148 \core_calendar\local\event\container::set_requesting_user($user->id); 149 $vault = \core_calendar\local\event\container::get_event_vault(); 150 151 $afterevent = null; 152 if ($aftereventid && $event = $vault->get_event_by_id($aftereventid)) { 153 $afterevent = $event; 154 } 155 156 return $vault->get_action_events_by_timesort($user, $timesortfrom, $timesortto, $afterevent, $limitnum, 157 $limittononsuspendedevents); 158 } 159 160 /** 161 * Get a list of action events for the logged in user by the given 162 * course and timesort values. 163 * 164 * @param \stdClass $course The course the events must belong to 165 * @param int|null $timesortfrom The start timesort value (inclusive) 166 * @param int|null $timesortto The end timesort value (inclusive) 167 * @param int|null $aftereventid Only return events after this one 168 * @param int $limitnum Limit results to this amount (between 1 and 50) 169 * @return array A list of action_event_interface objects 170 * @throws limit_invalid_parameter_exception 171 */ 172 public static function get_action_events_by_course( 173 $course, 174 $timesortfrom = null, 175 $timesortto = null, 176 $aftereventid = null, 177 $limitnum = 20 178 ) { 179 global $USER; 180 181 if ($limitnum < 1 || $limitnum > 50) { 182 throw new limit_invalid_parameter_exception( 183 "Limit must be between 1 and 50 (inclusive)"); 184 } 185 186 $vault = \core_calendar\local\event\container::get_event_vault(); 187 188 $afterevent = null; 189 if ($aftereventid && $event = $vault->get_event_by_id($aftereventid)) { 190 $afterevent = $event; 191 } 192 193 return $vault->get_action_events_by_course( 194 $USER, $course, $timesortfrom, $timesortto, $afterevent, $limitnum); 195 } 196 197 /** 198 * Get a list of action events for the logged in user by the given 199 * courses and timesort values. 200 * 201 * The limit number applies per course, not for the result set as a whole. 202 * E.g. Requesting 3 courses with a limit of 10 will result in up to 30 203 * events being returned (up to 10 per course). 204 * 205 * @param array $courses The courses the events must belong to 206 * @param int|null $timesortfrom The start timesort value (inclusive) 207 * @param int|null $timesortto The end timesort value (inclusive) 208 * @param int $limitnum Limit results per course to this amount (between 1 and 50) 209 * @return array A list of action_event_interface objects indexed by course id 210 */ 211 public static function get_action_events_by_courses( 212 $courses = [], 213 $timesortfrom = null, 214 $timesortto = null, 215 $limitnum = 20 216 ) { 217 $return = []; 218 219 foreach ($courses as $course) { 220 $return[$course->id] = self::get_action_events_by_course( 221 $course, 222 $timesortfrom, 223 $timesortto, 224 null, 225 $limitnum 226 ); 227 } 228 229 return $return; 230 } 231 232 /** 233 * Change the start day for an event. Only the date will be 234 * modified, the time of day for the event will be left as is. 235 * 236 * @param event_interface $event The existing event to modify 237 * @param DateTimeInterface $startdate The new date to use for the start day 238 * @return event_interface The new event with updated start date 239 */ 240 public static function update_event_start_day( 241 event_interface $event, 242 \DateTimeInterface $startdate 243 ) { 244 global $DB; 245 246 $mapper = container::get_event_mapper(); 247 $legacyevent = $mapper->from_event_to_legacy_event($event); 248 $hascoursemodule = !empty($event->get_course_module()); 249 $moduleinstance = null; 250 $starttime = $event->get_times()->get_start_time()->setDate( 251 $startdate->format('Y'), 252 $startdate->format('n'), 253 $startdate->format('j') 254 ); 255 $starttimestamp = $starttime->getTimestamp(); 256 257 if ($hascoursemodule) { 258 $moduleinstance = $DB->get_record( 259 $event->get_course_module()->get('modname'), 260 ['id' => $event->get_course_module()->get('instance')], 261 '*', 262 MUST_EXIST 263 ); 264 265 // If there is a timestart range callback implemented then we can 266 // use the values returned from the valid timestart range to apply 267 // some default validation on the event's timestart value to ensure 268 // that it falls within the specified range. 269 list($min, $max) = component_callback( 270 'mod_' . $event->get_course_module()->get('modname'), 271 'core_calendar_get_valid_event_timestart_range', 272 [$legacyevent, $moduleinstance], 273 [false, false] 274 ); 275 } else if ($legacyevent->courseid != 0 && $legacyevent->courseid != SITEID && $legacyevent->groupid == 0) { 276 // This is a course event. 277 list($min, $max) = component_callback( 278 'core_course', 279 'core_calendar_get_valid_event_timestart_range', 280 [$legacyevent, $event->get_course()->get_proxied_instance()], 281 [0, 0] 282 ); 283 } else { 284 $min = $max = 0; 285 } 286 287 // If the callback returns false for either value it means that 288 // there is no valid time start range. 289 if ($min === false || $max === false) { 290 throw new \moodle_exception('The start day of this event can not be modified'); 291 } 292 293 if ($min && $starttimestamp < $min[0]) { 294 throw new \moodle_exception($min[1]); 295 } 296 297 if ($max && $starttimestamp > $max[0]) { 298 throw new \moodle_exception($max[1]); 299 } 300 301 // This function does our capability checks. 302 $legacyevent->update((object) ['timestart' => $starttime->getTimestamp()]); 303 304 // Check that the user is allowed to manually edit calendar events before 305 // calling the event updated callback. The manual flag causes the code to 306 // check the user has the capabilities to modify the modules. 307 // 308 // We don't want to call the event update callback if the user isn't allowed 309 // to modify course modules because depending on the callback it can make 310 // some changes that would be considered security issues, such as updating the 311 // due date for an assignment. 312 if ($hascoursemodule && calendar_edit_event_allowed($legacyevent, true)) { 313 // If this event is from an activity then we need to call 314 // the activity callback to let it know that the event it 315 // created has been modified so it needs to update accordingly. 316 component_callback( 317 'mod_' . $event->get_course_module()->get('modname'), 318 'core_calendar_event_timestart_updated', 319 [$legacyevent, $moduleinstance] 320 ); 321 } 322 323 return $mapper->from_legacy_event_to_event($legacyevent); 324 } 325 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body