in classes/feature/calsync/task/syncoldevents.php [190:327]
protected function sync_courseevents($courseid, $timecreated) {
global $DB;
$timestart = time();
// Check the last time course events for this course were synced.
// Using a direct query here so we don't run into static cache issues.
$lastcoursesync = $DB->get_record('config_plugins', ['plugin' => 'local_o365', 'name' => 'cal_course_lastsync']);
if (!empty($lastcoursesync)) {
$lastcoursesync = unserialize($lastcoursesync->value);
if (isset($lastcoursesync[$courseid]) && (int)$lastcoursesync[$courseid] > $timecreated) {
// Course events for this course have been synced since this event was created, so we don't have to do it again.
return true;
}
}
$clientdata = \local_o365\oauth2\clientdata::instance_from_oidc();
$httpclient = new \local_o365\httpclient();
$calsync = new \local_o365\feature\calsync\main($clientdata, $httpclient);
list($subscribersprimary, $subscribersnotprimary) = $this->get_subscribers('course', $courseid);
$sql = 'SELECT ev.id AS eventid,
ev.name AS eventname,
ev.description AS eventdescription,
ev.timestart AS eventtimestart,
ev.timeduration AS eventtimeduration,
idmap.outlookeventid,
ev.userid AS eventuserid,
ev.groupid
FROM {event} ev
LEFT JOIN {local_o365_calidmap} idmap ON ev.id = idmap.eventid AND idmap.userid = ev.userid
WHERE ev.courseid = ? ';
$params = [$courseid];
$events = $DB->get_recordset_sql($sql, $params);
foreach ($events as $event) {
try {
mtrace('Syncing course event #'.$event->eventid);
$grouplimit = null;
// If this is a group event, get members and save for limiting later.
if (!empty($event->groupid)) {
$sql = 'SELECT userid
FROM {groups_members}
WHERE groupid = ?';
$params = [$event->groupid];
$grouplimit = $DB->get_records_sql($sql, $params);
}
$subject = $event->eventname;
$body = $event->eventdescription;
$evstart = $event->eventtimestart;
$evend = $evstart + $event->eventtimeduration;
// Sync primary cal users first.
if (!empty($subscribersprimary)) {
mtrace('Syncing primary calendar users.');
try {
// Determine attendees - if this is a group event, limit to group members.
if ($grouplimit !== null && is_array($grouplimit)) {
$eventattendees = array_intersect_key($subscribersprimary, $grouplimit);
} else {
$eventattendees = $subscribersprimary;
}
// If there's a stored outlookeventid the event exists in o365, so update it. Otherwise create it.
if (!empty($event->outlookeventid)) {
$calsync->update_event_raw($event->eventuserid, $event->outlookeventid,
['attendees' => $eventattendees]);
} else {
$calid = null;
if (!empty($subscribersprimary[$event->eventuserid])) {
if (!empty($subscribersprimary[$event->eventuserid]->subo365calid)) {
$calid = $subscribersprimary[$event->eventuserid]->subo365calid;
} else {
$calid = null;
}
} else if (isset($subscribersnotprimary[$event->eventuserid])) {
if (!empty($subscribersnotprimary[$event->eventuserid]->subo365calid)) {
$calid = $subscribersnotprimary[$event->eventuserid]->subo365calid;
} else {
$calid = null;
}
}
$calsync->create_event_raw($event->eventuserid, $event->eventid, $subject, $body, $evstart, $evend,
$eventattendees, [], $calid);
}
} catch (\Exception $e) {
mtrace('ERROR: '.$e->getMessage());
}
}
// Delete event for users who have an idmap record but are no longer subscribed.
// Users would have an idmap record if they were non-primary calendar users, and are thus not taken care of with
// the attendee update done above.
$sql = 'SELECT userid, id, eventid, outlookeventid FROM {local_o365_calidmap} WHERE eventid = ? AND origin = ?';
$idmapnosub = $DB->get_records_sql($sql, [$event->eventid, 'moodle']);
$idmapnosub = array_diff_key($idmapnosub, $subscribersnotprimary, $subscribersprimary);
if (isset($idmapnosub[$event->eventuserid])) {
// If the user who created the event is included, remove them. THIS IS VERY IMPORTANT. Otherwise any event
// in a calendar that the creator is not subscribed to will be removed, negating the work we did above with
// attendees.
unset($idmapnosub[$event->eventuserid]);
}
if (!empty($idmapnosub)) {
mtrace('Removing event for users who have unsubscribed.');
foreach ($idmapnosub as $userid => $usercalidmap) {
$calsync->delete_event_raw($userid, $usercalidmap->outlookeventid, $usercalidmap->id);
}
}
// Sync non-primary cal users.
if (!empty($subscribersnotprimary)) {
mtrace('Syncing non-primary calendar users.');
foreach ($subscribersnotprimary as $userid => $user) {
// If we're syncing a group event, only sync users in the group.
if ($grouplimit !== null && is_array($grouplimit) && !isset($grouplimit[$user->id])) {
continue;
}
$calid = (!empty($user->subo365calid)) ? $user->subo365calid : null;
$calsync->ensure_event_synced_for_user($event->eventid, $user->id, $subject, $body, $evstart, $evend,
$calid);
}
}
} catch (\Exception $e) {
// Could not sync this course event. Log and continue.
mtrace('Error syncing course event #'.$event->eventid.': '.$e->getMessage());
}
}
$events->close();
if (!empty($lastcoursesync) && is_array($lastcoursesync)) {
$lastcoursesync[$courseid] = $timestart;
} else {
$lastcoursesync = [$courseid => $timestart];
}
$lastcoursesync = serialize($lastcoursesync);
set_config('cal_course_lastsync', $lastcoursesync, 'local_o365');
return true;
}