diff --git a/calendar/classes/external/events_related_objects_cache.php b/calendar/classes/external/events_related_objects_cache.php index e845b64add5..48998950712 100644 --- a/calendar/classes/external/events_related_objects_cache.php +++ b/calendar/classes/external/events_related_objects_cache.php @@ -114,12 +114,15 @@ class events_related_objects_cache { public function get_context(event_interface $event) { global $USER; + $categoryid = $event->get_category() ? $event->get_category()->get('id') : null; $courseid = $event->get_course() ? $event->get_course()->get('id') : null; $groupid = $event->get_group() ? $event->get_group()->get('id') : null; $userid = $event->get_user() ? $event->get_user()->get('id') : null; $moduleid = $event->get_course_module() ? $event->get_course_module()->get('id') : null; - if (!empty($courseid)) { + if (!empty($categoryid)) { + return \context_coursecat::instance($categoryid); + } else if (!empty($courseid)) { return \context_course::instance($event->get_course()->get('id')); } else if (!empty($groupid)) { $group = $this->get_group($event); diff --git a/calendar/classes/privacy/provider.php b/calendar/classes/privacy/provider.php index 369b6012026..ae9c01415c9 100644 --- a/calendar/classes/privacy/provider.php +++ b/calendar/classes/privacy/provider.php @@ -97,26 +97,18 @@ class provider implements public static function get_contexts_for_userid(int $userid) : contextlist { $contextlist = new contextlist(); - // Calendar Events can exist at Site, Course Category, Course, Course Group, User, or Course Modules contexts. + // Only events belonging to that user will be exported. $params = [ - 'sitecontext' => CONTEXT_SYSTEM, - 'categorycontext' => CONTEXT_COURSECAT, - 'coursecontext' => CONTEXT_COURSE, - 'groupcontext' => CONTEXT_COURSE, - 'usercontext' => CONTEXT_USER, - 'cuserid' => $userid, - 'modulecontext' => CONTEXT_MODULE, - 'muserid' => $userid + 'usercontext' => CONTEXT_USER, + 'modulecontext' => CONTEXT_MODULE, + 'cuserid' => $userid, + 'muserid' => $userid, ]; // Get contexts of Calendar Events for the owner. $sql = "SELECT ctx.id FROM {context} ctx JOIN {event} e ON - (e.eventtype = 'site' AND ctx.contextlevel = :sitecontext) OR - (e.categoryid = ctx.instanceid AND e.eventtype = 'category' AND ctx.contextlevel = :categorycontext) OR - (e.courseid = ctx.instanceid AND e.eventtype = 'course' AND ctx.contextlevel = :coursecontext) OR - (e.courseid = ctx.instanceid AND e.eventtype = 'group' AND ctx.contextlevel = :groupcontext) OR (e.userid = ctx.instanceid AND e.eventtype = 'user' AND ctx.contextlevel = :usercontext) WHERE e.userid = :cuserid UNION @@ -128,12 +120,8 @@ class provider implements WHERE e.userid = :muserid"; $contextlist->add_from_sql($sql, $params); - // Calendar Subscriptions can exist at Site, Course Category, Course, Course Group, or User contexts. + // Only export subscriptions belonging to that user. $params = [ - 'sitecontext' => CONTEXT_SYSTEM, - 'categorycontext' => CONTEXT_COURSECAT, - 'coursecontext' => CONTEXT_COURSE, - 'groupcontext' => CONTEXT_COURSE, 'usercontext' => CONTEXT_USER, 'userid' => $userid ]; @@ -142,10 +130,6 @@ class provider implements $sql = "SELECT ctx.id FROM {context} ctx JOIN {event_subscriptions} s ON - (s.eventtype = 'site' AND ctx.contextlevel = :sitecontext) OR - (s.categoryid = ctx.instanceid AND s.eventtype = 'category' AND ctx.contextlevel = :categorycontext) OR - (s.courseid = ctx.instanceid AND s.eventtype = 'course' AND ctx.contextlevel = :coursecontext) OR - (s.courseid = ctx.instanceid AND s.eventtype = 'group' AND ctx.contextlevel = :groupcontext) OR (s.userid = ctx.instanceid AND s.eventtype = 'user' AND ctx.contextlevel = :usercontext) WHERE s.userid = :userid"; $contextlist->add_from_sql($sql, $params); @@ -164,8 +148,7 @@ class provider implements $context = $userlist->get_context(); - // Calendar Events can exist at Site (CONTEXT_SYSTEM), Course Category (CONTEXT_COURSECAT), - // Course and Course Group (CONTEXT_COURSE), User (CONTEXT_USER), or Course Modules (CONTEXT_MODULE) contexts. + // Calendar Events can exist at user (CONTEXT_USER), or Course Modules (CONTEXT_MODULE) contexts. if ($context->contextlevel == CONTEXT_MODULE) { $params = ['cmid' => $context->instanceid]; @@ -176,43 +159,21 @@ class provider implements WHERE cm.id = :cmid"; $userlist->add_from_sql('userid', $sql, $params); - } else if ($context->contextlevel == CONTEXT_SYSTEM) { - // Get contexts of Calendar Events for the owner. - $sql = "SELECT userid FROM {event} WHERE eventtype = 'site'"; - $userlist->add_from_sql('userid', $sql, []); - - // Get contexts for Calendar Subscriptions for the owner. - $sql = "SELECT userid FROM {event_subscriptions} WHERE eventtype = 'site'"; - $userlist->add_from_sql('userid', $sql, []); - } else if (in_array($context->contextlevel, [CONTEXT_COURSECAT, CONTEXT_COURSE, CONTEXT_USER])) { - $eventfields = [ - CONTEXT_COURSECAT => 'categoryid', - CONTEXT_COURSE => 'courseid', - CONTEXT_USER => 'userid' - ]; - $eventfield = $eventfields[$context->contextlevel]; - - $eventtypes = [ - CONTEXT_COURSECAT => 'category', - CONTEXT_COURSE => ['course' , 'group'], - CONTEXT_USER => 'user' - ]; - list($eventtypesql, $eventtypeparams) = $DB->get_in_or_equal($eventtypes[$context->contextlevel], SQL_PARAMS_NAMED); - - $params = $eventtypeparams + ['instanceid' => $context->instanceid]; + } else if ($context->contextlevel == CONTEXT_USER) { + $params = ['instanceid' => $context->instanceid]; // Get contexts of Calendar Events for the owner. $sql = "SELECT userid FROM {event} - WHERE eventtype $eventtypesql - AND $eventfield = :instanceid"; + WHERE eventtype = 'user' + AND userid = :instanceid"; $userlist->add_from_sql('userid', $sql, $params); // Get contexts for Calendar Subscriptions for the owner. $sql = "SELECT userid FROM {event_subscriptions} - WHERE eventtype $eventtypesql - AND $eventfield = :instanceid"; + WHERE eventtype = 'user' + AND userid = :instanceid"; $userlist->add_from_sql('userid', $sql, $params); } } @@ -276,9 +237,6 @@ class provider implements $userids = $userlist->get_userids(); $allowedcontexts = [ - CONTEXT_SYSTEM, - CONTEXT_COURSECAT, - CONTEXT_COURSE, CONTEXT_MODULE, CONTEXT_USER ]; @@ -449,9 +407,8 @@ class provider implements protected static function get_calendar_event_ids_by_context(\context $context, $userids = array()) { global $DB; - // Calendar Events can exist at Site (CONTEXT_SYSTEM), Course Category (CONTEXT_COURSECAT), - // Course and Course Group (CONTEXT_COURSE), User (CONTEXT_USER), or Course Modules (CONTEXT_MODULE) contexts. - if (!in_array($context->contextlevel, [CONTEXT_SYSTEM, CONTEXT_COURSECAT, CONTEXT_COURSE, CONTEXT_USER, CONTEXT_MODULE])) { + // Only events can exist at user and course module contexts can be exported. + if (!in_array($context->contextlevel, [CONTEXT_USER, CONTEXT_MODULE])) { return []; } @@ -471,35 +428,16 @@ class provider implements JOIN {modules} m ON m.id = cm.module JOIN {event} e ON e.modulename = m.name AND e.courseid = cm.course AND e.instance = cm.instance WHERE cm.id = :cmid + AND e.userid <> 0 $whereusersql"; - } else if ($context->contextlevel == CONTEXT_SYSTEM) { // Site events. - $params = []; - $sql = "SELECT DISTINCT e.id AS eventid - FROM {event} e - WHERE e.eventtype = 'site' - $whereusersql"; - } else { // The rest. - $eventfields = [ - CONTEXT_COURSECAT => 'categoryid', - CONTEXT_COURSE => 'courseid', - CONTEXT_USER => 'userid' - ]; - $eventfield = $eventfields[$context->contextlevel]; - - $eventtypes = [ - CONTEXT_COURSECAT => 'category', - CONTEXT_COURSE => ['course' , 'group'], - CONTEXT_USER => 'user' - ]; - list($eventtypesql, $eventtypeparams) = $DB->get_in_or_equal($eventtypes[$context->contextlevel], SQL_PARAMS_NAMED); - - $params = $eventtypeparams + ['instanceid' => $context->instanceid]; + } else { + $params = ['instanceid' => $context->instanceid]; // Get Calendar Events for the specified Moodle context. $sql = "SELECT DISTINCT e.id AS eventid FROM {event} e - WHERE e.eventtype $eventtypesql - AND e.{$eventfield} = :instanceid + WHERE e.eventtype = 'user' + AND e.userid = :instanceid $whereusersql"; } @@ -520,9 +458,8 @@ class provider implements protected static function get_calendar_subscription_ids_by_context(\context $context, $userids = array()) { global $DB; - // Calendar Subscriptions can exist at Site (CONTEXT_SYSTEM), Course Category (CONTEXT_COURSECAT), - // Course and Course Group (CONTEXT_COURSE), or User (CONTEXT_USER) contexts. - if (!in_array($context->contextlevel, [CONTEXT_SYSTEM, CONTEXT_COURSECAT, CONTEXT_COURSE, CONTEXT_USER])) { + // Only own user event subscriptions can be exported. + if ($context->contextlevel != CONTEXT_USER) { return []; } @@ -532,40 +469,14 @@ class provider implements list($usersql, $userparams) = $DB->get_in_or_equal($userids, SQL_PARAMS_NAMED); $whereusersql = "AND s.userid {$usersql}"; } + $params = ['instanceid' => $context->instanceid]; - if ($context->contextlevel == CONTEXT_SYSTEM) { - $params = []; - - // Get Calendar Subscriptions for the system context. - $sql = "SELECT DISTINCT s.id AS subscriptionid - FROM {event_subscriptions} s - WHERE s.eventtype = 'site' - $whereusersql"; - } else { - $eventfields = [ - CONTEXT_COURSECAT => 'categoryid', - CONTEXT_COURSE => 'courseid', - CONTEXT_USER => 'userid' - ]; - $eventfield = $eventfields[$context->contextlevel]; - - $eventtypes = [ - CONTEXT_COURSECAT => 'category', - CONTEXT_COURSE => ['course' , 'group'], - CONTEXT_USER => 'user' - ]; - list($eventtypesql, $eventtypeparams) = $DB->get_in_or_equal($eventtypes[$context->contextlevel], SQL_PARAMS_NAMED); - - $params = $eventtypeparams + ['instanceid' => $context->instanceid]; - - // Get Calendar Subscriptions for the specified context. - $sql = "SELECT DISTINCT s.id AS subscriptionid - FROM {event_subscriptions} s - WHERE s.eventtype $eventtypesql - AND s.{$eventfield} = :instanceid - $whereusersql"; - } - + // Get Calendar Subscriptions for the specified context. + $sql = "SELECT DISTINCT s.id AS subscriptionid + FROM {event_subscriptions} s + WHERE s.eventtype = 'user' + AND s.userid = :instanceid + $whereusersql"; $params += $userparams; return $DB->get_records_sql($sql, $params); @@ -587,12 +498,8 @@ class provider implements list($contextsql1, $contextparams1) = $DB->get_in_or_equal($contextlist->get_contextids(), SQL_PARAMS_NAMED); list($contextsql2, $contextparams2) = $DB->get_in_or_equal($contextlist->get_contextids(), SQL_PARAMS_NAMED); - // Calendar Events can exist at Site, Course Category, Course, Course Group, User, or Course Modules contexts. + // Only User and Course Modules contexts belonging to the user can be exported. $params = [ - 'sitecontext' => CONTEXT_SYSTEM, - 'categorycontext' => CONTEXT_COURSECAT, - 'coursecontext' => CONTEXT_COURSE, - 'groupcontext' => CONTEXT_COURSE, 'usercontext' => CONTEXT_USER, 'cuserid' => $userid, 'modulecontext' => CONTEXT_MODULE, @@ -615,10 +522,6 @@ class provider implements ctx.id AS ctxid FROM {context} ctx INNER JOIN {event} e ON - (e.eventtype = 'site' AND ctx.contextlevel = :sitecontext) OR - (e.categoryid = ctx.instanceid AND e.eventtype = 'category' AND ctx.contextlevel = :categorycontext) OR - (e.courseid = ctx.instanceid AND e.eventtype = 'course' AND ctx.contextlevel = :coursecontext) OR - (e.courseid = ctx.instanceid AND e.eventtype = 'group' AND ctx.contextlevel = :groupcontext) OR (e.userid = ctx.instanceid AND e.eventtype = 'user' AND ctx.contextlevel = :usercontext) WHERE e.userid = :cuserid AND ctx.id {$contextsql1} @@ -654,10 +557,6 @@ class provider implements list($contextsql, $contextparams) = $DB->get_in_or_equal($contextlist->get_contextids(), SQL_PARAMS_NAMED); $params = [ - 'sitecontext' => CONTEXT_SYSTEM, - 'categorycontext' => CONTEXT_COURSECAT, - 'coursecontext' => CONTEXT_COURSE, - 'groupcontext' => CONTEXT_COURSE, 'usercontext' => CONTEXT_USER, 'userid' => $user->id ]; @@ -672,10 +571,6 @@ class provider implements s.eventtype as eventtype FROM {context} c INNER JOIN {event_subscriptions} s ON - (s.eventtype = 'site' AND c.contextlevel = :sitecontext) OR - (s.categoryid = c.instanceid AND s.eventtype = 'category' AND c.contextlevel = :categorycontext) OR - (s.courseid = c.instanceid AND s.eventtype = 'course' AND c.contextlevel = :coursecontext) OR - (s.courseid = c.instanceid AND s.eventtype = 'group' AND c.contextlevel = :groupcontext) OR (s.userid = c.instanceid AND s.eventtype = 'user' AND c.contextlevel = :usercontext) WHERE s.userid = :userid AND c.id {$contextsql}"; diff --git a/calendar/lib.php b/calendar/lib.php index 3bf8caf9cae..3d8f0ceef71 100644 --- a/calendar/lib.php +++ b/calendar/lib.php @@ -235,9 +235,18 @@ class calendar_event { $data->eventtype = 'user'; } - // Default to the current user. + // Only user and user override type of events should record the user id. + // For all other event types we set userid to 0 as they are considered shared events. if (empty($data->userid)) { - $data->userid = $USER->id; + if ($this->allow_custom_userid($data)) { + $data->userid = $USER->id; + } else { + $data->userid = 0; + } + } + + if (empty($data->courseid) && $data->eventtype == 'site') { + $data->courseid = SITEID; } if (!empty($data->timeduration) && is_array($data->timeduration)) { @@ -315,6 +324,28 @@ class calendar_event { return !empty($this->properties->{$key}); } + /** + * Decide whether user id should be stored on the event or not. + * + * Only user events and user overrides type of events should retain user id. + * + * @param stdClass $data The event data object. + * @return bool + */ + protected function allow_custom_userid(stdClass $data): bool { + if ($data->eventtype === 'user') { + return true; + } + + $isactionevent = !empty($data->type) && $data->type == CALENDAR_EVENT_TYPE_ACTION; + $isuseroverride = !empty($data->priority) && $data->priority == CALENDAR_EVENT_USER_OVERRIDE_PRIORITY; + if ($isactionevent && $isuseroverride) { + return true; + } + + return false; + } + /** * Calculate the context value needed for an event. * @@ -489,49 +520,18 @@ class calendar_event { } if ($usingeditor) { - switch ($this->properties->eventtype) { - case 'user': - $this->properties->courseid = 0; - $this->properties->course = 0; - $this->properties->groupid = 0; - $this->properties->userid = $USER->id; - break; - case 'site': - $this->properties->courseid = SITEID; - $this->properties->course = SITEID; - $this->properties->groupid = 0; - $this->properties->userid = $USER->id; - break; - case 'course': - $this->properties->groupid = 0; - $this->properties->userid = $USER->id; - break; - case 'category': - $this->properties->groupid = 0; - $this->properties->category = 0; - $this->properties->userid = $USER->id; - break; - case 'group': - $this->properties->userid = $USER->id; - break; - default: - // We should NEVER get here, but just incase we do lets fail gracefully. - $usingeditor = false; - break; - } - // If we are actually using the editor, we recalculate the context because some default values // were set when calculate_context() was called from the constructor. - if ($usingeditor) { - $this->properties->context = $this->calculate_context(); - $this->editorcontext = $this->get_context(); - } + $this->properties->context = $this->calculate_context(); + $this->editorcontext = $this->get_context(); $editor = $this->properties->description; $this->properties->format = $this->properties->description['format']; $this->properties->description = $this->properties->description['text']; } + $this->set_default_event_ids(); + // Insert the event into the database. $this->properties->id = $DB->insert_record('event', $this->properties); @@ -676,6 +676,8 @@ class calendar_event { $event->trigger(); } } else { + $this->set_default_event_ids(); + $DB->update_record('event', $this->properties); $event = self::load($this->properties->id); $this->properties = $event->properties(); @@ -870,6 +872,49 @@ class calendar_event { return $properties; } + /** + * Set the default event ids. + */ + protected function set_default_event_ids(): void { + global $USER; + $userid = (!empty($this->properties->userid)) ? $this->properties->userid : $USER->id; + switch ($this->properties->eventtype) { + case 'user': + $this->properties->courseid = 0; + $this->properties->course = 0; + $this->properties->groupid = 0; + $this->properties->userid = $userid; + break; + case 'site': + $this->properties->courseid = SITEID; + $this->properties->course = SITEID; + $this->properties->groupid = 0; + $this->properties->userid = 0; + break; + case 'course': + $this->properties->groupid = 0; + $this->properties->userid = 0; + break; + case 'category': + $this->properties->groupid = 0; + $this->properties->category = 0; + $this->properties->userid = 0; + break; + case 'group': + $this->properties->userid = 0; + break; + } + + // Only user overrides type of events should store user's id. + $isactionevent = !empty($this->properties->type) && $this->properties->type == CALENDAR_EVENT_TYPE_ACTION; + $isuseroverride = $isactionevent && !empty($this->properties->priority) && + $this->properties->priority == CALENDAR_EVENT_USER_OVERRIDE_PRIORITY; + + if ($isuseroverride) { + $this->properties->userid = $userid; + } + } + /** * Toggles the visibility of an event * @@ -2776,7 +2821,9 @@ function calendar_add_subscription($sub) { // User events. $sub->courseid = 0; } - $sub->userid = $USER->id; + + // Only subscriptions for user type should store user id, shared events (course,site...) should have userid set to 0. + $sub->userid = ($sub->eventtype == 'user') ? $USER->id : 0; // File subscriptions never update. if (empty($sub->url)) { @@ -2905,7 +2952,7 @@ function calendar_add_icalendar_event($event, $unused = null, $subscriptionid, $ // We should never do anything with an event without a subscription reference. $sub = calendar_get_subscription($subscriptionid); $eventrecord->subscriptionid = $subscriptionid; - $eventrecord->userid = $sub->userid; + $eventrecord->userid = ($sub->eventtype == 'user') ? $sub->userid : 0; $eventrecord->groupid = $sub->groupid; $eventrecord->courseid = $sub->courseid; $eventrecord->categoryid = $sub->categoryid; @@ -3264,6 +3311,8 @@ function calendar_get_calendar_context($subscription) { // Determine context based on calendar type. if ($subscription->eventtype === 'site') { $context = \context_course::instance(SITEID); + } else if ($subscription->eventtype === 'category') { + $context = \context_coursecat::instance($subscription->categoryid); } else if ($subscription->eventtype === 'group' || $subscription->eventtype === 'course') { $context = \context_course::instance($subscription->courseid); } else { diff --git a/calendar/tests/event_vault_test.php b/calendar/tests/event_vault_test.php index 5d90f93b3d8..83d0bdbab16 100644 --- a/calendar/tests/event_vault_test.php +++ b/calendar/tests/event_vault_test.php @@ -608,8 +608,8 @@ class core_calendar_event_vault_testcase extends advanced_testcase { for ($i = 1; $i < 6; $i++) { create_event([ 'name' => sprintf('Event %d', $i), - 'eventtype' => 'user', - 'userid' => $user->id, + 'eventtype' => 'due', + 'userid' => 0, 'timesort' => $i, 'type' => CALENDAR_EVENT_TYPE_ACTION, 'courseid' => $course1->id, @@ -619,8 +619,8 @@ class core_calendar_event_vault_testcase extends advanced_testcase { for ($i = 6; $i < 12; $i++) { create_event([ 'name' => sprintf('Event %d', $i), - 'eventtype' => 'user', - 'userid' => $user->id, + 'eventtype' => 'due', + 'userid' => 0, 'timesort' => $i, 'type' => CALENDAR_EVENT_TYPE_ACTION, 'courseid' => $course2->id, @@ -663,8 +663,8 @@ class core_calendar_event_vault_testcase extends advanced_testcase { for ($i = 1; $i < 6; $i++) { create_event([ 'name' => sprintf('Event %d', $i), - 'eventtype' => 'user', - 'userid' => $user->id, + 'eventtype' => 'due', + 'userid' => 0, 'timesort' => $i, 'type' => CALENDAR_EVENT_TYPE_ACTION, 'courseid' => $course1->id, @@ -674,8 +674,8 @@ class core_calendar_event_vault_testcase extends advanced_testcase { for ($i = 6; $i < 12; $i++) { create_event([ 'name' => sprintf('Event %d', $i), - 'eventtype' => 'user', - 'userid' => $user->id, + 'eventtype' => 'due', + 'userid' => 0, 'timesort' => $i, 'type' => CALENDAR_EVENT_TYPE_ACTION, 'courseid' => $course2->id, @@ -719,8 +719,8 @@ class core_calendar_event_vault_testcase extends advanced_testcase { for ($i = 1; $i < 6; $i++) { create_event([ 'name' => sprintf('Event %d', $i), - 'eventtype' => 'user', - 'userid' => $user->id, + 'eventtype' => 'due', + 'userid' => 0, 'timesort' => $i, 'type' => CALENDAR_EVENT_TYPE_ACTION, 'courseid' => $course1->id, @@ -730,8 +730,8 @@ class core_calendar_event_vault_testcase extends advanced_testcase { for ($i = 6; $i < 12; $i++) { create_event([ 'name' => sprintf('Event %d', $i), - 'eventtype' => 'user', - 'userid' => $user->id, + 'eventtype' => 'due', + 'userid' => 0, 'timesort' => $i, 'type' => CALENDAR_EVENT_TYPE_ACTION, 'courseid' => $course2->id, @@ -773,8 +773,8 @@ class core_calendar_event_vault_testcase extends advanced_testcase { for ($i = 1; $i < 21; $i++) { $records[] = create_event([ 'name' => sprintf('Event %d', $i), - 'eventtype' => 'user', - 'userid' => $user->id, + 'eventtype' => 'due', + 'userid' => 0, 'timesort' => $i, 'type' => CALENDAR_EVENT_TYPE_ACTION, 'courseid' => $course1->id, @@ -784,8 +784,8 @@ class core_calendar_event_vault_testcase extends advanced_testcase { for ($i = 21; $i < 41; $i++) { $records[] = create_event([ 'name' => sprintf('Event %d', $i), - 'eventtype' => 'user', - 'userid' => $user->id, + 'eventtype' => 'due', + 'userid' => 0, 'timesort' => $i, 'type' => CALENDAR_EVENT_TYPE_ACTION, 'courseid' => $course2->id, @@ -830,8 +830,8 @@ class core_calendar_event_vault_testcase extends advanced_testcase { for ($i = 1; $i < 41; $i++) { create_event([ 'name' => sprintf('Event %d', $i), - 'eventtype' => 'user', - 'userid' => $user->id, + 'eventtype' => 'due', + 'userid' => 0, 'timesort' => $i, 'type' => CALENDAR_EVENT_TYPE_ACTION, 'courseid' => $course1->id, @@ -901,8 +901,8 @@ class core_calendar_event_vault_testcase extends advanced_testcase { for ($i = 1; $i < 21; $i++) { create_event([ 'name' => sprintf('Event %d', $i), - 'eventtype' => 'user', - 'userid' => $user->id, + 'eventtype' => 'due', + 'userid' => 0, 'timesort' => $i, 'type' => CALENDAR_EVENT_TYPE_ACTION, 'courseid' => $course1->id, @@ -912,8 +912,8 @@ class core_calendar_event_vault_testcase extends advanced_testcase { for ($i = 21; $i < 41; $i++) { create_event([ 'name' => sprintf('Event %d', $i), - 'eventtype' => 'user', - 'userid' => $user->id, + 'eventtype' => 'due', + 'userid' => 0, 'timesort' => $i, 'type' => CALENDAR_EVENT_TYPE_ACTION, 'courseid' => $course2->id, @@ -979,8 +979,8 @@ class core_calendar_event_vault_testcase extends advanced_testcase { for ($i = 1; $i < 11; $i++) { $records[] = create_event([ 'name' => sprintf('1 event %d', $i), - 'eventtype' => 'user', - 'userid' => $user->id, + 'eventtype' => 'due', + 'userid' => 0, 'timesort' => $i, 'type' => CALENDAR_EVENT_TYPE_ACTION, 'courseid' => $course1->id, @@ -990,8 +990,8 @@ class core_calendar_event_vault_testcase extends advanced_testcase { for ($i = 1; $i < 11; $i++) { $records[] = create_event([ 'name' => sprintf('2 event %d', $i), - 'eventtype' => 'user', - 'userid' => $user->id, + 'eventtype' => 'due', + 'userid' => 0, 'timesort' => $i, 'type' => CALENDAR_EVENT_TYPE_ACTION, 'courseid' => $course1->id, @@ -1002,8 +1002,8 @@ class core_calendar_event_vault_testcase extends advanced_testcase { for ($i = 1; $i < 11; $i++) { $records[] = create_event([ 'name' => sprintf('3 event %d', $i), - 'eventtype' => 'user', - 'userid' => $user->id, + 'eventtype' => 'due', + 'userid' => 0, 'timesort' => $i, 'type' => CALENDAR_EVENT_TYPE_ACTION, 'courseid' => $course2->id, diff --git a/calendar/tests/externallib_test.php b/calendar/tests/externallib_test.php index bc33c032785..46af548aa55 100644 --- a/calendar/tests/externallib_test.php +++ b/calendar/tests/externallib_test.php @@ -96,13 +96,6 @@ class core_calendar_externallib_testcase extends externallib_advanced_testcase { } else { $prop->repeat = 1; } - if (empty($prop->userid)) { - if (!empty($userid)) { - $prop->userid = $userid; - } else { - $prop->userid = 0; - } - } if (!isset($prop->courseid)) { $prop->courseid = $SITE->id; } @@ -390,44 +383,54 @@ class core_calendar_externallib_testcase extends externallib_advanced_testcase { $this->setUser($user); $events = core_calendar_external::get_calendar_events($paramevents, $options); $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events); - $this->assertEquals(2, count($events['events'])); // site, user. - $this->assertEquals(2, count($events['warnings'])); // course, group. + // There should be a single user event. + $this->assertEquals(1, count($events['events'])); + // There should be only two events (course and group). + $this->assertEquals(2, count($events['warnings'])); $role = $DB->get_record('role', array('shortname' => 'student')); $this->getDataGenerator()->enrol_user($user->id, $course->id, $role->id); $events = core_calendar_external::get_calendar_events($paramevents, $options); $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events); - $this->assertEquals(4, count($events['events'])); // site, user, both course events. - $this->assertEquals(1, count($events['warnings'])); // group. + // There should be a site and both course events. + $this->assertEquals(3, count($events['events'])); + // There should be a warning related to group event. + $this->assertEquals(1, count($events['warnings'])); $options = array ('siteevents' => true, 'userevents' => true, 'timeend' => time() + HOURSECS); $events = core_calendar_external::get_calendar_events($paramevents, $options); $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events); - $this->assertEquals(3, count($events['events'])); // site, user, one course event. - $this->assertEquals(1, count($events['warnings'])); // group. + // There should be a site and a course event. + $this->assertEquals(2, count($events['events'])); + // There should be a warning related to group event. + $this->assertEquals(1, count($events['warnings'])); groups_add_member($group, $user); $events = core_calendar_external::get_calendar_events($paramevents, $options); $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events); - $this->assertEquals(4, count($events['events'])); // site, user, group, one course event. + // There should be a site, group, one course event. + $this->assertEquals(3, count($events['events'])); $this->assertEquals(0, count($events['warnings'])); $paramevents = array ('courseids' => array($course->id), 'groupids' => array($group->id)); $events = core_calendar_external::get_calendar_events($paramevents, $options); $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events); - $this->assertEquals(4, count($events['events'])); // site, user, group, one course event. + // There should be only site, course and group events. + $this->assertEquals(3, count($events['events'])); $this->assertEquals(0, count($events['warnings'])); $paramevents = array ('groupids' => array($group->id, 23)); $events = core_calendar_external::get_calendar_events($paramevents, $options); $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events); - $this->assertEquals(3, count($events['events'])); // site, user, group. + // There should be only site and group events. + $this->assertEquals(2, count($events['events'])); $this->assertEquals(1, count($events['warnings'])); $paramevents = array ('courseids' => array(23)); $events = core_calendar_external::get_calendar_events($paramevents, $options); $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events); - $this->assertEquals(2, count($events['events'])); // site, user. + // There should be a single site event. + $this->assertEquals(1, count($events['events'])); $this->assertEquals(1, count($events['warnings'])); $paramevents = array (); @@ -468,7 +471,7 @@ class core_calendar_externallib_testcase extends externallib_advanced_testcase { $events = core_calendar_external::get_calendar_events($paramevents, $options); $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events); - $this->assertCount(5, $events['events']); + $this->assertCount(4, $events['events']); // Hide the assignment. set_coursemodule_visible($assign->cmid, 0); @@ -479,7 +482,7 @@ class core_calendar_externallib_testcase extends externallib_advanced_testcase { $events = core_calendar_external::get_calendar_events($paramevents, $options); $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events); // Expect one less. - $this->assertCount(4, $events['events']); + $this->assertCount(3, $events['events']); // Create some category events. $this->setAdminUser(); @@ -838,7 +841,7 @@ class core_calendar_externallib_testcase extends externallib_advanced_testcase { $now = time(); // Create two events - one for everybody in the course and one only for the first student. $event1 = $this->create_calendar_event('Base event', 0, 'due', 0, $now + DAYSECS, $params + ['courseid' => $course->id]); - $event2 = $this->create_calendar_event('User event', $user->id, 'due', 0, $now + 2*DAYSECS, $params + ['courseid' => 0]); + $event2 = $this->create_calendar_event('User event', 0, 'user', 0, $now + 2 * DAYSECS, $params + ['courseid' => 0]); // Retrieve course events for the second student - only one "Base event" is returned. $this->setUser($user2); @@ -850,14 +853,13 @@ class core_calendar_externallib_testcase extends externallib_advanced_testcase { $this->assertEquals(0, count($events['warnings'])); $this->assertEquals('Base event', $events['events'][0]['name']); - // Retrieve events for the first student - both events are returned. + // Retrieve events for the first student. $this->setUser($user); $events = core_calendar_external::get_calendar_events($paramevents, $options); $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events); - $this->assertEquals(2, count($events['events'])); + $this->assertEquals(1, count($events['events'])); $this->assertEquals(0, count($events['warnings'])); $this->assertEquals('Base event', $events['events'][0]['name']); - $this->assertEquals('User event', $events['events'][1]['name']); // Retrieve events by id as a teacher, 'User event' should be returned since teacher has access to this course. $this->setUser($teacher); @@ -1720,7 +1722,7 @@ class core_calendar_externallib_testcase extends externallib_advanced_testcase { $timedurationuntil->add($interval); $formdata = [ 'id' => 0, - 'userid' => $user->id, + 'userid' => 0, 'modulename' => '', 'instance' => 0, 'visible' => 1, @@ -1781,7 +1783,7 @@ class core_calendar_externallib_testcase extends externallib_advanced_testcase { $timedurationuntil->add($interval); $formdata = [ 'id' => 0, - 'userid' => $user->id, + 'userid' => 0, 'modulename' => '', 'instance' => 0, 'visible' => 1, @@ -1827,7 +1829,7 @@ class core_calendar_externallib_testcase extends externallib_advanced_testcase { ); $event = $result['event']; - $this->assertEquals($user->id, $event['userid']); + $this->assertEquals(0, $event['userid']); $this->assertEquals($formdata['eventtype'], $event['eventtype']); $this->assertEquals($formdata['name'], $event['name']); } @@ -1847,7 +1849,7 @@ class core_calendar_externallib_testcase extends externallib_advanced_testcase { $timedurationuntil->add($interval); $formdata = [ 'id' => 0, - 'userid' => $user->id, + 'userid' => 0, 'modulename' => '', 'instance' => 0, 'visible' => 1, @@ -1958,7 +1960,7 @@ class core_calendar_externallib_testcase extends externallib_advanced_testcase { ); $event = $result['event']; - $this->assertEquals($user->id, $event['userid']); + $this->assertEquals(0, $event['userid']); $this->assertEquals($formdata['eventtype'], $event['eventtype']); $this->assertEquals($formdata['name'], $event['name']); $this->assertEquals($formdata['courseid'], $event['course']['id']); @@ -2046,7 +2048,7 @@ class core_calendar_externallib_testcase extends externallib_advanced_testcase { $timedurationuntil->add($interval); $formdata = [ 'id' => 0, - 'userid' => $user->id, + 'userid' => 0, 'modulename' => '', 'instance' => 0, 'visible' => 1, @@ -2162,7 +2164,7 @@ class core_calendar_externallib_testcase extends externallib_advanced_testcase { ); $event = $result['event']; - $this->assertEquals($user->id, $event['userid']); + $this->assertEquals(0, $event['userid']); $this->assertEquals($formdata['eventtype'], $event['eventtype']); $this->assertEquals($formdata['name'], $event['name']); $this->assertEquals($group->id, $event['groupid']); @@ -2185,7 +2187,7 @@ class core_calendar_externallib_testcase extends externallib_advanced_testcase { $timedurationuntil->add($interval); $formdata = [ 'id' => 0, - 'userid' => $user->id, + 'userid' => 0, 'modulename' => '', 'instance' => 0, 'visible' => 1, @@ -2236,7 +2238,7 @@ class core_calendar_externallib_testcase extends externallib_advanced_testcase { ); $event = $result['event']; - $this->assertEquals($user->id, $event['userid']); + $this->assertEquals(0, $event['userid']); $this->assertEquals($formdata['eventtype'], $event['eventtype']); $this->assertEquals($formdata['name'], $event['name']); $this->assertEquals($group->id, $event['groupid']); @@ -2259,7 +2261,7 @@ class core_calendar_externallib_testcase extends externallib_advanced_testcase { $timedurationuntil->add($interval); $formdata = [ 'id' => 0, - 'userid' => $user->id, + 'userid' => 0, 'modulename' => '', 'instance' => 0, 'visible' => 1, @@ -2309,7 +2311,7 @@ class core_calendar_externallib_testcase extends externallib_advanced_testcase { ); $event = $result['event']; - $this->assertEquals($user->id, $event['userid']); + $this->assertEquals(0, $event['userid']); $this->assertEquals($formdata['eventtype'], $event['eventtype']); $this->assertEquals($formdata['name'], $event['name']); $this->assertEquals($group->id, $event['groupid']); @@ -2581,8 +2583,10 @@ class core_calendar_externallib_testcase extends externallib_advanced_testcase { $category = $generator->create_category(['visible' => 0]); $name = 'Category Event (category: ' . $category->id . ')'; $record = new stdClass(); + $record->eventtype = 'category'; $record->categoryid = $category->id; - $categoryevent = $this->create_calendar_event($name, $USER->id, 'category', 0, time(), $record); + $record->userid = 0; + $categoryevent = $this->create_calendar_event($name, 0, 'category', 0, time(), $record); $events = [ 'eventids' => [$categoryevent->id] diff --git a/calendar/tests/local_api_test.php b/calendar/tests/local_api_test.php index 987de7b3915..934ef414adc 100644 --- a/calendar/tests/local_api_test.php +++ b/calendar/tests/local_api_test.php @@ -154,8 +154,8 @@ class core_calendar_local_api_testcase extends advanced_testcase { 'courseid' => $course->id, 'modulename' => 'assign', 'instance' => $moduleinstance->id, - 'userid' => 1, - 'eventtype' => 'user', + 'userid' => 0, + 'eventtype' => 'due', 'repeats' => 0, 'timestart' => 1, ]; @@ -205,8 +205,8 @@ class core_calendar_local_api_testcase extends advanced_testcase { 'courseid' => $course->id, 'modulename' => 'assign', 'instance' => $moduleinstance->id, - 'userid' => 1, - 'eventtype' => 'user', + 'userid' => 0, + 'eventtype' => 'due', 'repeats' => 0, 'timestart' => 1, ]; @@ -257,8 +257,8 @@ class core_calendar_local_api_testcase extends advanced_testcase { 'courseid' => $course->id, 'modulename' => 'assign', 'instance' => $moduleinstance->id, - 'userid' => 1, - 'eventtype' => 'user', + 'userid' => 0, + 'eventtype' => 'due', 'repeats' => 0, 'timestart' => 1, ]; diff --git a/calendar/tests/privacy_test.php b/calendar/tests/privacy_test.php index d2173b79a80..6cd78cdf1b9 100644 --- a/calendar/tests/privacy_test.php +++ b/calendar/tests/privacy_test.php @@ -80,8 +80,8 @@ class core_calendar_privacy_testcase extends provider_testcase { $course3context = context_course::instance($course3->id); // Add Category Calendar Events for Category. - $this->create_test_standard_calendar_event('category', $user->id, time(), '', $category->id); - $this->create_test_standard_calendar_event('category', $user->id, time(), '', $category->id); + $this->create_test_standard_calendar_event('category', 0, time(), '', $category->id); + $this->create_test_standard_calendar_event('category', 0, time(), '', $category->id); // Add User Calendar Events for User. $this->create_test_standard_calendar_event('user', $user->id, time(), ''); @@ -89,38 +89,43 @@ class core_calendar_privacy_testcase extends provider_testcase { $this->create_test_standard_calendar_event('user', $user->id, time(), '', 0, $course2->id); // Add a Course Calendar Event for Course 1. - $this->create_test_standard_calendar_event('course', $user->id, time(), '', 0, $course1->id); + $this->create_test_standard_calendar_event('course', 0, time(), '', 0, $course1->id); // Add a Course Assignment Action Calendar Event for Course 2. - $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign'); + $assigngenerator = $this->getDataGenerator()->get_plugin_generator('mod_assign'); $params['course'] = $course2->id; $params['assignsubmission_onlinetext_enabled'] = 1; - $instance = $generator->create_instance($params); - $cm = get_coursemodule_from_instance('assign', $instance->id); - $modulecontext = context_module::instance($cm->id); - $assign = new assign($modulecontext, $cm, $course2); - $this->create_test_action_calendar_event('duedate', $course2->id, $instance->id, 'assign', $user->id, time()); - $this->create_test_action_calendar_event('gradingduedate', $course2->id, $instance->id, 'assign', $user->id, time()); + $assign1 = $assigngenerator->create_instance($params); + $assign1cm = get_coursemodule_from_instance('assign', $assign1->id); + $assign1context = context_module::instance($assign1cm->id); + $this->create_test_action_calendar_event('duedate', $course2->id, $assign1->id, 'assign', 0, time()); + $this->create_test_action_calendar_event('gradingduedate', $course2->id, $assign1->id, 'assign', 0, time()); + + // Add a due date event similar to a user override in another assign instance. + $assign2 = $assigngenerator->create_instance($params); + $assign2cm = get_coursemodule_from_instance('assign', $assign2->id); + $assign2context = context_module::instance($assign2cm->id); + $this->create_test_action_calendar_event('duedate', $course2->id, $assign2->id, 'assign', $user->id, time()); + $this->create_test_action_calendar_event('gradingduedate', $course2->id, $assign2->id, 'assign', $user->id, time()); // Add a Calendar Subscription and Group Calendar Event to Course 3. - $this->create_test_calendar_subscription('course', 'https://calendar.google.com/', $user->id, 0, $course3->id); - $this->create_test_standard_calendar_event('group', $user->id, time(), '', 0, $course3->id, $course3group->id); + $this->create_test_calendar_subscription('course', 'https://calendar.google.com/', 0, 0, $course3->id); + $this->create_test_standard_calendar_event('group', 0, time(), '', 0, $course3->id, $course3group->id); // The user will be in these contexts. $usercontextids = [ $usercontext->id, - $categorycontext->id, - $course1context->id, - $modulecontext->id, - $course3context->id + $assign2context->id, ]; // Retrieve the user's context ids. $contextids = provider::get_contexts_for_userid($user->id); // Check the user context list and retrieved user context lists contains the same number of records. - $this->assertEquals(count($usercontextids), count($contextids->get_contextids())); + $this->assertCount(count($usercontextids), $contextids->get_contextids()); // There should be no difference between the contexts. $this->assertEmpty(array_diff($usercontextids, $contextids->get_contextids())); + // Check that the module context for the assignment without user override event is not included. + $this->assertNotContains($assign1context->id, $contextids->get_contextids()); } /** @@ -150,12 +155,12 @@ class core_calendar_privacy_testcase extends provider_testcase { $event1 = $this->create_test_standard_calendar_event('user', $user->id, time(), ''); // Add Category Calendar Events for Category. - $event2 = $this->create_test_standard_calendar_event('category', $user->id, time(), '', $category->id); + $event2 = $this->create_test_standard_calendar_event('category', 0, time(), '', $category->id); // Add two Course Calendar Event for Course 1 and set the same time (1 day a head). $time = strtotime('+1 day', time()); - $event3 = $this->create_test_standard_calendar_event('course', $user->id, $time, 'ABC', 0, $course1->id); - $event4 = $this->create_test_standard_calendar_event('course', $user->id, $time, 'DEF', 0, $course1->id); + $event3 = $this->create_test_standard_calendar_event('course', 0, $time, 'ABC', 0, $course1->id); + $event4 = $this->create_test_standard_calendar_event('course', 0, $time, 'DEF', 0, $course1->id); // Add a Course Assignment Action Calendar Event for Course 2. $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign'); @@ -169,7 +174,7 @@ class core_calendar_privacy_testcase extends provider_testcase { // Add a Calendar Subscription and Group Calendar Event to Course 3. $subscription1 = $this->create_test_calendar_subscription('course', 'https://calendar.google.com/', $user->id, 0, $course3->id); - $event6 = $this->create_test_standard_calendar_event('group', $user->id, time(), '', 0, $course3->id, $course3group->id); + $event6 = $this->create_test_standard_calendar_event('group', 0, time(), '', 0, $course3->id, $course3group->id); // Retrieve the user's context ids. $contextlist = provider::get_contexts_for_userid($user->id); @@ -320,16 +325,16 @@ class core_calendar_privacy_testcase extends provider_testcase { // Add a Course Calendar Event by User 1 for Course 1 and Course 2. $this->setUser($user1); - $this->create_test_standard_calendar_event('course', $user1->id, time(), '', 0, $course1->id); - $this->create_test_standard_calendar_event('course', $user1->id, time(), '', 0, $course2->id); + $this->create_test_standard_calendar_event('course', 0, time(), '', 0, $course1->id); + $this->create_test_standard_calendar_event('course', 0, time(), '', 0, $course2->id); // Add a Calendar Subscription by User 1 for Course 1. $this->create_test_calendar_subscription('course', 'https://calendar.google.com/', $user1->id, 0, $course1->id); // Add a Course Calendar Event by User 2 for Course 1 and Course 2. $this->setUser($user2); - $this->create_test_standard_calendar_event('course', $user2->id, time(), '', 0, $course1->id); - $this->create_test_standard_calendar_event('course', $user2->id, time(), '', 0, $course2->id); + $this->create_test_standard_calendar_event('course', 0, time(), '', 0, $course1->id); + $this->create_test_standard_calendar_event('course', 0, time(), '', 0, $course2->id); // Add a Calendar Subscription by User 2 for Course 2. $this->create_test_calendar_subscription('course', 'https://calendar.google.com/', $user2->id, 0, $course2->id); @@ -342,23 +347,23 @@ class core_calendar_privacy_testcase extends provider_testcase { $cm = get_coursemodule_from_instance('assign', $instance->id); $modulecontext = context_module::instance($cm->id); $assign = new assign($modulecontext, $cm, $course2); - $this->create_test_action_calendar_event('duedate', $course2->id, $instance->id, 'assign', $user2->id, time()); + $this->create_test_action_calendar_event('duedate', $course2->id, $instance->id, 'assign', 0, time()); $this->create_test_action_calendar_event('gradingduedate', $course2->id, $instance->id, 'assign', $user2->id, time()); // Delete all Calendar Events for all Users by Context for Course 1. provider::delete_data_for_all_users_in_context($course1context); - // Verify all Calendar Events for Course 1 were deleted. + // The course1 events should still exist, since it belongs to the course and not to the user who created them. $events = $DB->get_records('event', array('courseid' => $course1->id)); - $this->assertCount(0, $events); - // Verify all Calendar Subscriptions for Course 1 were deleted. + $this->assertCount(2, $events); + // Course1 subscription should still exist, since it belongs to the course and not to the user who created them. $subscriptions = $DB->get_records('event_subscriptions', array('courseid' => $course1->id)); - $this->assertCount(0, $subscriptions); + $this->assertCount(1, $subscriptions); - // Verify all Calendar Events for Course 2 exists still. + // The course2 events should still exist, since it belongs to the course and not to the user who created them. $events = $DB->get_records('event', array('courseid' => $course2->id)); $this->assertCount(4, $events); - // Verify all Calendar Subscriptions for Course 2 exists still. + // Course2 subscription should still exist, since it belongs to the course and not to the user who created them. $subscriptions = $DB->get_records('event_subscriptions', array('courseid' => $course2->id)); $this->assertCount(1, $subscriptions); @@ -367,10 +372,10 @@ class core_calendar_privacy_testcase extends provider_testcase { // Verify all Calendar Events for Course 2 context were deleted. $events = $DB->get_records('event', array('courseid' => $course2->id, 'modulename' => '0')); - $this->assertCount(0, $events); + $this->assertCount(2, $events); // Verify all Calendar Subscriptions for Course 2 were deleted. $subscriptions = $DB->get_records('event_subscriptions', array('courseid' => $course2->id)); - $this->assertCount(0, $subscriptions); + $this->assertCount(1, $subscriptions); // Verify all Calendar Events for the assignment exists still. $events = $DB->get_records('event', array('modulename' => 'assign')); @@ -379,9 +384,9 @@ class core_calendar_privacy_testcase extends provider_testcase { // Delete all Calendar Events for all Users by Context for the assignment. provider::delete_data_for_all_users_in_context($modulecontext); - // Verify all Calendar Events for the assignment context were deleted. + // Verify that the action event still exists since it is not a user override. $events = $DB->get_records('event', array('modulename' => 'assign')); - $this->assertCount(0, $events); + $this->assertCount(1, $events); } /** @@ -401,25 +406,28 @@ class core_calendar_privacy_testcase extends provider_testcase { $course1 = $this->getDataGenerator()->create_course(); $course2 = $this->getDataGenerator()->create_course(); - // Add 5 Calendar Events for User 1 for various contexts. + // Add 6 events for user 1 for various contexts. $this->setUser($user1); $this->create_test_standard_calendar_event('user', $user1->id, time(), ''); - $this->create_test_standard_calendar_event('site', $user1->id, time(), '', 0, 1); - $this->create_test_standard_calendar_event('category', $user1->id, time(), '', $category->id); - $this->create_test_standard_calendar_event('course', $user1->id, time(), '', 0, $course1->id); - $this->create_test_standard_calendar_event('course', $user1->id, time(), '', 0, $course2->id); + $this->create_test_standard_calendar_event('user', $user1->id, time(), ''); + $this->create_test_standard_calendar_event('site', 0, time(), '', 0, 1); + $this->create_test_standard_calendar_event('category', 0, time(), '', $category->id); + $this->create_test_standard_calendar_event('course', 0, time(), '', 0, $course1->id); + $this->create_test_standard_calendar_event('course', 0, time(), '', 0, $course2->id); - // Add 1 Calendar Subscription for User 1 at course context. - $this->create_test_calendar_subscription('course', 'https://calendar.google.com/', $user1->id, 0, $course2->id); + // Add two subscription for user 1 at course and user contexts. + $this->create_test_calendar_subscription('course', 'https://calendar.google.com/', 0, 0, $course2->id); + $this->create_test_calendar_subscription('user', 'https://calendar.google.com/', $user1->id); - // Add 3 Calendar Events for User 2 for various contexts. + // Add four events for user 2 for various contexts. $this->setUser($user2); $this->create_test_standard_calendar_event('user', $user2->id, time(), ''); - $this->create_test_standard_calendar_event('category', $user2->id, time(), '', $category->id); - $this->create_test_standard_calendar_event('course', $user2->id, time(), '', 0, $course1->id); + $this->create_test_standard_calendar_event('user', $user2->id, time(), ''); + $this->create_test_standard_calendar_event('category', 0, time(), '', $category->id); + $this->create_test_standard_calendar_event('course', 0, time(), '', 0, $course1->id); - // Add 1 Calendar Subscription for User 2 at course context. - $this->create_test_calendar_subscription('course', 'https://calendar.google.com/', $user2->id, 0, $course2->id); + // Add a calendar Subscription for User 2 at course context. + $this->create_test_calendar_subscription('user', 'https://calendar.google.com/', $user2->id, 0, $course2->id); // Retrieve the user's context ids. $contextlist = provider::get_contexts_for_userid($user1->id); @@ -428,17 +436,31 @@ class core_calendar_privacy_testcase extends provider_testcase { // Delete all Calendar data for User 1. provider::delete_data_for_user($approvedcontextlist); - // Test all Calendar Events and Subscriptions for User 1 equals zero. + // All user events created by user1 should have been removed. $events = $DB->get_records('event', ['userid' => $user1->id]); $this->assertCount(0, $events); + // The subscription created by user1 should have been deleted. $eventsubscriptions = $DB->get_records('event_subscriptions', ['userid' => $user1->id]); $this->assertCount(0, $eventsubscriptions); - // Test all Calendar Events and Subscriptions for User 2 still exists and matches the same number created. + // Test all calendar events and subscriptions for user2 still exists and matches the same number created. $events = $DB->get_records('event', ['userid' => $user2->id]); - $this->assertCount(3, $events); + $this->assertCount(2, $events); + // The subscription created by user2 should have not been deleted. $eventsubscriptions = $DB->get_records('event_subscriptions', ['userid' => $user2->id]); $this->assertCount(1, $eventsubscriptions); + + // There should be only six "shared" events created (userid equal zero). + // One site, one category and two course events that were created by user1. + // One category and one course event created by user2. + $events = $DB->get_records('event', ['userid' => 0]); + $this->assertCount(6, $events); + + // There should be eight event created in total. + // One site, one category and two course events that were created by user1. + // One category, one course and two user events created by user2. + $events = $DB->get_records('event'); + $this->assertCount(8, $events); } /** @@ -474,10 +496,10 @@ class core_calendar_privacy_testcase extends provider_testcase { // Add Category Calendar Events for Category. $this->setUser($user1); - $this->create_test_standard_calendar_event('category', $user1->id, time(), '', + $this->create_test_standard_calendar_event('category', 0, time(), '', $category->id); $this->setUser($user2); - $this->create_test_standard_calendar_event('category', $user2->id, time(), '', + $this->create_test_standard_calendar_event('category', 0, time(), '', $category->id); // Add User Calendar Events for user1 and user2. @@ -493,10 +515,10 @@ class core_calendar_privacy_testcase extends provider_testcase { // Add a Course Calendar Events for Course 1. $this->setUser($user1); - $this->create_test_standard_calendar_event('course', $user1->id, time(), '', + $this->create_test_standard_calendar_event('course', 0, time(), '', 0, $course1->id); $this->setUser($user2); - $this->create_test_standard_calendar_event('course', $user2->id, time(), '', + $this->create_test_standard_calendar_event('course', 0, time(), '', 0, $course1->id); // Add a Course Assignment Action Calendar Event for Course 2. @@ -514,7 +536,7 @@ class core_calendar_privacy_testcase extends provider_testcase { 'assign', $user2->id, time()); // Add a Calendar Subscription and Group Calendar Event to Course 3. - $this->create_test_standard_calendar_event('group', $user2->id, time(), '', 0, + $this->create_test_standard_calendar_event('group', 0, time(), '', 0, $course3->id, $course3group->id); $this->setUser($user3); $this->create_test_calendar_subscription('course', 'https://calendar.google.com/', $user3->id, @@ -530,28 +552,22 @@ class core_calendar_privacy_testcase extends provider_testcase { provider::get_users_in_context($userlist2); $this->assertCount(1, $userlist2); $this->assertTrue(in_array($user2->id, $userlist2->get_userids())); - // The user list for course1context should return user1 and user2. + // The user list for course1context should not return any users. $userlist3 = new \core_privacy\local\request\userlist($course1context, $component); provider::get_users_in_context($userlist3); - $this->assertCount(2, $userlist3); - $this->assertTrue(in_array($user1->id, $userlist3->get_userids())); - $this->assertTrue(in_array($user2->id, $userlist3->get_userids())); + $this->assertCount(0, $userlist3); // The user list for course2context should not return any users. $userlist4 = new \core_privacy\local\request\userlist($course2context, $component); provider::get_users_in_context($userlist4); $this->assertCount(0, $userlist4); - // The user list for course3context should return user2 and user3. + // The user list for course3context should not return any users. $userlist5 = new \core_privacy\local\request\userlist($course3context, $component); provider::get_users_in_context($userlist5); - $this->assertCount(2, $userlist5); - $this->assertTrue(in_array($user2->id, $userlist5->get_userids())); - $this->assertTrue(in_array($user3->id, $userlist5->get_userids())); - // The user list for categorycontext should return user1 and user2. + $this->assertCount(0, $userlist5); + // The user list for categorycontext should not return any users. $userlist6 = new \core_privacy\local\request\userlist($categorycontext, $component); provider::get_users_in_context($userlist6); - $this->assertCount(2, $userlist6); - $this->assertTrue(in_array($user1->id, $userlist6->get_userids())); - $this->assertTrue(in_array($user2->id, $userlist6->get_userids())); + $this->assertCount(0, $userlist6); // The user list for modulecontext should return user2. $userlist7 = new \core_privacy\local\request\userlist($modulecontext, $component); provider::get_users_in_context($userlist7); @@ -596,10 +612,10 @@ class core_calendar_privacy_testcase extends provider_testcase { // Add Category Calendar Events for Category. $this->setUser($user1); - $this->create_test_standard_calendar_event('category', $user1->id, time(), '', + $this->create_test_standard_calendar_event('category', 0, time(), '', $category->id); $this->setUser($user2); - $this->create_test_standard_calendar_event('category', $user2->id, time(), '', + $this->create_test_standard_calendar_event('category', 0, time(), '', $category->id); // Add User Calendar Events for user1 and user2. @@ -615,10 +631,10 @@ class core_calendar_privacy_testcase extends provider_testcase { // Add a Course Calendar Events for Course 1. $this->setUser($user1); - $this->create_test_standard_calendar_event('course', $user1->id, time(), '', + $this->create_test_standard_calendar_event('course', 0, time(), '', 0, $course1->id); $this->setUser($user2); - $this->create_test_standard_calendar_event('course', $user2->id, time(), '', + $this->create_test_standard_calendar_event('course', 0, time(), '', 0, $course1->id); // Add a Course Assignment Action Calendar Event for Course 2. @@ -636,7 +652,7 @@ class core_calendar_privacy_testcase extends provider_testcase { 'assign', $user2->id, time()); // Add a Calendar Subscription and Group Calendar Event to Course 3. - $this->create_test_standard_calendar_event('group', $user2->id, time(), '', 0, + $this->create_test_standard_calendar_event('group', 0, time(), '', 0, $course3->id, $course3group->id); $this->setUser($user3); $this->create_test_calendar_subscription('course', 'https://calendar.google.com/', $user3->id, @@ -650,22 +666,22 @@ class core_calendar_privacy_testcase extends provider_testcase { $userlist2 = new \core_privacy\local\request\userlist($usercontext2, $component); provider::get_users_in_context($userlist2); $this->assertCount(1, $userlist2); - // The user list for course1context should return user1 and user2. + // The user list for course1context should not return any users. $userlist3 = new \core_privacy\local\request\userlist($course1context, $component); provider::get_users_in_context($userlist3); - $this->assertCount(2, $userlist3); + $this->assertCount(0, $userlist3); // The user list for course2context should not return any users. $userlist4 = new \core_privacy\local\request\userlist($course2context, $component); provider::get_users_in_context($userlist4); $this->assertCount(0, $userlist4); - // The user list for course3context should return user2 and user3. + // The user list for course3context should not return any users. $userlist5 = new \core_privacy\local\request\userlist($course3context, $component); provider::get_users_in_context($userlist5); - $this->assertCount(2, $userlist5); - // The user list for categorycontext should return user1 and user2. + $this->assertCount(0, $userlist5); + // The user list for categorycontext should not return any users. $userlist6 = new \core_privacy\local\request\userlist($categorycontext, $component); provider::get_users_in_context($userlist6); - $this->assertCount(2, $userlist6); + $this->assertCount(0, $userlist6); // The user list for modulecontext should return user2. $userlist7 = new \core_privacy\local\request\userlist($modulecontext, $component); provider::get_users_in_context($userlist7); @@ -693,28 +709,25 @@ class core_calendar_privacy_testcase extends provider_testcase { $approvedlist2 = new approved_userlist($course1context, $component, []); // Delete using delete_data_for_user. provider::delete_data_for_users($approvedlist2); - // The user list for course1context should return user1 and user2. + // The user list for course1context should not return any users. $userlist3 = new \core_privacy\local\request\userlist($course1context, $component); provider::get_users_in_context($userlist3); - $this->assertCount(2, $userlist3); - $this->assertTrue(in_array($user1->id, $userlist3->get_userids())); - $this->assertTrue(in_array($user2->id, $userlist3->get_userids())); + $this->assertCount(0, $userlist3); // Convert $userlist3 into an approved_contextlist. // Pass the ID of user1 as a value for the approved user list. $approvedlist2 = new approved_userlist($course1context, $component, [$user1->id]); // Delete using delete_data_for_user. provider::delete_data_for_users($approvedlist2); - // The user list for course1context should return user2. + // The user list for course1context should not return any users. $userlist3 = new \core_privacy\local\request\userlist($course1context, $component); provider::get_users_in_context($userlist3); - $this->assertCount(1, $userlist3); - $this->assertTrue(in_array($user2->id, $userlist3->get_userids())); + $this->assertCount(0, $userlist3); - // The user list for course3context should still return user2 and user3. + // The user list for course3context should not return any users. $userlist5 = new \core_privacy\local\request\userlist($course3context, $component); provider::get_users_in_context($userlist5); - $this->assertCount(2, $userlist5); + $this->assertCount(0, $userlist5); // Convert $userlist6 into an approved_contextlist. $approvedlist3 = new approved_userlist($categorycontext, $component, $userlist6->get_userids()); @@ -762,7 +775,7 @@ class core_calendar_privacy_testcase extends provider_testcase { 'categoryid' => $categoryid, 'courseid' => $courseid, 'groupid' => $groupid, - 'userid' => $userid, + 'userid' => ($eventtype == 'user') ? $userid : 0, 'modulename' => 0, 'instance' => 0, 'eventtype' => $eventtype, @@ -822,7 +835,7 @@ class core_calendar_privacy_testcase extends provider_testcase { 'categoryid' => $categoryid, 'courseid' => $courseid, 'groupid' => $groupid, - 'userid' => $userid, + 'userid' => ($eventtype == 'user') ? $userid : 0, 'eventtype' => $eventtype ]; diff --git a/lib/db/upgrade.php b/lib/db/upgrade.php index 532b238c23d..9e49c7f8be1 100644 --- a/lib/db/upgrade.php +++ b/lib/db/upgrade.php @@ -2471,5 +2471,17 @@ function xmldb_main_upgrade($oldversion) { upgrade_main_savepoint(true, 2021052500.64); } + if ($oldversion < 2021052500.65) { + // This upgrade step will update all shared events setting userid to 0. + // Site, category, course, group and action events (except user overrides) dont belong to the user who creates them. + $DB->execute("UPDATE {event} SET userid = 0 WHERE eventtype <> 'user' OR priority <> 0"); + + // Only user type of subscription should record user id. + $DB->execute("UPDATE {event_subscriptions} SET userid = 0 WHERE eventtype <> 'user'"); + + // Main savepoint reached. + upgrade_main_savepoint(true, 2021052500.65); + } + return true; } diff --git a/lib/moodlelib.php b/lib/moodlelib.php index 75ac71f4bde..f9576e9f19d 100644 --- a/lib/moodlelib.php +++ b/lib/moodlelib.php @@ -4275,7 +4275,7 @@ function delete_user(stdClass $user) { // Now do a brute force cleanup. // Delete all user events and subscription events. - $DB->delete_records_select('event', 'userid = :userid AND subscriptionid IS NOT NULL', ['userid' => $user->id]); + $DB->delete_records_select('event', 'userid = :userid', ['userid' => $user->id]); // Now, delete all calendar subscription from the user. $DB->delete_records('event_subscriptions', ['userid' => $user->id]); diff --git a/lib/testing/generator/data_generator.php b/lib/testing/generator/data_generator.php index a5697b50ee5..600cc762a2c 100644 --- a/lib/testing/generator/data_generator.php +++ b/lib/testing/generator/data_generator.php @@ -1139,19 +1139,23 @@ EOD; break; case 'group': unset($record->categoryid); + unset($record->userid); break; case 'course': unset($record->categoryid); unset($record->groupid); + unset($record->userid); break; case 'category': unset($record->courseid); unset($record->groupid); + unset($record->userid); break; case 'site': unset($record->categoryid); unset($record->courseid); unset($record->groupid); + unset($record->userid); break; } diff --git a/mod/assign/lib.php b/mod/assign/lib.php index d9ded666cd7..c3d172e2819 100644 --- a/mod/assign/lib.php +++ b/mod/assign/lib.php @@ -302,7 +302,7 @@ function assign_update_events($assign, $override = null) { // Events module won't show user events when the courseid is nonzero. $event->courseid = ($userid) ? 0 : $assigninstance->course; $event->groupid = $groupid; - $event->userid = $userid; + $event->userid = 0; $event->modulename = 'assign'; $event->instance = $assigninstance->id; $event->timestart = $duedate; @@ -332,6 +332,8 @@ function assign_update_events($assign, $override = null) { $params = new stdClass(); $params->assign = $assigninstance->name; $eventname = get_string('overrideusereventname', 'assign', $params); + // Only set userid for user override events. + $event->userid = $userid; // Set user override priority. $event->priority = CALENDAR_EVENT_USER_OVERRIDE_PRIORITY; } else { diff --git a/mod/lesson/lib.php b/mod/lesson/lib.php index 45444fcc958..8275fea8574 100644 --- a/mod/lesson/lib.php +++ b/mod/lesson/lib.php @@ -167,7 +167,7 @@ function lesson_update_events($lesson, $override = null) { // Events module won't show user events when the courseid is nonzero. $event->courseid = ($userid) ? 0 : $lesson->course; $event->groupid = $groupid; - $event->userid = $userid; + $event->userid = 0; $event->modulename = 'lesson'; $event->instance = $lesson->id; $event->timestart = $available; @@ -200,6 +200,8 @@ function lesson_update_events($lesson, $override = null) { $params = new stdClass(); $params->lesson = $lesson->name; $eventname = get_string('overrideusereventname', 'lesson', $params); + // Only set userid for user override events. + $event->userid = $userid; // Set user override priority. $event->priority = CALENDAR_EVENT_USER_OVERRIDE_PRIORITY; } else { diff --git a/mod/quiz/lib.php b/mod/quiz/lib.php index 37873c60a4b..ba56c86b4ab 100644 --- a/mod/quiz/lib.php +++ b/mod/quiz/lib.php @@ -1268,7 +1268,7 @@ function quiz_update_events($quiz, $override = null) { // Events module won't show user events when the courseid is nonzero. $event->courseid = ($userid) ? 0 : $quiz->course; $event->groupid = $groupid; - $event->userid = $userid; + $event->userid = 0; $event->modulename = 'quiz'; $event->instance = $quiz->id; $event->timestart = $timeopen; @@ -1301,6 +1301,8 @@ function quiz_update_events($quiz, $override = null) { $params = new stdClass(); $params->quiz = $quiz->name; $eventname = get_string('overrideusereventname', 'quiz', $params); + // Only set userid for override events. + $event->userid = $userid; // Set user override priority. $event->priority = CALENDAR_EVENT_USER_OVERRIDE_PRIORITY; } else { diff --git a/version.php b/version.php index 3f7de16ae8e..1f2f578e4a9 100644 --- a/version.php +++ b/version.php @@ -29,7 +29,7 @@ defined('MOODLE_INTERNAL') || die(); -$version = 2021052500.64; // YYYYMMDD = weekly release date of this DEV branch. +$version = 2021052500.65; // YYYYMMDD = weekly release date of this DEV branch. // RR = release increments - 00 in DEV branches. // .XX = incremental changes. $release = '4.0dev (Build: 20210226)'; // Human-friendly version name