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]
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 * @param string|null $searchvalue The value a user wishes to search against 124 * @return array A list of action_event_interface objects 125 * @throws \moodle_exception 126 */ 127 public static function get_action_events_by_timesort( 128 $timesortfrom = null, 129 $timesortto = null, 130 $aftereventid = null, 131 $limitnum = 20, 132 $limittononsuspendedevents = false, 133 ?\stdClass $user = null, 134 ?string $searchvalue = null 135 ) { 136 global $USER; 137 138 if (!$user) { 139 $user = $USER; 140 } 141 142 if (is_null($timesortfrom) && is_null($timesortto)) { 143 throw new \moodle_exception("Must provide a timesort to and/or from value"); 144 } 145 146 if ($limitnum < 1 || $limitnum > 50) { 147 throw new \moodle_exception("Limit must be between 1 and 50 (inclusive)"); 148 } 149 150 \core_calendar\local\event\container::set_requesting_user($user->id); 151 $vault = \core_calendar\local\event\container::get_event_vault(); 152 153 $afterevent = null; 154 if ($aftereventid && $event = $vault->get_event_by_id($aftereventid)) { 155 $afterevent = $event; 156 } 157 158 return $vault->get_action_events_by_timesort($user, $timesortfrom, $timesortto, $afterevent, $limitnum, 159 $limittononsuspendedevents, $searchvalue); 160 } 161 162 /** 163 * Get a list of action events for the logged in user by the given 164 * course and timesort values. 165 * 166 * @param \stdClass $course The course the events must belong to 167 * @param int|null $timesortfrom The start timesort value (inclusive) 168 * @param int|null $timesortto The end timesort value (inclusive) 169 * @param int|null $aftereventid Only return events after this one 170 * @param int $limitnum Limit results to this amount (between 1 and 50) 171 * @param string|null $searchvalue The value a user wishes to search against 172 * @return array A list of action_event_interface objects 173 * @throws limit_invalid_parameter_exception 174 */ 175 public static function get_action_events_by_course( 176 $course, 177 $timesortfrom = null, 178 $timesortto = null, 179 $aftereventid = null, 180 $limitnum = 20, 181 ?string $searchvalue = null 182 ) { 183 global $USER; 184 185 if ($limitnum < 1 || $limitnum > 50) { 186 throw new limit_invalid_parameter_exception( 187 "Limit must be between 1 and 50 (inclusive)"); 188 } 189 190 $vault = \core_calendar\local\event\container::get_event_vault(); 191 192 $afterevent = null; 193 if ($aftereventid && $event = $vault->get_event_by_id($aftereventid)) { 194 $afterevent = $event; 195 } 196 197 return $vault->get_action_events_by_course( 198 $USER, $course, $timesortfrom, $timesortto, $afterevent, $limitnum, $searchvalue); 199 } 200 201 /** 202 * Get a list of action events for the logged in user by the given 203 * courses and timesort values. 204 * 205 * The limit number applies per course, not for the result set as a whole. 206 * E.g. Requesting 3 courses with a limit of 10 will result in up to 30 207 * events being returned (up to 10 per course). 208 * 209 * @param array $courses The courses the events must belong to 210 * @param int|null $timesortfrom The start timesort value (inclusive) 211 * @param int|null $timesortto The end timesort value (inclusive) 212 * @param int $limitnum Limit results per course to this amount (between 1 and 50) 213 * @param string|null $searchvalue The value a user wishes to search against 214 * @return array A list of action_event_interface objects indexed by course id 215 */ 216 public static function get_action_events_by_courses( 217 $courses = [], 218 $timesortfrom = null, 219 $timesortto = null, 220 $limitnum = 20, 221 ?string $searchvalue = null 222 ) { 223 $return = []; 224 225 foreach ($courses as $course) { 226 $return[$course->id] = self::get_action_events_by_course( 227 $course, 228 $timesortfrom, 229 $timesortto, 230 null, 231 $limitnum, 232 $searchvalue 233 ); 234 } 235 236 return $return; 237 } 238 239 /** 240 * Change the start day for an event. Only the date will be 241 * modified, the time of day for the event will be left as is. 242 * 243 * @param event_interface $event The existing event to modify 244 * @param DateTimeInterface $startdate The new date to use for the start day 245 * @return event_interface The new event with updated start date 246 */ 247 public static function update_event_start_day( 248 event_interface $event, 249 \DateTimeInterface $startdate 250 ) { 251 global $DB; 252 253 $mapper = container::get_event_mapper(); 254 $legacyevent = $mapper->from_event_to_legacy_event($event); 255 $hascoursemodule = !empty($event->get_course_module()); 256 $moduleinstance = null; 257 $starttime = $event->get_times()->get_start_time()->setDate( 258 $startdate->format('Y'), 259 $startdate->format('n'), 260 $startdate->format('j') 261 ); 262 $starttimestamp = $starttime->getTimestamp(); 263 264 if ($hascoursemodule) { 265 $moduleinstance = $DB->get_record( 266 $event->get_course_module()->get('modname'), 267 ['id' => $event->get_course_module()->get('instance')], 268 '*', 269 MUST_EXIST 270 ); 271 272 // If there is a timestart range callback implemented then we can 273 // use the values returned from the valid timestart range to apply 274 // some default validation on the event's timestart value to ensure 275 // that it falls within the specified range. 276 list($min, $max) = component_callback( 277 'mod_' . $event->get_course_module()->get('modname'), 278 'core_calendar_get_valid_event_timestart_range', 279 [$legacyevent, $moduleinstance], 280 [false, false] 281 ); 282 } else if ($legacyevent->courseid != 0 && $legacyevent->courseid != SITEID && $legacyevent->groupid == 0) { 283 // This is a course event. 284 list($min, $max) = component_callback( 285 'core_course', 286 'core_calendar_get_valid_event_timestart_range', 287 [$legacyevent, $event->get_course()->get_proxied_instance()], 288 [0, 0] 289 ); 290 } else { 291 $min = $max = 0; 292 } 293 294 // If the callback returns false for either value it means that 295 // there is no valid time start range. 296 if ($min === false || $max === false) { 297 throw new \moodle_exception('The start day of this event can not be modified'); 298 } 299 300 if ($min && $starttimestamp < $min[0]) { 301 throw new \moodle_exception($min[1]); 302 } 303 304 if ($max && $starttimestamp > $max[0]) { 305 throw new \moodle_exception($max[1]); 306 } 307 308 // This function does our capability checks. 309 $legacyevent->update((object) ['timestart' => $starttime->getTimestamp()]); 310 311 // Check that the user is allowed to manually edit calendar events before 312 // calling the event updated callback. The manual flag causes the code to 313 // check the user has the capabilities to modify the modules. 314 // 315 // We don't want to call the event update callback if the user isn't allowed 316 // to modify course modules because depending on the callback it can make 317 // some changes that would be considered security issues, such as updating the 318 // due date for an assignment. 319 if ($hascoursemodule && calendar_edit_event_allowed($legacyevent, true)) { 320 // If this event is from an activity then we need to call 321 // the activity callback to let it know that the event it 322 // created has been modified so it needs to update accordingly. 323 component_callback( 324 'mod_' . $event->get_course_module()->get('modname'), 325 'core_calendar_event_timestart_updated', 326 [$legacyevent, $moduleinstance] 327 ); 328 329 // Rebuild the course cache to make sure the updated dates are reflected. 330 $courseid = $event->get_course()->get('id'); 331 $cmid = $event->get_course_module()->get('id'); 332 \course_modinfo::purge_course_module_cache($courseid, $cmid); 333 rebuild_course_cache($courseid, true, true); 334 } 335 336 return $mapper->from_legacy_event_to_event($legacyevent); 337 } 338 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body