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 * This file contains helper classes and functions for testing. 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 25defined('MOODLE_INTERNAL') || die(); 26 27global $CFG; 28 29require_once($CFG->dirroot . '/calendar/lib.php'); 30 31use core_calendar\local\event\entities\action_event; 32use core_calendar\local\event\entities\event; 33use core_calendar\local\event\entities\repeat_event_collection; 34use core_calendar\local\event\proxies\std_proxy; 35use core_calendar\local\event\proxies\coursecat_proxy; 36use core_calendar\local\event\proxies\cm_info_proxy; 37use core_calendar\local\event\value_objects\action; 38use core_calendar\local\event\value_objects\event_description; 39use core_calendar\local\event\value_objects\event_times; 40use core_calendar\local\event\factories\event_factory_interface; 41 42/** 43 * Create a calendar event with the given properties. 44 * 45 * @param array $properties The properties to set on the event 46 * @return \calendar_event 47 */ 48function create_event($properties) { 49 $record = new \stdClass(); 50 $record->name = 'event name'; 51 $record->eventtype = 'site'; 52 $record->repeat = 0; 53 $record->repeats = 0; 54 $record->timestart = time(); 55 $record->timeduration = 0; 56 $record->timesort = 0; 57 $record->type = CALENDAR_EVENT_TYPE_STANDARD; 58 $record->courseid = 0; 59 $record->categoryid = 0; 60 61 foreach ($properties as $name => $value) { 62 $record->$name = $value; 63 } 64 65 $event = new \calendar_event($record); 66 return $event->create($record); 67} 68 69/** 70 * Helper function to create a x number of events for each event type. 71 * 72 * @param int $quantity The quantity of events to be created. 73 * @return array List of created events. 74 */ 75function create_standard_events(int $quantity): array { 76 $types = ['site', 'category', 'course', 'group', 'user']; 77 78 $events = []; 79 foreach ($types as $eventtype) { 80 // Create five events of each event type. 81 for ($i = 0; $i < $quantity; $i++) { 82 $events[] = create_event(['eventtype' => $eventtype]); 83 } 84 } 85 86 return $events; 87} 88 89/** 90 * Helper function to create an action event. 91 * 92 * @param array $data The event data. 93 * @return bool|calendar_event 94 */ 95function create_action_event(array $data) { 96 global $CFG; 97 98 require_once($CFG->dirroot . '/calendar/lib.php'); 99 100 if (!isset($data['modulename']) || !isset($data['instance'])) { 101 throw new coding_exception('Module and instance should be specified when creating an action event.'); 102 } 103 104 $isuseroverride = isset($data->priority) && $data->priority == CALENDAR_EVENT_USER_OVERRIDE_PRIORITY; 105 if ($isuseroverride) { 106 if (!in_array($data['modulename'], ['assign', 'lesson', 'quiz'])) { 107 throw new coding_exception('Only assign, lesson and quiz modules supports overrides'); 108 } 109 } 110 111 $event = array_merge($data, [ 112 'eventtype' => isset($data['eventtype']) ? $data['eventtype'] : 'open', 113 'courseid' => isset($data['courseid']) ? $data['courseid'] : 0, 114 'instance' => $data['instance'], 115 'modulename' => $data['modulename'], 116 'type' => CALENDAR_EVENT_TYPE_ACTION, 117 ]); 118 119 return create_event($event); 120} 121 122/** 123 * Helper function to create an user override calendar event. 124 * 125 * @param string $modulename The modulename. 126 * @param int $instanceid The instance id. 127 * @param int $userid The user id. 128 * @return calendar_event|false 129 */ 130function create_user_override_event(string $modulename, int $instanceid, int $userid) { 131 if (!isset($userid)) { 132 throw new coding_exception('Must specify userid when creating a user override.'); 133 } 134 135 return create_action_event([ 136 'modulename' => $modulename, 137 'instance' => $instanceid, 138 'userid' => $userid, 139 'priority' => CALENDAR_EVENT_USER_OVERRIDE_PRIORITY, 140 ]); 141} 142 143/** 144 * Helper function to create an group override calendar event. 145 * 146 * @param string $modulename The modulename. 147 * @param int $instanceid The instance id. 148 * @param int $courseid The course id. 149 * @param int $groupid The group id. 150 * @return calendar_event|false 151 */ 152function create_group_override_event(string $modulename, int $instanceid, int $courseid, int $groupid) { 153 if (!isset($groupid)) { 154 throw new coding_exception('Must specify groupid when creating a group override.'); 155 } 156 157 return create_action_event([ 158 'groupid' => $groupid, 159 'courseid' => $courseid, 160 'modulename' => $modulename, 161 'instance' => $instanceid, 162 ]); 163} 164 165/** 166 * A test factory that will create action events. 167 * 168 * @copyright 2017 Ryan Wyllie <ryan@moodle.com> 169 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or late 170 */ 171class action_event_test_factory implements event_factory_interface { 172 173 /** 174 * @var callable $callback. 175 */ 176 private $callback; 177 178 /** 179 * A test factory that will create action events. The factory accepts a callback 180 * that will be used to determine if the event should be returned or not. 181 * 182 * The callback will be given the event and should return true if the event 183 * should be returned and false otherwise. 184 * 185 * @param callable $callback The callback. 186 */ 187 public function __construct($callback = null) { 188 $this->callback = $callback; 189 } 190 191 public function create_instance(\stdClass $record) { 192 $module = null; 193 $subscription = null; 194 195 if ($record->instance && $record->modulename) { 196 $module = new cm_info_proxy($record->instance, $record->modulename, $record->courseid); 197 } 198 199 if ($record->subscriptionid) { 200 $subscription = new std_proxy($record->subscriptionid, function($id) { 201 return (object)['id' => $id]; 202 }); 203 } 204 205 $event = new event( 206 $record->id, 207 $record->name, 208 new event_description($record->description, $record->format), 209 new coursecat_proxy($record->categoryid), 210 new std_proxy($record->courseid, function($id) { 211 $course = new \stdClass(); 212 $course->id = $id; 213 return $course; 214 }), 215 new std_proxy($record->groupid, function($id) { 216 $group = new \stdClass(); 217 $group->id = $id; 218 return $group; 219 }), 220 new std_proxy($record->userid, function($id) { 221 $user = new \stdClass(); 222 $user->id = $id; 223 return $user; 224 }), 225 !empty($record->repeatid) ? new repeat_event_collection($record, $this) : null, 226 $module, 227 $record->eventtype, 228 new event_times( 229 (new \DateTimeImmutable())->setTimestamp($record->timestart), 230 (new \DateTimeImmutable())->setTimestamp($record->timestart + $record->timeduration), 231 (new \DateTimeImmutable())->setTimestamp($record->timesort ? $record->timesort : $record->timestart), 232 (new \DateTimeImmutable())->setTimestamp($record->timemodified) 233 ), 234 !empty($record->visible), 235 $subscription, 236 $record->location, 237 !empty($record->component) ? $record->component : null 238 ); 239 240 $action = new action( 241 'Test action', 242 new \moodle_url('/'), 243 1, 244 true 245 ); 246 247 $actionevent = new action_event($event, $action); 248 249 if ($callback = $this->callback) { 250 return $callback($actionevent) ? $actionevent : false; 251 } else { 252 return $actionevent; 253 } 254 } 255} 256