/** * Do the job. */ public function execute() { global $DB, $CFG; require_once $CFG->dirroot . '/calendar/lib.php'; // Get calendars set to sync in. $starttime = time(); \local_o365\feature\calsync\observers::set_event_import(true); // Using a direct query here so we don't run into static cache issues. $laststarttime = $DB->get_record('config_plugins', ['plugin' => 'local_o365', 'name' => 'calsyncinlastrun']); $laststarttime = !empty($laststarttime) && !empty($laststarttime->value) ? $laststarttime->value : 0; $httpclient = new \local_o365\httpclient(); $clientdata = \local_o365\oauth2\clientdata::instance_from_oidc(); $calsubs = $DB->get_recordset_select('local_o365_calsub', 'syncbehav = ? OR syncbehav = ?', ['in', 'both']); $calsync = new \local_o365\feature\calsync\main($clientdata, $httpclient); foreach ($calsubs as $i => $calsub) { try { $events = $calsync->get_events($calsub->user_id, $calsub->o365calid, $laststarttime); if (!empty($events) && is_array($events) && isset($events['value']) && is_array($events['value'])) { if (!empty($events['value'])) { foreach ($events['value'] as $i => $event) { if (!isset($event['Id'])) { mtrace('Skipped an event because of malformed data.'); continue; } $idmapexists = $DB->record_exists('local_o365_calidmap', ['outlookeventid' => $event['Id']]); if ($idmapexists === false) { // Create Moodle event. $eventparams = ['name' => $event['Subject'], 'description' => $event['Body']['Content'], 'eventtype' => $calsub->caltype, 'repeatid' => 0, 'modulename' => 0, 'instance' => 0, 'timestart' => strtotime($event['Start']), 'visible' => 1, 'uuid' => '', 'sequence' => 1]; $end = strtotime($event['End']); $eventparams['timeduration'] = $end - $eventparams['timestart']; if ($calsub->caltype === 'user') { $eventparams['userid'] = $calsub->caltypeid; } if ($calsub->caltype === 'course') { $eventparams['courseid'] = $calsub->caltypeid; } $moodleevent = \calendar_event::create($eventparams, false); if (!empty($moodleevent) && !empty($moodleevent->id)) { $idmaprec = ['eventid' => $moodleevent->id, 'outlookeventid' => $event['Id'], 'origin' => 'o365', 'userid' => $calsub->user_id]; $DB->insert_record('local_o365_calidmap', (object) $idmaprec); mtrace('Successfully imported event #' . $moodleevent->id); } } } } else { mtrace('No new events to sync in.'); } } else { mtrace('Bad response received when fetching events.'); } } catch (\Exception $e) { mtrace('Error: ' . $e->getMessage()); } } $calsubs->close(); \local_o365\feature\calsync\observers::set_event_import(false); set_config('calsyncinlastrun', $starttime, 'local_o365'); return true; }
/** * Constructor * * @param int $repositoryid repository instance id * @param int|stdClass $context a context id or context object * @param array $options repository options * @param int $readonly indicate this repo is readonly or not */ public function __construct($repositoryid, $context = SYSCONTEXTID, $options = array(), $readonly = 0) { parent::__construct($repositoryid, $context, $options, $readonly); $this->httpclient = new \local_o365\httpclient(); $this->clientdata = \local_o365\oauth2\clientdata::instance_from_oidc(); $this->onedriveconfigured = \local_o365\rest\onedrive::is_configured(); $this->unifiedconfigured = \local_o365\rest\unified::is_configured(); $this->sharepointconfigured = \local_o365\rest\sharepoint::is_configured(); }
/** * Do the job. */ public function execute() { if (\local_o365\utils::is_configured() !== true) { return false; } $aadsyncenabled = get_config('local_o365', 'aadsync'); if (empty($aadsyncenabled) || $aadsyncenabled === 'photosynconlogin') { mtrace('Azure AD cron sync disabled. Nothing to do.'); return true; } $httpclient = new \local_o365\httpclient(); $clientdata = \local_o365\oauth2\clientdata::instance_from_oidc(); $usersync = new \local_o365\feature\usersync\main($clientdata, $httpclient); $skiptoken = get_config('local_o365', 'task_usersync_lastskiptoken'); if (empty($skiptoken)) { $skiptoken = ''; } for ($i = 0; $i < 5; $i++) { $users = $usersync->get_users('default', $skiptoken); if (!empty($users) && is_array($users) && !empty($users['value']) && is_array($users['value'])) { $usersync->sync_users($users['value']); } else { // No users returned, we're likely past the last page of results. Erase deltalink state and exit loop. mtrace('No more users to sync.'); set_config('task_usersync_lastskiptoken', '', 'local_o365'); break; } $nextlink = ''; if (isset($users['odata.nextLink'])) { $nextlink = $users['odata.nextLink']; } else { if (isset($users['@odata.nextLink'])) { $nextlink = $users['@odata.nextLink']; } } // If we have an odata.nextLink, extract deltalink value and store in $deltalink for the next loop. Otherwise break. if (!empty($nextlink)) { $skiptoken = $this->extract_skiptoken($nextlink); if (empty($skiptoken)) { $skiptoken = ''; mtrace('Bad odata.nextLink received.'); break; } } else { $skiptoken = ''; mtrace('No odata.nextLink received.'); break; } } if (!empty($skiptoken)) { mtrace('Partial user sync completed. Saving place for next run.'); } else { mtrace('Full user sync completed. Resetting saved state for new run.'); } set_config('task_usersync_lastskiptoken', $skiptoken, 'local_o365'); return true; }
/** * Get the token to authenticate with OneNote. * * @return string The token to authenticate with OneNote. */ public function get_token() { global $USER; $httpclient = new \local_o365\httpclient(); $clientdata = \local_o365\oauth2\clientdata::instance_from_oidc(); $resource = \local_o365\rest\onenote::get_resource(); $token = \local_o365\oauth2\token::instance($USER->id, $resource, $clientdata, $httpclient); return $token->get_token(); }
/** * Automatically construct an instance of the API class for a given user. * * NOTE: Useful for one-offs, not efficient for bulk operations. * * @param int $userid The Moodle user ID to construct the API for. * @return \local_o365\rest\o365api An instance of the requested API class with dependencies met for a given user. */ public static function instance_for_user($userid) { $httpclient = new \local_o365\httpclient(); $clientdata = \local_o365\oauth2\clientdata::instance_from_oidc(); $resource = static::get_resource(); $token = \local_o365\oauth2\token::instance($userid, $resource, $clientdata, $httpclient); if (!empty($token)) { return new static($token, $httpclient); } else { throw new \moodle_exception('erroro365apinotoken', 'local_o365'); } }
/** * Get a Unified API instance. * * @param string $caller The calling function, used for logging. * @return \local_o365\rest\unified A Unified API instance. */ public static function get_unified_api($caller = 'get_unified_api') { $clientdata = \local_o365\oauth2\clientdata::instance_from_oidc(); $httpclient = new \local_o365\httpclient(); $resource = \local_o365\rest\unified::get_resource(); $token = \local_o365\oauth2\systemtoken::instance(null, $resource, $clientdata, $httpclient); if (!empty($token)) { return new \local_o365\rest\unified($token, $httpclient); } else { $msg = 'Couldn\'t construct unified api client because we didn\'t have a system API user token.'; $caller = '\\local_o365\\feature\\usergroups\\observers::' . $caller; \local_o365\utils::debug($msg, $caller); return false; } }
/** * Construct an API client. * * @return \local_o365\rest\o365api|bool A constructed user API client (unified or legacy), or false if error. */ public function get_api() { $unifiedconfigured = \local_o365\rest\unified::is_configured(); if ($unifiedconfigured === true) { $resource = \local_o365\rest\unified::get_resource(); } else { $resource = \local_o365\rest\azuread::get_resource(); } $clientdata = \local_o365\oauth2\clientdata::instance_from_oidc(); $httpclient = new \local_o365\httpclient(); $token = \local_o365\oauth2\systemtoken::instance(null, $resource, $clientdata, $httpclient); if (empty($token)) { throw new \Exception('No token available for system user. Please run local_o365 health check.'); } if ($unifiedconfigured === true) { $apiclient = new \local_o365\rest\unified($token, $httpclient); } else { $apiclient = new \local_o365\rest\azuread($token, $httpclient); } return $apiclient; }
/** * Construct a sharepoint API client using the system API user. * * @return \local_o365\rest\sharepoint|bool A constructed sharepoint API client, or false if error. */ public static function construct_sharepoint_api_with_system_user() { try { $spresource = \local_o365\rest\sharepoint::get_resource(); if (!empty($spresource)) { $httpclient = new \local_o365\httpclient(); $clientdata = \local_o365\oauth2\clientdata::instance_from_oidc(); $sptoken = \local_o365\oauth2\systemtoken::instance(null, $spresource, $clientdata, $httpclient); if (!empty($sptoken)) { $sharepoint = new \local_o365\rest\sharepoint($sptoken, $httpclient); return $sharepoint; } } } catch (\Exception $e) { \local_o365\utils::debug($e->getMessage(), get_called_class()); } return false; }
public function __construct(\local_o365\oauth2\clientdata $clientdata = null, \local_o365\httpclient $httpclient = null) { $this->clientdata = !empty($clientdata) ? $clientdata : \local_o365\oauth2\clientdata::instance_from_oidc(); $this->httpclient = !empty($httpclient) ? $httpclient : new \local_o365\httpclient(); }
/** * Get the Azure AD UPN of a connected Moodle user. * * @param \stdClass $user The Moodle user. * @return string|bool The user's Azure AD UPN, or false if failure. */ public static function get_muser_upn($user) { global $DB; $now = time(); if (is_numeric($user)) { $user = $DB->get_record('user', ['id' => $user]); if (empty($user)) { \local_o365\utils::debug('User not found', 'rest\\azuread\\get_muser_upn', $user); return false; } } // Get user UPN. $userobjectdata = $DB->get_record('local_o365_objects', ['type' => 'user', 'moodleid' => $user->id]); if (!empty($userobjectdata)) { return $userobjectdata->o365name; } else { // Get user data. $authoidcuserdata = $DB->get_record('auth_oidc_token', ['username' => $user->username]); if (empty($authoidcuserdata)) { // No data for the user in the OIDC token table. Can't proceed. \local_o365\utils::debug('No oidc token found for user.', 'rest\\azuread\\get_muser_upn', $user->username); return false; } $httpclient = new \local_o365\httpclient(); try { $clientdata = \local_o365\oauth2\clientdata::instance_from_oidc(); } catch (\Exception $e) { \local_o365\utils::debug($e->getMessage()); return false; } $resource = static::get_resource(); $token = \local_o365\oauth2\systemtoken::instance(null, $resource, $clientdata, $httpclient); $aadapiclient = new \local_o365\rest\azuread($token, $httpclient); $aaduserdata = $aadapiclient->get_user($authoidcuserdata->oidcuniqid); $userobjectdata = (object) ['type' => 'user', 'subtype' => '', 'objectid' => $aaduserdata['objectId'], 'o365name' => $aaduserdata['userPrincipalName'], 'moodleid' => $user->id, 'timecreated' => $now, 'timemodified' => $now]; $userobjectdata->id = $DB->insert_record('local_o365_objects', $userobjectdata); return $userobjectdata->o365name; } }
/** * Gets the instance of the correct api class. Use this method to get an instance of the api class. * * @return \local_onenote\api\base An implementation of the OneNote API. */ public static function getinstance() { global $USER, $SESSION, $CFG; $msaccountclass = '\\local_onenote\\api\\msaccount'; $o365class = '\\local_onenote\\api\\o365'; $iso365user = \local_o365\utils::is_o365_connected($USER->id) === true && class_exists('\\local_o365\\rest\\onenote') ? true : false; if ($iso365user === true) { require_once $CFG->dirroot . '/local/msaccount/msaccount_client.php'; $sesskey = 'msaccount_client-' . md5(\msaccount_client::SCOPE); $disableo365onenote = get_user_preferences('local_o365_disableo365onenote', 0); $iso365user = !empty($SESSION->{$sesskey}) || !empty($disableo365onenote) ? false : $iso365user; if ($iso365user === true) { try { $httpclient = new \local_o365\httpclient(); $clientdata = \local_o365\oauth2\clientdata::instance_from_oidc(); $onenoteresource = \local_o365\rest\onenote::get_resource(); $token = \local_o365\oauth2\token::instance($USER->id, $onenoteresource, $clientdata, $httpclient); if (empty($token)) { $iso365user = false; } } catch (\Exception $e) { $iso365user = false; } } $class = $iso365user === true ? $o365class : $msaccountclass; } else { $class = $msaccountclass; } if (empty(self::$instance)) { self::$instance = new $class(); } return self::$instance; }
/** * Sync all user events for a given user with Outlook. * * @param int $userid The ID of the user to sync. * @param int $timecreated The time the task was created. */ protected function sync_userevents($userid, $timecreated) { global $DB; $timestart = time(); // Check the last time user events for this user were synced. // Using a direct query here so we don't run into static cache issues. $lastusersync = $DB->get_record('config_plugins', ['plugin' => 'local_o365', 'name' => 'cal_user_lastsync']); if (!empty($lastusersync)) { $lastusersync = unserialize($lastusersync->value); if (is_array($lastusersync) && isset($lastusersync[$userid]) && (int) $lastusersync[$userid] > $timecreated) { // User events for this user 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); $usertoken = $calsync->get_user_token($userid); if (empty($usertoken)) { // No token, can't sync. \local_o365\utils::debug('Could not get user token for calendar sync.'); return false; } $subscription = $DB->get_record('local_o365_calsub', ['user_id' => $userid, 'caltype' => 'user']); $sql = 'SELECT ev.id AS eventid, ev.name AS eventname, ev.description AS eventdescription, ev.timestart AS eventtimestart, ev.timeduration AS eventtimeduration, idmap.outlookeventid, idmap.origin AS idmaporigin FROM {event} ev LEFT JOIN {local_o365_calidmap} idmap ON ev.id = idmap.eventid AND idmap.userid = ev.userid WHERE ev.courseid = 0 AND ev.groupid = 0 AND ev.userid = ?'; $events = $DB->get_recordset_sql($sql, [$userid]); foreach ($events as $event) { mtrace('Syncing user event #' . $event->eventid); if (!empty($subscription)) { if (empty($event->outlookeventid)) { // Event not synced, if outward subscription exists sync to o365. if ($subscription->syncbehav === 'out' || $subscription->syncbehav === 'both') { mtrace('Creating event in Outlook.'); $subject = $event->eventname; $body = $event->eventdescription; $evstart = $event->eventtimestart; $evend = $event->eventtimestart + $event->eventtimeduration; $calid = !empty($subscription->o365calid) ? $subscription->o365calid : null; if (isset($subscription->isprimary) && $subscription->isprimary == 1) { $calid = null; } $calsync->create_event_raw($userid, $event->eventid, $subject, $body, $evstart, $evend, [], [], $calid); } else { mtrace('Not creating event in Outlook. (Sync settings are inward-only.)'); } } else { // Event synced. If event was created in Moodle and subscription is inward-only, delete o365 event. if ($event->idmaporigin === 'moodle' && $subscription->syncbehav === 'in') { mtrace('Removing event from Outlook (Created in Moodle, sync settings are inward-only.)'); $calsync->delete_event_raw($userid, $event->outlookeventid); } else { mtrace('Event already synced.'); } } } else { // No subscription exists. Delete relevant events. if (!empty($event->outlookeventid)) { if ($event->idmaporigin === 'moodle') { mtrace('Removing event from Outlook.'); // Event was created in Moodle, delete o365 event. $calsync->delete_event_raw($userid, $event->outlookeventid); } else { mtrace('Not removing event from Outlook (It was created there.)'); } } else { mtrace('Did not have an outlookeventid. Event not synced?'); } } } $events->close(); if (!empty($lastusersync) && is_array($lastusersync)) { $lastusersync[$userid] = $timestart; } else { $lastusersync = [$userid => $timestart]; } $lastusersync = serialize($lastusersync); set_config('cal_user_lastsync', $lastusersync, 'local_o365'); return true; }
/** * Do the job. */ public function execute() { global $DB; $configsetting = get_config('local_o365', 'creategroups'); if (empty($configsetting)) { mtrace('Groups not enabled, skipping...'); return true; } $now = time(); $httpclient = new \local_o365\httpclient(); $clientdata = \local_o365\oauth2\clientdata::instance_from_oidc(); $unifiedresource = \local_o365\rest\unified::get_resource(); $unifiedtoken = \local_o365\oauth2\systemtoken::instance(null, $unifiedresource, $clientdata, $httpclient); if (empty($unifiedtoken)) { mtrace('Could not get unified API token.'); return true; } $unifiedclient = new \local_o365\rest\unified($unifiedtoken, $httpclient); $aadresource = \local_o365\rest\azuread::get_resource(); $aadtoken = \local_o365\oauth2\systemtoken::instance(null, $aadresource, $clientdata, $httpclient); if (empty($aadtoken)) { mtrace('Could not get Azure AD token.'); return true; } $aadclient = new \local_o365\rest\azuread($aadtoken, $httpclient); $siterec = $DB->get_record('course', ['id' => SITEID]); $siteshortname = strtolower(preg_replace('/[^a-z0-9]+/iu', '', $siterec->shortname)); $sql = 'SELECT crs.* FROM {course} crs LEFT JOIN {local_o365_objects} obj ON obj.type = ? AND obj.subtype = ? AND obj.moodleid = crs.id WHERE obj.id IS NULL AND crs.id != ? LIMIT 0, 5'; $params = ['group', 'course', SITEID]; $courses = $DB->get_recordset_sql($sql, $params); foreach ($courses as $course) { // Create group. $groupname = $siterec->shortname . ': ' . $course->fullname; $groupshortname = $siteshortname . '_' . $course->shortname; $response = $unifiedclient->create_group($groupname, $groupshortname); if (empty($response) || !is_array($response) || empty($response['objectId'])) { mtrace('Could not create group for course #' . $course->id); var_dump($response); continue; } mtrace('Created group ' . $response['objectId'] . ' for course #' . $course->id); $objectrec = ['type' => 'group', 'subtype' => 'course', 'objectid' => $response['objectId'], 'moodleid' => $course->id, 'o365name' => $groupname, 'timecreated' => $now, 'timemodified' => $now]; $objectrec['id'] = $DB->insert_record('local_o365_objects', (object) $objectrec); mtrace('Recorded group object (' . $objectrec['objectid'] . ') into object table with record id ' . $objectrec['id']); // It takes a little while for the group object to register. mtrace('Waiting 10 seconds for group to register...'); sleep(10); // Add enrolled users to group. mtrace('Adding users to group (' . $objectrec['objectid'] . ')'); $coursecontext = \context_course::instance($course->id); list($esql, $params) = get_enrolled_sql($coursecontext); $sql = "SELECT u.*,\n tok.oidcuniqid as userobjectid\n FROM {user} u\n JOIN ({$esql}) je ON je.id = u.id\n JOIN {auth_oidc_token} tok ON tok.username = u.username AND tok.resource = :tokresource\n WHERE u.deleted = 0"; $params['tokresource'] = 'https://graph.windows.net'; $enrolled = $DB->get_recordset_sql($sql, $params); foreach ($enrolled as $user) { $response = $aadclient->add_member_to_group($objectrec['objectid'], $user->userobjectid); if ($response === true) { mtrace('Added user #' . $user->id . ' (' . $user->userobjectid . ')'); } else { mtrace('Could not add user #' . $user->id . ' (' . $user->userobjectid . ')'); mtrace('Received: ' . $response); } } $enrolled->close(); } $courses->close(); }
/** * Attempt to fix application permissions. */ public function mode_fixappperms() { $data = new \stdClass(); $success = false; $resource = \local_o365\rest\azuread::get_resource(); $clientdata = \local_o365\oauth2\clientdata::instance_from_oidc(); $httpclient = new \local_o365\httpclient(); $token = \local_o365\oauth2\systemtoken::instance(null, $resource, $clientdata, $httpclient); if (empty($token)) { throw new \moodle_exception('errorchecksystemapiuser', 'local_o365'); } $apiclient = new \local_o365\rest\azuread($token, $httpclient); $success = $apiclient->push_permissions(); $data->success = $success; if ($success === true) { set_config('detectperms', 1, 'local_o365'); } echo $this->ajax_response($data, $success); }
/** * Handle user_enrolment_deleted event * * Tasks * - remove user from course usergroups. * * @param \core\event\user_enrolment_deleted $event The triggered event. * @return bool Success/Failure. */ public static function handle_user_enrolment_deleted(\core\event\user_enrolment_deleted $event) { global $DB; $userid = $event->relateduserid; $courseid = $event->courseid; if (empty($userid) || empty($courseid)) { return true; } // Remove user from course usergroup. $configsetting = get_config('local_o365', 'creategroups'); if (!empty($configsetting)) { $httpclient = new \local_o365\httpclient(); $clientdata = \local_o365\oauth2\clientdata::instance_from_oidc(); $aadresource = \local_o365\rest\azuread::get_resource(); $aadtoken = \local_o365\oauth2\systemtoken::instance(null, $aadresource, $clientdata, $httpclient); if (!empty($aadtoken)) { $aadclient = new \local_o365\rest\azuread($aadtoken, $httpclient); $aadclient->remove_user_from_course_group($courseid, $userid); } } return true; }
/** * Gets the instance of the correct api class. Use this method to get an instance of the api class. * * @return \local_onenote\api\base An implementation of the OneNote API. */ public static function getinstance() { global $USER, $SESSION, $CFG; $msaccountclass = '\\local_onenote\\api\\msaccount'; $o365class = '\\local_onenote\\api\\o365'; $class = ''; $iso365user = \local_o365\utils::is_o365_connected($USER->id) === true && class_exists('\\local_o365\\rest\\onenote') ? true : false; if ($iso365user === true) { $sesskey = class_exists('\\local_msaccount\\client') ? 'msaccount_client-' . md5(\local_msaccount\client::SCOPE) : null; $disableo365onenote = get_user_preferences('local_o365_disableo365onenote', 0); // If the user is logged in to msaccount OneNote, or has o365 OneNote disabled. $iso365user = !empty($sesskey) && !empty($SESSION->{$sesskey}) || !empty($disableo365onenote) ? false : $iso365user; if ($iso365user === true) { try { $httpclient = new \local_o365\httpclient(); $clientdata = \local_o365\oauth2\clientdata::instance_from_oidc(); $onenoteresource = \local_o365\rest\onenote::get_resource(); $token = \local_o365\oauth2\token::instance($USER->id, $onenoteresource, $clientdata, $httpclient); if (empty($token)) { $iso365user = false; } } catch (\Exception $e) { $iso365user = false; } } if ($iso365user === true) { $class = $o365class; } else { $class = class_exists('\\local_msaccount\\client') ? $msaccountclass : null; } } else { $class = class_exists('\\local_msaccount\\client') ? $msaccountclass : null; } if (empty($class)) { throw new \moodle_exception('error_noapiavailable', 'local_onenote'); } if (empty(self::$instance)) { self::$instance = new $class(); } return self::$instance; }
/** * Looks for links pointing to Office 365 Video content and processes them. * * @param $link HTML tag containing a link * @return string HTML content after processing. */ function filter_oembed_o365videocallback($link) { if (empty($link[3])) { return $link[0]; } $link[3] = preg_replace("/&/", "&", $link[3]); $values = array(); parse_str($link[3], $values); if (empty($values['chid']) || empty($values['vid'])) { return $link[0]; } if (!\local_o365\rest\sharepoint::is_configured()) { \local_o365\utils::debug('filter_oembed share point is not configured', 'filter_oembed_o365videocallback'); return $link[0]; } try { $spresource = \local_o365\rest\sharepoint::get_resource(); if (!empty($spresource)) { $httpclient = new \local_o365\httpclient(); $clientdata = \local_o365\oauth2\clientdata::instance_from_oidc(); $sptoken = \local_o365\oauth2\systemtoken::instance(null, $spresource, $clientdata, $httpclient); if (!empty($sptoken)) { $sharepoint = new \local_o365\rest\sharepoint($sptoken, $httpclient); // Retrieve api url for video service. $url = $sharepoint->videoservice_discover(); if (!empty($url)) { $sharepoint->override_resource($url); $width = 640; if (!empty($values['width'])) { $width = $values['width']; } $height = 360; if (!empty($values['height'])) { $height = $values['height']; } // Retrieve embed code. return $sharepoint->get_video_embed_code($values['chid'], $values['vid'], $width, $height); } } } } catch (\Exception $e) { \local_o365\utils::debug('filter_oembed share point execption: ' . $e->getMessage(), 'filter_oembed_o365videocallback'); } return $link[0]; }
/** * Do the job. */ public function execute() { global $DB; // API Setup. try { $spresource = \local_o365\rest\sharepoint::get_resource(); if (empty($spresource)) { throw new \moodle_exception('erroracplocalo365notconfig', 'local_o365'); } $httpclient = new \local_o365\httpclient(); $clientdata = \local_o365\oauth2\clientdata::instance_from_oidc(); $sptoken = \local_o365\oauth2\systemtoken::instance(null, $spresource, $clientdata, $httpclient); if (empty($sptoken)) { throw new \moodle_exception('erroracpnosptoken', 'local_o365'); } $sharepoint = new \local_o365\rest\sharepoint($sptoken, $httpclient); } catch (\Exception $e) { $errmsg = 'ERROR: Problem initializing SharePoint API. Reason: ' . $e->getMessage(); mtrace($errmsg); \local_o365\utils::debug($errmsg, 'local_o365\\task\\sharepointinit::execute'); set_config('sharepoint_initialized', 'error', 'local_o365'); return false; } // Create parent site(s). try { mtrace('Creating parent site for Moodle...'); $moodlesiteuri = $sharepoint->get_moodle_parent_site_uri(); $sitelevels = explode('/', $moodlesiteuri); $currentparentsite = ''; foreach ($sitelevels as $partialurl) { $sharepoint->set_site($currentparentsite); if ($sharepoint->site_exists($currentparentsite . '/' . $partialurl) === false) { $moodlesitename = get_string('acp_parentsite_name', 'local_o365'); $moodlesitedesc = get_string('acp_parentsite_desc', 'local_o365'); $frontpagerec = $DB->get_record('course', ['id' => SITEID], 'id,shortname'); if (!empty($frontpagerec) && !empty($frontpagerec->shortname)) { $moodlesitename = $frontpagerec->shortname; } mtrace('Setting parent site to "' . $currentparentsite . '", creating subsite "' . $partialurl . '"'); $result = $sharepoint->create_site($moodlesitename, $partialurl, $moodlesitedesc); $currentparentsite .= '/' . $partialurl; mtrace('Created parent site "' . $currentparentsite . '"'); } else { $currentparentsite .= '/' . $partialurl; mtrace('Parent site "' . $currentparentsite . '" already exists.'); } } mtrace('Finished creating Moodle parent site.'); } catch (\Exception $e) { $errmsg = 'ERROR: Problem creating parent site. Reason: ' . $e->getMessage(); mtrace($errmsg); \local_o365\utils::debug($errmsg, 'local_o365\\task\\sharepointinit::execute'); set_config('sharepoint_initialized', 'error', 'local_o365'); return false; } // Create course sites. mtrace('Creating course subsites in "' . $moodlesiteuri . '"'); $sharepoint->set_site($moodlesiteuri); $courses = $DB->get_recordset('course'); $successes = []; $failures = []; foreach ($courses as $course) { if ($course->id == SITEID) { continue; } try { $sharepoint->create_course_site($course); $successes[] = $course->id; mtrace('Created course subsite for course ' . $course->id); } catch (\Exception $e) { mtrace('Encountered error creating course subsite for course ' . $course->id); $failures[$course->id] = $e->getMessage(); } } if (!empty($failures)) { $errmsg = 'ERROR: Encountered problems creating course sites.'; mtrace($errmsg . ' See logs.'); \local_o365\utils::debug($errmsg, 'local_o365\\task\\sharepointinit::execute', $failures); set_config('sharepoint_initialized', 'error', 'local_o365'); } else { set_config('sharepoint_initialized', '1', 'local_o365'); mtrace('SharePoint successfully initialized.'); return true; } }
/** * Manage calendar syncing. */ public function mode_calendar() { global $DB, $USER, $OUTPUT, $PAGE; if (empty($this->o365connected)) { throw new \moodle_exception('ucp_notconnected', 'local_o365'); } $outlookresource = \local_o365\rest\calendar::get_resource(); if (empty($outlookresource)) { throw new \Exception('Not configured'); } $httpclient = new \local_o365\httpclient(); $clientdata = \local_o365\oauth2\clientdata::instance_from_oidc(); $token = \local_o365\oauth2\token::instance($USER->id, $outlookresource, $clientdata, $httpclient); $calsync = new \local_o365\feature\calsync\main(); $o365calendars = $calsync->get_calendars(); $customdata = ['o365calendars' => [], 'usercourses' => enrol_get_my_courses(['id', 'fullname']), 'cancreatesiteevents' => false, 'cancreatecourseevents' => []]; foreach ($o365calendars as $o365calendar) { $customdata['o365calendars'][] = ['id' => $o365calendar['Id'], 'name' => $o365calendar['Name']]; } $primarycalid = $customdata['o365calendars'][0]['id']; // Determine permissions to create events. Determines whether user can sync from o365 to Moodle. $customdata['cancreatesiteevents'] = has_capability('moodle/calendar:manageentries', \context_course::instance(SITEID)); foreach ($customdata['usercourses'] as $courseid => $course) { $cancreateincourse = has_capability('moodle/calendar:manageentries', \context_course::instance($courseid)); $customdata['cancreatecourseevents'][$courseid] = $cancreateincourse; } $mform = new \local_o365\feature\calsync\form\subscriptions('?action=calendar', $customdata); if ($mform->is_cancelled()) { redirect(new \moodle_url('/local/o365/ucp.php')); } else { if ($fromform = $mform->get_data()) { \local_o365\feature\calsync\form\subscriptions::update_subscriptions($fromform, $primarycalid, $customdata['cancreatesiteevents'], $customdata['cancreatecourseevents']); redirect(new \moodle_url('/local/o365/ucp.php')); } else { $PAGE->requires->jquery(); $defaultdata = []; $existingsubsrs = $DB->get_recordset('local_o365_calsub', ['user_id' => $USER->id]); foreach ($existingsubsrs as $existingsubrec) { if ($existingsubrec->caltype === 'site') { $defaultdata['sitecal']['checked'] = '1'; $defaultdata['sitecal']['syncwith'] = $existingsubrec->o365calid; $defaultdata['sitecal']['syncbehav'] = $existingsubrec->syncbehav; } else { if ($existingsubrec->caltype === 'user') { $defaultdata['usercal']['checked'] = '1'; $defaultdata['usercal']['syncwith'] = $existingsubrec->o365calid; $defaultdata['usercal']['syncbehav'] = $existingsubrec->syncbehav; } else { if ($existingsubrec->caltype === 'course') { $defaultdata['coursecal'][$existingsubrec->caltypeid]['checked'] = '1'; $defaultdata['coursecal'][$existingsubrec->caltypeid]['syncwith'] = $existingsubrec->o365calid; $defaultdata['coursecal'][$existingsubrec->caltypeid]['syncbehav'] = $existingsubrec->syncbehav; } } } } $existingsubsrs->close(); $mform->set_data($defaultdata); echo $OUTPUT->header(); $mform->display(); echo $OUTPUT->footer(); } } }