From ca24f21f5f287dd8203002fb38998c5b2a734281 Mon Sep 17 00:00:00 2001 From: Patryk Mroczko Date: Thu, 24 Oct 2024 11:16:49 +0200 Subject: [PATCH] Fix Moodle plugin CI errors --- .gitlab-ci.yml | 86 +++++++ .travis.yml | 41 ---- classes/adminsetting/tabs.php | 4 +- .../usersynccreationrestriction.php | 4 +- classes/adminsetting/usersyncoptions.php | 10 +- classes/adminsetting/verifysetup.php | 8 +- classes/event/api_call_failed.php | 2 - classes/event/calendar_subscribed.php | 2 - classes/event/calendar_unsubscribed.php | 2 - .../feature/calsync/form/element/calendar.php | 16 +- .../feature/calsync/form/subscriptions.php | 20 +- classes/feature/calsync/main.php | 33 +-- classes/feature/calsync/observers.php | 4 +- .../calsync/task/importfromoutlook.php | 6 +- .../feature/calsync/task/syncoldevents.php | 9 +- classes/feature/cohortsync/main.php | 32 +-- classes/feature/courserequest/main.php | 27 ++- classes/feature/coursesync/main.php | 64 ++--- classes/feature/coursesync/observers.php | 3 +- classes/feature/coursesync/utils.php | 43 ++-- classes/feature/sds/task/sync.php | 21 +- classes/feature/sds/utils.php | 6 +- classes/feature/userconnections/filtering.php | 10 +- classes/feature/usersync/main.php | 28 ++- classes/form/cohortsync.php | 2 +- classes/form/courserequestform.php | 12 +- classes/form/teamstabconfiguration.php | 6 +- classes/healthcheck/healthcheckinterface.php | 14 +- classes/healthcheck/ratelimit.php | 2 - classes/httpclient.php | 57 +++-- classes/httpclientinterface.php | 64 +++-- classes/oauth2/apptoken.php | 6 +- classes/oauth2/clientdata.php | 2 +- classes/oauth2/token.php | 12 +- classes/obj/o365user.php | 4 - classes/observers.php | 43 ++-- classes/page/acp.php | 30 +-- classes/page/ajax.php | 8 +- classes/page/base.php | 2 - classes/privacy/provider.php | 48 ++-- classes/rest/o365api.php | 4 +- classes/rest/unified.php | 223 +++++++++--------- classes/task/cohortsync.php | 8 +- classes/task/coursemembershipsync.php | 4 +- classes/task/coursesync.php | 5 +- classes/task/groupmembershipsync.php | 2 +- classes/task/notifysecretexpiry.php | 11 +- classes/task/processcourserequestapproval.php | 7 +- classes/task/processmatchqueue.php | 4 +- classes/task/updatecourserequeststatus.php | 2 - classes/task/usersync.php | 13 +- classes/tests/mockhttpclient.php | 4 +- classes/utils.php | 33 +-- .../webservices/create_onenoteassignment.php | 21 +- .../webservices/delete_onenoteassignment.php | 11 +- .../webservices/exception/assignnotfound.php | 4 +- .../exception/couldnotsavegrade.php | 4 +- .../exception/invalidassignment.php | 4 +- .../webservices/exception/modulenotfound.php | 4 +- .../webservices/exception/sectionnotfound.php | 4 +- classes/webservices/read_assignments.php | 178 +++++++------- classes/webservices/read_courseusers.php | 18 +- .../webservices/read_onenoteassignment.php | 14 +- classes/webservices/read_teachercourses.php | 12 +- classes/webservices/update_grade.php | 83 +++---- .../webservices/update_onenoteassignment.php | 20 +- classes/webservices/utils.php | 7 +- db/access.php | 2 +- db/caches.php | 2 +- db/services.php | 2 +- db/tasks.php | 14 +- db/upgrade.php | 136 ++++------- export_manifest.php | 2 + lang/cs/local_o365.php | 6 + lang/de/local_o365.php | 6 + lang/en/local_o365.php | 16 +- lang/es/local_o365.php | 6 + lang/fi/local_o365.php | 6 + lang/fr/local_o365.php | 8 +- lang/it/local_o365.php | 6 + lang/ja/local_o365.php | 6 + lang/nl/local_o365.php | 6 + lang/pl/local_o365.php | 6 + lang/pt_br/local_o365.php | 6 + lib.php | 45 +++- sass/styles.scss | 129 ---------- settings.php | 2 +- sso_end.php | 1 + sso_login.php | 1 + sso_start.php | 1 + styles.css | 55 +++-- teams_tab.php | 5 +- teams_tab_configuration.php | 1 + teams_tab_redirect.php | 1 + tests/coursesyncutils_test.php | 54 +++-- tests/observers_test.php | 26 +- tests/privacy_provider_test.php | 82 ++++--- tests/token_test.php | 15 +- tests/usersync_test.php | 109 +++++---- tests/webservices_onenoteassignment_test.php | 163 +++++++------ tests/webservices_utils_test.php | 56 +++-- 101 files changed, 1292 insertions(+), 1187 deletions(-) create mode 100644 .gitlab-ci.yml delete mode 100644 .travis.yml delete mode 100644 sass/styles.scss diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 000000000..8ed181988 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,86 @@ +services: + - name: selenium/standalone-chrome:3 + alias: behat + - name: mysql:8.0 + alias: db + command: + - '--character-set-server=utf8mb4' + - '--collation-server=utf8mb4_unicode_ci' + - '--innodb_file_per_table=On' + - '--wait-timeout=28800' + - '--skip-log-bin' + +cache: + paths: + - .cache + +variables: + DEBIAN_FRONTEND: 'noninteractive' + COMPOSER_ALLOW_SUPERUSER: 1 + COMPOSER_CACHE_DIR: "$CI_PROJECT_DIR/.cache/composer" + NPM_CONFIG_CACHE: "$CI_PROJECT_DIR/.cache/npm" + CI_BUILD_DIR: '/tmp/plugin' + MOODLE_BRANCH: 'MOODLE_405_STABLE' + MOODLE_BEHAT_WWWROOT: 'http://localhost:8000' + MOODLE_BEHAT_WDHOST: 'http://behat:4444/wd/hub' + MOODLE_START_BEHAT_SERVERS: 'no' + MYSQL_ALLOW_EMPTY_PASSWORD: 'yes' + DB: 'mysqli' + +stages: + - moodle-plugin-ci + +.setupandruncheck: &setupandruncheck + stage: moodle-plugin-ci + before_script: + - mkdir -pv "$CI_BUILD_DIR" + - cp -ru "$CI_PROJECT_DIR/"* "$CI_BUILD_DIR" + - mkdir -p /usr/share/man/man1 /usr/share/man/man3 /usr/share/man/man7 + - apt-get -qq update + - apt-get -yqq install --no-install-suggests default-jre-headless default-mysql-client + - 'curl -sS https://raw.githubusercontent.com/creationix/nvm/v0.39.3/install.sh | bash' + - . ~/.bashrc + - nvm install --default --latest-npm lts/gallium + - 'curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer' + - composer create-project -n --no-dev --no-progress --no-ansi moodlehq/moodle-plugin-ci /opt/mci ^4 + - export PATH="/opt/mci/bin:/opt/mci/vendor/bin:$PATH" + - moodle-plugin-ci add-plugin --clone https://github.com/microsoft/moodle-auth_oidc.git --branch $MOODLE_BRANCH + - moodle-plugin-ci install --db-host db --db-name moodle + - '{ php -S 0.0.0.0:8000 -t "$CI_PROJECT_DIR/moodle" >/dev/null 2>&1 & }' + - TXT_RED="\e[31m" + + script: + - errors=() + - moodle-plugin-ci phplint || errors+=("phplint") + - moodle-plugin-ci phpmd || errors+=("phpmd") + - moodle-plugin-ci codechecker --max-warnings 0 || errors+=("codechecker") + - moodle-plugin-ci phpdoc --max-warnings 0 || errors+=("phpdoc") + - moodle-plugin-ci validate || errors+=("validate") + - moodle-plugin-ci savepoints || errors+=("savepoints") + - moodle-plugin-ci mustache || errors+=("mustache") + - moodle-plugin-ci grunt --max-lint-warnings 0 || errors+=("grunt") + - moodle-plugin-ci phpunit || errors+=("phpunit") + - moodle-plugin-ci behat --auto-rerun 0 --profile chrome || errors+=("behat") + - |- + if [ ${#errors[@]} -ne 0 ]; then + echo -e "${TXT_RED}Check errors: ${errors[@]}"; + exit 1; + fi + +php81: + tags: + - docker + image: moodlehq/moodle-php-apache:8.1 + <<: *setupandruncheck + +php82: + tags: + - docker + image: moodlehq/moodle-php-apache:8.2 + <<: *setupandruncheck + +php83: + tags: + - docker + image: moodlehq/moodle-php-apache:8.3 + <<: *setupandruncheck diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index f7b979416..000000000 --- a/.travis.yml +++ /dev/null @@ -1,41 +0,0 @@ -language: php - -sudo: false - -cache: - directories: - - $HOME/.composer/cache - -php: - - 5.6 - - 7.0 - -env: - global: - - MOODLE_BRANCH=MOODLE_30_STABLE - - matrix: - - DB=pgsql - - DB=mysqli - -before_install: - - phpenv config-rm xdebug.ini - - cd ../.. - - composer selfupdate - - composer create-project -n --no-dev moodlerooms/moodle-plugin-ci ci ^1 - - export PATH="$(cd ci/bin; pwd):$(cd ci/vendor/bin; pwd):$PATH" - -install: - - moodle-plugin-ci install - -script: - - moodle-plugin-ci phplint - - moodle-plugin-ci phpcpd - - moodle-plugin-ci phpmd - - moodle-plugin-ci codechecker - - moodle-plugin-ci csslint - - moodle-plugin-ci shifter - - moodle-plugin-ci jshint - - moodle-plugin-ci validate - - moodle-plugin-ci phpunit - - moodle-plugin-ci behat \ No newline at end of file diff --git a/classes/adminsetting/tabs.php b/classes/adminsetting/tabs.php index e2f72f69c..d4d6dabf9 100644 --- a/classes/adminsetting/tabs.php +++ b/classes/adminsetting/tabs.php @@ -30,8 +30,6 @@ use moodle_url; use tabobject; -defined('MOODLE_INTERNAL') || die(); - /** * A tab in the plugin configuration page. */ @@ -136,7 +134,7 @@ public function write_setting($data) { * @param moodle_url|null $url An explicit URL to use instead of settings page section. * @uses $CFG */ - public function addtab($id, $name, moodle_url $url = null) { + public function addtab($id, $name, ?moodle_url $url = null) { if (empty($url)) { $urlparams = [ 'section' => $this->section, diff --git a/classes/adminsetting/usersynccreationrestriction.php b/classes/adminsetting/usersynccreationrestriction.php index 27d3c591b..934738ef4 100644 --- a/classes/adminsetting/usersynccreationrestriction.php +++ b/classes/adminsetting/usersynccreationrestriction.php @@ -72,8 +72,8 @@ public function __construct($name, $visiblename, $description, $defaultsetting) ]; $order = 0; while ($order++ < 15) { - $this->remotefields['extensionAttribute' . $order] = get_string('settings_fieldmap_field_extensionattribute', 'auth_oidc', - $order); + $this->remotefields['extensionAttribute' . $order] = get_string('settings_fieldmap_field_extensionattribute', + 'auth_oidc', $order); } return parent::__construct($name, $visiblename, $description, $defaultsetting); diff --git a/classes/adminsetting/usersyncoptions.php b/classes/adminsetting/usersyncoptions.php index 9ba63fc90..1b1fb21a7 100644 --- a/classes/adminsetting/usersyncoptions.php +++ b/classes/adminsetting/usersyncoptions.php @@ -83,18 +83,18 @@ public function __construct($name, $visiblename, $description) { */ public function output_html($data, $query = '') { global $OUTPUT; - if (!$this->load_choices() or empty($this->choices)) { + if (!$this->load_choices() || empty($this->choices)) { return ''; } $default = $this->get_defaultsetting(); if (is_null($default)) { - $default = array(); + $default = []; } if (is_null($data)) { - $data = array(); + $data = []; } - $options = array(); - $defaults = array(); + $options = []; + $defaults = []; foreach ($this->choices as $key => $description) { if (!empty($data[$key])) { $checked = 'checked="checked"'; diff --git a/classes/adminsetting/verifysetup.php b/classes/adminsetting/verifysetup.php index d1647c52a..f97c35b4f 100644 --- a/classes/adminsetting/verifysetup.php +++ b/classes/adminsetting/verifysetup.php @@ -87,14 +87,10 @@ public function output_html($data, $query = '') { if (\local_o365\adminsetting\detectoidc::setup_step_complete() === true) { $existingsetting = $this->config_read($this->name); if (!empty($existingsetting)) { - $messageattrs = [ - 'class' => 'permmessage' - ]; + $messageattrs = ['class' => 'permmessage']; $message = \html_writer::tag('span', get_string('settings_detectperms_valid', 'local_o365'), $messageattrs); } else { - $messageattrs = [ - 'class' => 'permmessage' - ]; + $messageattrs = ['class' => 'permmessage']; $message = \html_writer::tag('span', get_string('settings_detectperms_invalid', 'local_o365'), $messageattrs); } } else { diff --git a/classes/event/api_call_failed.php b/classes/event/api_call_failed.php index e10096683..d26a60177 100644 --- a/classes/event/api_call_failed.php +++ b/classes/event/api_call_failed.php @@ -25,8 +25,6 @@ namespace local_o365\event; -defined('MOODLE_INTERNAL') || die(); - /** * Event fired whenever a user subscribes to a calendar. */ diff --git a/classes/event/calendar_subscribed.php b/classes/event/calendar_subscribed.php index 709ccaf88..7abb9d653 100644 --- a/classes/event/calendar_subscribed.php +++ b/classes/event/calendar_subscribed.php @@ -25,8 +25,6 @@ namespace local_o365\event; -defined('MOODLE_INTERNAL') || die(); - /** * Event fired whenever a user subscribes to a calendar. */ diff --git a/classes/event/calendar_unsubscribed.php b/classes/event/calendar_unsubscribed.php index 66b932b02..d44183225 100644 --- a/classes/event/calendar_unsubscribed.php +++ b/classes/event/calendar_unsubscribed.php @@ -25,8 +25,6 @@ namespace local_o365\event; -defined('MOODLE_INTERNAL') || die(); - /** * Event fired whenever a user unsubscribes from a calendar. */ diff --git a/classes/feature/calsync/form/element/calendar.php b/classes/feature/calsync/form/element/calendar.php index 747b6a856..dc08c7633 100644 --- a/classes/feature/calsync/form/element/calendar.php +++ b/classes/feature/calsync/form/element/calendar.php @@ -31,6 +31,9 @@ require_once("$CFG->libdir/form/advcheckbox.php"); +// phpcs:disable moodle.NamingConventions.ValidVariableName.VariableNameLowerCase -- Parent class uses uppercase variable names. +// phpcs:disable moodle.NamingConventions.ValidFunctionName.LowercaseMethod -- Parent class uses uppercase method names. + /** * Calendar form element. Provides checkbox to enable/disable calendar and options for sync behavior. */ @@ -50,15 +53,15 @@ class calendar extends \HTML_QuickForm_advcheckbox { /** * Constructor, accessed through __call constructor workaround. * - * @param string $elementName The name of the element. - * @param string $elementLabel The label of the element. + * @param string $elementname The name of the element. + * @param string $elementlabel The label of the element. * @param string $text Text that appears after the checkbox. * @param array $attributes Array of checkbox attributes. * @param array $customdata Array of form custom data. */ - public function calendarconstruct($elementName = null, $elementLabel = null, $text = null, $attributes = null, + public function calendarconstruct($elementname = null, $elementlabel = null, $text = null, $attributes = null, $customdata = []) { - parent::__construct($elementName, $elementLabel, $text, $attributes, null); + parent::__construct($elementname, $elementlabel, $text, $attributes, null); $this->customdata = $customdata; $this->_type = 'advcheckbox'; } @@ -112,7 +115,7 @@ public function setValue($value) { * * @return string html for help button */ - function getHelpButton(){ + public function getHelpButton() { return $this->_helpbutton; } @@ -183,3 +186,6 @@ public function toHtml() { return $html; } } + +// phpcs:enable moodle.NamingConventions.ValidVariableName.VariableNameLowerCase +// phpcs:enable moodle.NamingConventions.ValidFunctionName.LowercaseMethod diff --git a/classes/feature/calsync/form/subscriptions.php b/classes/feature/calsync/form/subscriptions.php index 36b972871..fec28c5ec 100644 --- a/classes/feature/calsync/form/subscriptions.php +++ b/classes/feature/calsync/form/subscriptions.php @@ -112,11 +112,11 @@ public static function update_subscriptions($fromform, $primarycalid, $cancreate $newsetting = [ 'user_id' => $USER->id, 'o365calid' => $sitecalenderid, - 'timecreated' => time() + 'timecreated' => time(), ]; $newsetting['id'] = $DB->insert_record('local_o365_calsettings', (object)$newsetting); } else if (empty($fromform->settingcal) && !empty($usersetting)) { - $DB->delete_records('local_o365_calsettings', array('user_id' => $USER->id)); + $DB->delete_records('local_o365_calsettings', ['user_id' => $USER->id]); } // Determine and organize existing subscriptions. @@ -176,7 +176,7 @@ public static function update_subscriptions($fromform, $primarycalid, $cancreate $eventdata = [ 'objectid' => $currentcaldata[$caltype]['recid'], 'userid' => $USER->id, - 'other' => ['caltype' => $caltype] + 'other' => ['caltype' => $caltype], ]; $event = \local_o365\event\calendar_unsubscribed::create($eventdata); $event->trigger(); @@ -202,13 +202,13 @@ public static function update_subscriptions($fromform, $primarycalid, $cancreate 'o365calid' => $syncwith, 'syncbehav' => $syncbehav, 'isprimary' => ($syncwith == $primarycalid) ? '1' : '0', - 'timecreated' => time() + 'timecreated' => time(), ]; $newsub['id'] = $DB->insert_record('local_o365_calsub', (object)$newsub); $eventdata = [ 'objectid' => $newsub['id'], 'userid' => $USER->id, - 'other' => ['caltype' => $caltype] + 'other' => ['caltype' => $caltype], ]; } else { // Already subscribed, update behavior. @@ -222,7 +222,7 @@ public static function update_subscriptions($fromform, $primarycalid, $cancreate $eventdata = [ 'objectid' => $currentcaldata[$caltype]['recid'], 'userid' => $USER->id, - 'other' => ['caltype' => $caltype] + 'other' => ['caltype' => $caltype], ]; } $event = \local_o365\event\calendar_subscribed::create($eventdata); @@ -241,13 +241,13 @@ public static function update_subscriptions($fromform, $primarycalid, $cancreate } } $todelete = (empty($fromform->settingcal)) ? $existingcoursesubs : array_diff_key($existingcoursesubs, $newcoursesubs); - $toadd = (empty($fromform->settingcal)) ? array() : array_diff_key($newcoursesubs, $existingcoursesubs); + $toadd = (empty($fromform->settingcal)) ? [] : array_diff_key($newcoursesubs, $existingcoursesubs); foreach ($todelete as $courseid => $unused) { $DB->delete_records('local_o365_calsub', ['user_id' => $USER->id, 'caltype' => 'course', 'caltypeid' => $courseid]); $eventdata = [ 'objectid' => $USER->id, 'userid' => $USER->id, - 'other' => ['caltype' => 'course', 'caltypeid' => $courseid] + 'other' => ['caltype' => 'course', 'caltypeid' => $courseid], ]; $event = \local_o365\event\calendar_unsubscribed::create($eventdata); $event->trigger(); @@ -273,7 +273,7 @@ public static function update_subscriptions($fromform, $primarycalid, $cancreate $eventdata = [ 'objectid' => $USER->id, 'userid' => $USER->id, - 'other' => ['caltype' => 'course', 'caltypeid' => $courseid] + 'other' => ['caltype' => 'course', 'caltypeid' => $courseid], ]; $event = \local_o365\event\calendar_subscribed::create($eventdata); $event->trigger(); @@ -297,7 +297,7 @@ public static function update_subscriptions($fromform, $primarycalid, $cancreate $eventdata = [ 'objectid' => $USER->id, 'userid' => $USER->id, - 'other' => ['caltype' => 'course', 'caltypeid' => $courseid] + 'other' => ['caltype' => 'course', 'caltypeid' => $courseid], ]; $event = \local_o365\event\calendar_subscribed::create($eventdata); $event->trigger(); diff --git a/classes/feature/calsync/main.php b/classes/feature/calsync/main.php index de9bc00ea..2dca5ef20 100644 --- a/classes/feature/calsync/main.php +++ b/classes/feature/calsync/main.php @@ -32,8 +32,6 @@ use local_o365\utils; use moodle_exception; -defined('MOODLE_INTERNAL') || die(); - /** * Calendar sync feature. */ @@ -54,7 +52,7 @@ class main { * @param httpclient|null $httpclient * @throws moodle_exception */ - public function __construct(clientdata $clientdata = null, httpclient $httpclient = null) { + public function __construct(?clientdata $clientdata = null, ?httpclient $httpclient = null) { $this->clientdata = (!empty($clientdata)) ? $clientdata : clientdata::instance_from_oidc(); $this->httpclient = (!empty($httpclient)) ? $httpclient : new httpclient(); } @@ -293,7 +291,7 @@ public function create_outlook_event_from_moodle_event($moodleventid) { 'emailAddress' => [ 'name' => $groupobject->o365name, 'address' => $outlookgroupemail, - ] + ], ], 'responseRequested' => false, 'isOrganizer' => true, @@ -313,6 +311,7 @@ public function create_outlook_event_from_moodle_event($moodleventid) { } } catch (moodle_exception $e) { // No token found, nothing to do. + debugging('Error creating group event. Details: ' . $e->getMessage()); } } } @@ -478,7 +477,7 @@ public function update_outlook_event($moodleeventid) { try { $apiclient->update_event($idmaprec->outlookeventid, $updated, $o365upn); } catch (moodle_exception $e) { - // Do nothing. + mtrace('Error updating event: '.$e->getMessage()); } } } @@ -539,30 +538,6 @@ protected function construct_outlook_group_email($courseid) { return $groupemail; } - /** - * Get group first and last name. - * @param string $groupname The o365 group name. - * @return array The first index is the first name and the second index is the last name. - */ - protected function group_first_last_name($groupname) { - $firstname = ''; - $lastname = ''; - if (empty($groupname)) { - return array($firstname, $lastname); - } - - $pos = strpos($groupname, ': '); - - if (false === $pos) { - return array($firstname, $lastname); - } - - $firstname = substr($groupname, 0, $pos + 1); - $lastname = substr($groupname, $pos + 1); - $lastname = trim($lastname); - return array($firstname, $lastname); - } - /** * Create a new calendar in the user's o365 calendars. * diff --git a/classes/feature/calsync/observers.php b/classes/feature/calsync/observers.php index d88e78f50..3d89ad2f0 100644 --- a/classes/feature/calsync/observers.php +++ b/classes/feature/calsync/observers.php @@ -75,8 +75,8 @@ public static function handle_user_enrolment_deleted(\core\event\user_enrolment_ 'userid' => $userid, 'other' => [ 'caltype' => 'course', - 'caltypeid' => $courseid - ] + 'caltypeid' => $courseid, + ], ]; $event = \local_o365\event\calendar_unsubscribed::create($eventdata); $event->trigger(); diff --git a/classes/feature/calsync/task/importfromoutlook.php b/classes/feature/calsync/task/importfromoutlook.php index 68f34d413..944d68879 100644 --- a/classes/feature/calsync/task/importfromoutlook.php +++ b/classes/feature/calsync/task/importfromoutlook.php @@ -28,8 +28,6 @@ use core_date; use moodle_exception; -defined('MOODLE_INTERNAL') || die(); - /** * Scheduled task to check for new o365 events and sync them into Moodle. */ @@ -111,7 +109,7 @@ public function execute() { // If all day event time is stored in Outlook only as UTC time and not in the local user time. if (isset($event['isAllDay']) && $event['isAllDay'] == '1') { // Need to make the time the same as the user preference so no time conversion. - $user = $DB->get_record('user', array('id' => $calsub->user_id)); + $user = $DB->get_record('user', ['id' => $calsub->user_id]); if ($user->timezone == 99) { $user->timezone = core_date::get_server_timezone(); } @@ -137,7 +135,7 @@ public function execute() { 'eventid' => $moodleevent->id, 'outlookeventid' => $event['id'], 'origin' => 'o365', - 'userid' => $calsub->user_id + 'userid' => $calsub->user_id, ]; $DB->insert_record('local_o365_calidmap', (object)$idmaprec); mtrace('Successfully imported event #'.$moodleevent->id); diff --git a/classes/feature/calsync/task/syncoldevents.php b/classes/feature/calsync/task/syncoldevents.php index ae1423929..2f276920f 100644 --- a/classes/feature/calsync/task/syncoldevents.php +++ b/classes/feature/calsync/task/syncoldevents.php @@ -28,8 +28,6 @@ use local_o365\utils; use moodle_exception; -defined('MOODLE_INTERNAL') || die(); - /** * AdHoc task to sync existing Moodle calendar events with Microsoft 365. * @@ -125,7 +123,7 @@ protected function sync_siteevents($timecreated) { $calsync->update_event_raw($event->eventuserid, $event->outlookeventid, ['attendees' => $subscribersprimary]); } catch (moodle_exception $e) { - // Do nothing. + mtrace('ERROR: ' . $e->getMessage()); } } else { $calid = null; @@ -146,7 +144,7 @@ protected function sync_siteevents($timecreated) { $subscribersprimary, [], $calid); } } catch (moodle_exception $e) { - mtrace('ERROR: '.$e->getMessage()); + mtrace('ERROR: ' . $e->getMessage()); } } @@ -269,6 +267,7 @@ protected function sync_courseevents($courseid, $timecreated) { ['attendees' => $eventattendees]); } catch (moodle_exception $e) { // Do nothing. + mtrace('Error updating event #' . $event->eventid . ': ' . $e->getMessage()); } } else { $calid = null; @@ -327,7 +326,7 @@ protected function sync_courseevents($courseid, $timecreated) { } } catch (moodle_exception $e) { // Could not sync this course event. Log and continue. - mtrace('Error syncing course event #'.$event->eventid.': '.$e->getMessage()); + mtrace('Error syncing course event #' . $event->eventid . ': ' . $e->getMessage()); } } $events->close(); diff --git a/classes/feature/cohortsync/main.php b/classes/feature/cohortsync/main.php index 6471e081f..2eaa5e881 100644 --- a/classes/feature/cohortsync/main.php +++ b/classes/feature/cohortsync/main.php @@ -58,9 +58,11 @@ class main { private $cohortlist; /** + * Return the list of groups. + * * @return array */ - public function get_grouplist() : array { + public function get_grouplist(): array { if (is_null($this->grouplist)) { $this->fetch_groups_from_cache(); } @@ -69,9 +71,11 @@ public function get_grouplist() : array { } /** + * Return the list of cohorts. + * * @return array */ - public function get_cohortlist() : array { + public function get_cohortlist(): array { if (is_null($this->cohortlist)) { $this->fetch_cohorts(); } @@ -97,7 +101,7 @@ public function __construct(unified $graphclient) { * @param int $cohortid * @return bool */ - public function add_mapping(string $groupoid, int $cohortid) : bool { + public function add_mapping(string $groupoid, int $cohortid): bool { global $DB; if (!$groupoid || !$cohortid) { @@ -136,7 +140,7 @@ public function add_mapping(string $groupoid, int $cohortid) : bool { * * @return array */ - public function get_mappings() : array { + public function get_mappings(): array { global $DB; $mappings = $DB->get_records('local_o365_objects', ['type' => 'group', 'subtype' => 'cohort']); @@ -151,7 +155,7 @@ public function get_mappings() : array { * @param int $cohortid * @return void */ - public function delete_mapping_by_group_oid_and_cohort_id(string $groupoid, int $cohortid) : void { + public function delete_mapping_by_group_oid_and_cohort_id(string $groupoid, int $cohortid): void { global $DB; $params = ['objectid' => $groupoid, 'moodleid' => $cohortid]; @@ -164,7 +168,7 @@ public function delete_mapping_by_group_oid_and_cohort_id(string $groupoid, int * @param int $id * @return void */ - public function delete_mapping_by_id(int $id) : void { + public function delete_mapping_by_id(int $id): void { global $DB; $params = ['id' => $id]; @@ -177,7 +181,7 @@ public function delete_mapping_by_id(int $id) : void { * This function populates the $this->grouplist with the groups fetched from * the local Moodle cache. */ - public function fetch_groups_from_cache() : void { + public function fetch_groups_from_cache(): void { global $DB; $sql = 'SELECT * @@ -197,7 +201,7 @@ public function fetch_groups_from_cache() : void { /** * Fetch cohorts from the local Moodle cache. */ - public function fetch_cohorts() : void { + public function fetch_cohorts(): void { $systemcontext = context_system::instance(); $systemcohorts = cohort_get_cohorts($systemcontext->id, 0, 0); $this->cohortlist = $systemcohorts['cohorts']; @@ -208,7 +212,7 @@ public function fetch_cohorts() : void { * * @return bool */ - public function update_groups_cache() : bool { + public function update_groups_cache(): bool { global $DB; if (utils::update_groups_cache($this->graphclient, 1)) { @@ -230,7 +234,7 @@ public function update_groups_cache() : bool { * @param int $cohortid * @return void */ - public function sync_members_by_group_oid_and_cohort_id(string $groupoid, int $cohortid) : void { + public function sync_members_by_group_oid_and_cohort_id(string $groupoid, int $cohortid): void { $groupownersandmembers = $this->get_group_owners_and_members($groupoid); if ($groupownersandmembers !== false) { @@ -289,7 +293,7 @@ public function get_group_owners_and_members(string $groupoid) { * @return void */ private function sync_cohort_members_by_cohort_id_and_microsoft_user_objects(int $cohortid, - array $microsoftuserobjects) : void { + array $microsoftuserobjects): void { global $DB; $microsoftuseroids = array_column($microsoftuserobjects, 'id'); @@ -322,7 +326,7 @@ private function sync_cohort_members_by_cohort_id_and_microsoft_user_objects(int * @param array $moodleuserids * @return array */ - private function get_all_potential_user_details(array $microsoftuseroids, array $moodleuserids) : array { + private function get_all_potential_user_details(array $microsoftuseroids, array $moodleuserids): array { global $DB; if (empty($microsoftuseroids) && empty($moodleuserids)) { @@ -366,7 +370,7 @@ private function get_all_potential_user_details(array $microsoftuseroids, array * @param string $groupoid * @return string */ - public function get_group_name_by_group_oid(string $groupoid) : string { + public function get_group_name_by_group_oid(string $groupoid): string { $groupname = ''; foreach ($this->grouplist as $group) { @@ -385,7 +389,7 @@ public function get_group_name_by_group_oid(string $groupoid) : string { * @param int $cohortid * @return string */ - public function get_cohort_name_by_cohort_id(int $cohortid) : string { + public function get_cohort_name_by_cohort_id(int $cohortid): string { $cohortname = ''; if (is_null($this->cohortlist)) { diff --git a/classes/feature/courserequest/main.php b/classes/feature/courserequest/main.php index d37968506..ebf4ef648 100644 --- a/classes/feature/courserequest/main.php +++ b/classes/feature/courserequest/main.php @@ -25,8 +25,6 @@ namespace local_o365\feature\courserequest; -defined('MOODLE_INTERNAL') || die(); - use context_course; use core_user; use course_request; @@ -36,9 +34,22 @@ use local_o365\utils; use moodle_exception; use stdClass; + +/** + * Main class for the course request from Microsoft Teams feature. + */ class main { + /** + * @var int The course request status: pending. + */ const COURSE_REQUEST_STATUS_PENDING = 0; + /** + * @var int The course request status: approved. + */ const COURSE_REQUEST_STATUS_APPROVED = 1; + /** + * @var int The course request status: rejected. + */ const COURSE_REQUEST_STATUS_REJECTED = 2; /** @@ -70,7 +81,7 @@ public function __construct(unified $graphclient, bool $debug = false) { * @param string $eol * @return void */ - protected function mtrace(string $msg, int $level = 0, string $eol = "\n") : void { + protected function mtrace(string $msg, int $level = 0, string $eol = "\n"): void { if ($this->debug === true) { if ($level) { $msg = str_repeat('...', $level) . ' ' . $msg; @@ -86,7 +97,7 @@ protected function mtrace(string $msg, int $level = 0, string $eol = "\n") : voi * @param array $teamdata * @return bool */ - public function save_custom_course_request_data(course_request $request, array $teamdata) : bool { + public function save_custom_course_request_data(course_request $request, array $teamdata): bool { global $DB; if (empty($request) || empty($teamdata)) { @@ -197,7 +208,7 @@ public function get_user_team_details_by_team_oid(string $teamoid) { * @param int $courseid * @return bool */ - public function enrol_team_owners_and_members_in_course_by_team_oid_and_course_id(string $teamoid, int $courseid) : bool { + public function enrol_team_owners_and_members_in_course_by_team_oid_and_course_id(string $teamoid, int $courseid): bool { global $DB; if (empty($teamoid) || empty($courseid)) { @@ -246,7 +257,7 @@ public function enrol_team_owners_and_members_in_course_by_team_oid_and_course_i } if ($moodleuser->suspended || $moodleuser->deleted) { mtrace('......... Moodle user matching Microsoft account ' . $teamowner['id'] . ' is suspended or deleted.'); - contrinue; + continue; } if (user_has_role_assignment($userconnectionrecord->moodleid, $ownerroleid, $context->id) && in_array($userconnectionrecord->moodleid, $enrolleduserids)) { @@ -276,7 +287,7 @@ public function enrol_team_owners_and_members_in_course_by_team_oid_and_course_i } if ($moodleuser->suspended || $moodleuser->deleted) { mtrace('......... Moodle user matching Microsoft account ' . $teammember['id'] . ' is suspended or deleted.'); - contrinue; + continue; } if (user_has_role_assignment($userconnectionrecord->moodleid, $memberroleid, $context->id) && in_array($userconnectionrecord->moodleid, $enrolleduserids)) { @@ -300,7 +311,7 @@ public function enrol_team_owners_and_members_in_course_by_team_oid_and_course_i * * @return array */ - private function get_team_owners_and_members_by_team_oid(string $teamoid) : array { + private function get_team_owners_and_members_by_team_oid(string $teamoid): array { $teamowners = []; $teammembers = []; diff --git a/classes/feature/coursesync/main.php b/classes/feature/coursesync/main.php index 596d674a2..58cb77d4f 100644 --- a/classes/feature/coursesync/main.php +++ b/classes/feature/coursesync/main.php @@ -33,8 +33,6 @@ use moodle_exception; use stdClass; -defined('MOODLE_INTERNAL') || die(); - define('API_CALL_RETRY_LIMIT', 5); /** @@ -112,14 +110,14 @@ protected function mtrace(string $msg, int $level = 0, string $eol = "\n") { * * @return bool */ - public function has_education_license() : bool { + public function has_education_license(): bool { return $this->haseducationlicense; } /** * Create teams and populate membership for all courses that don't have an associated team recorded. */ - public function sync_courses() : bool { + public function sync_courses(): bool { global $DB; $this->mtrace('Start syncing courses.'); @@ -254,7 +252,7 @@ private function create_education_group(stdClass $course, int $baselevel = 3) { * @param int $baselevel * @return bool */ - public function set_lti_properties_in_education_group(string $groupobjectid, stdClass $course, int $baselevel = 3) : bool { + public function set_lti_properties_in_education_group(string $groupobjectid, stdClass $course, int $baselevel = 3): bool { $this->mtrace('Set LMS attributes in group ' . $groupobjectid . ' for course #' . $course->id, $baselevel); $lmsattributes = [ @@ -346,7 +344,7 @@ private function create_standard_group(stdClass $course, int $baselevel = 3) { * @return bool whether at least one owner was added. */ private function add_group_owners_and_members_to_group(string $groupobjectid, array $owners, array $members, - int $baselevel = 3) : bool { + int $baselevel = 3): bool { global $SESSION; if (empty($owners) && empty($members)) { $this->mtrace('Skip adding owners / members to the group. Reason: No users to add.', $baselevel); @@ -441,7 +439,7 @@ private function add_group_owners_and_members_to_group(string $groupobjectid, ar sleep(10); } try { - $this->mtrace('Chunk ' . $key + 1 . ', adding ' . count($users) . ' users as ' . $role, $baselevel + 1); + $this->mtrace('Chunk ' . ($key + 1) . ', adding ' . count($users) . ' users as ' . $role, $baselevel + 1); if (isset($SESSION->o365_groups_not_exist)) { if (in_array($groupobjectid, $SESSION->o365_groups_not_exist)) { @@ -498,7 +496,7 @@ private function add_group_owners_and_members_to_group(string $groupobjectid, ar * @param string $exceptionmessage * @return bool */ - private static function is_resource_not_exist_exception(string $exceptionmessage) : bool { + private static function is_resource_not_exist_exception(string $exceptionmessage): bool { return (strpos($exceptionmessage, \local_o365\utils::RESOURCE_NOT_EXIST_ERROR) !== false); } @@ -754,7 +752,7 @@ public function install_moodle_app_in_team(string $groupobjectid, int $courseid, * @return string */ private function add_moodle_tab_to_channel(string $groupobjectid, string $channelid, string $appid, - int $moodlecourseid) : string { + int $moodlecourseid): string { global $CFG; $tabconfiguration = [ @@ -837,7 +835,7 @@ private function process_courses_without_groups(int $baselevel = 1) { * @param int $baselevel * @return bool True if group creation succeeds, or False if it fails. */ - public function create_group_for_course(stdClass $course, int $baselevel = 2) : bool { + public function create_group_for_course(stdClass $course, int $baselevel = 2): bool { global $SESSION; $this->mtrace('Process course #' . $course->id, $baselevel); @@ -999,7 +997,7 @@ private function process_courses_without_teams() { * @param array $objectrecmetadata The metadata of the object database record. * @return bool */ - private function restore_group(int $objectrecid, string $objectid, array $objectrecmetadata) : bool { + private function restore_group(int $objectrecid, string $objectid, array $objectrecmetadata): bool { global $DB; $deletedgroups = $this->graphclient->list_deleted_groups(); @@ -1028,7 +1026,7 @@ private function restore_group(int $objectrecid, string $objectid, array $object * * @return bool */ - public function update_teams_cache() : bool { + public function update_teams_cache(): bool { global $DB; $this->mtrace('Update teams cache...'); @@ -1184,7 +1182,7 @@ public function cleanup_course_connection_records() { * * @return bool */ - public function update_team_name(int $courseid) : bool { + public function update_team_name(int $courseid): bool { global $DB; if (!$course = $DB->get_record('course', ['id' => $courseid])) { @@ -1238,7 +1236,7 @@ public function update_team_name(int $courseid) : bool { * @return bool */ public function process_course_reset(stdClass $course, stdClass $o365object, bool $teamexists = false, - bool $createafterreset = true) : bool { + bool $createafterreset = true): bool { global $DB; // Rename existing group. @@ -1477,7 +1475,7 @@ public function process_course_team_user_sync_from_moodle_to_microsoft(int $cour * @return array * @throws moodle_exception */ - public function get_group_members(string $groupobjectid) : array { + public function get_group_members(string $groupobjectid): array { $groupmembers = []; $memberrecords = $this->graphclient->get_group_members($groupobjectid); @@ -1495,7 +1493,7 @@ public function get_group_members(string $groupobjectid) : array { * @return array * @throws moodle_exception */ - public function get_group_owners(string $groupobjectid) : array { + public function get_group_owners(string $groupobjectid): array { $groupowners = []; $ownerresults = $this->graphclient->get_group_owners($groupobjectid); @@ -1511,7 +1509,7 @@ public function get_group_owners(string $groupobjectid) : array { * * @return array An array of group IDs. */ - public function get_all_group_ids() : array { + public function get_all_group_ids(): array { $groupids = []; $groups = $this->graphclient->get_groups(); @@ -1636,6 +1634,7 @@ public function remove_member_from_group(string $groupobjectid, string $userobje $this->graphclient->get_aad_user_conversation_member_id($groupobjectid, $userobjectid); } catch (moodle_exception $e) { // Do nothing. + $removed = false; } if ($aaduserconversationmemberid) { try { @@ -1644,6 +1643,7 @@ public function remove_member_from_group(string $groupobjectid, string $userobje $removed = true; } catch (moodle_exception $e) { // Do nothing. + $removed = false; } } } @@ -1669,6 +1669,7 @@ public function remove_owner_from_group(string $groupobjectid, string $userobjec $this->graphclient->get_aad_user_conversation_member_id($groupobjectid, $userobjectid); } catch (moodle_exception $e) { // Do nothing. + $removed = false; } if ($aaduserconversationmemberid) { try { @@ -1677,6 +1678,7 @@ public function remove_owner_from_group(string $groupobjectid, string $userobjec $removed = true; } catch (moodle_exception $e) { // Do nothing. + $removed = false; } } } @@ -1695,7 +1697,7 @@ public function remove_owner_from_group(string $groupobjectid, string $userobjec * @return bool */ public function process_course_team_user_sync_from_microsoft_to_moodle(int $courseid, string $groupobjectid = '', - array $connectedusers = null) : bool { + ?array $connectedusers = null): bool { global $DB; $coursecontext = context_course::instance($courseid, IGNORE_MISSING); @@ -1785,8 +1787,8 @@ public function process_course_team_user_sync_from_microsoft_to_moodle(int $cour array_keys($moodletomicrosoftusermappings)); // Sync teachers. - // - $connectedcurrentcourseteachers contains the current teachers in the course. - // - $connectedintendedcourseteachers contains the teachers that should be in the course. + // - $connectedcurrentcourseteachers contains the current teachers in the course. + // - $connectedintendedcourseteachers contains the teachers that should be in the course. $teacherstoenrol = array_diff($connectedintendedcourseteachers, $connectedcurrentcourseteachers); if ($teacherstoenrol) { $this->mtrace('Add teacher role to ' . count($teacherstoenrol) . ' users...', 2); @@ -1809,8 +1811,8 @@ public function process_course_team_user_sync_from_microsoft_to_moodle(int $cour } // Sync students. - // - $connectedcurrentcoursestudents contains the current students in the course. - // - $connectedintendedcoursestudents contains the students that should be in the course. + // - $connectedcurrentcoursestudents contains the current students in the course. + // - $connectedintendedcoursestudents contains the students that should be in the course. $studentstoenrol = array_diff($connectedintendedcoursestudents, $connectedcurrentcoursestudents); if ($studentstoenrol) { $this->mtrace('Add student role to ' . count($studentstoenrol) . ' users...', 2); @@ -1842,7 +1844,7 @@ public function process_course_team_user_sync_from_microsoft_to_moodle(int $cour * @param int $roleid The ID of the role. * @param context_course $context The context of the course. */ - private function assign_role_by_user_id_role_id_and_course_context(int $userid, int $roleid, context_course $context) : void { + private function assign_role_by_user_id_role_id_and_course_context(int $userid, int $roleid, context_course $context): void { enrol_try_internal_enrol($context->instanceid, $userid, $roleid); $this->mtrace('Assigned role #' . $roleid . ' to user #' . $userid . '.', 3); } @@ -1857,7 +1859,7 @@ private function assign_role_by_user_id_role_id_and_course_context(int $userid, * @param bool $hasotherrole Whether the user has other role. */ private function unassign_role_by_user_id_role_id_and_course_context(int $userid, int $roleid, context_course $context, - bool $hasotherrole) : void { + bool $hasotherrole): void { role_unassign($roleid, $userid, $context->id); $this->mtrace('Removed role #' . $roleid . ' from user #' . $userid . '.', 3); @@ -1875,7 +1877,7 @@ private function unassign_role_by_user_id_role_id_and_course_context(int $userid * @param int $courseid The ID of the course. * @return bool */ - private function unenrol_user_by_user_id_and_course_id(int $userid, int $courseid) : bool { + private function unenrol_user_by_user_id_and_course_id(int $userid, int $courseid): bool { global $DB; $sql = "SELECT * @@ -1919,7 +1921,7 @@ private function unenrol_user_by_user_id_and_course_id(int $userid, int $coursei * @param int $courseid The ID of the course. * @param string $groupobjectid The object ID of the Microsoft 365 group. */ - public function process_initial_course_team_user_sync(int $courseid, string $groupobjectid) : void { + public function process_initial_course_team_user_sync(int $courseid, string $groupobjectid): void { $coursecontext = context_course::instance($courseid); $this->mtrace('Perform initial Moodle course and Microsoft Teams user sync between course #' . $courseid . @@ -1980,8 +1982,8 @@ public function process_initial_course_team_user_sync(int $courseid, string $gro } // Sync teachers from Microsoft Teams to Moodle course. - // - $connectedcurrentcourseteachers contains the current teachers in the course. - // - $connectedintendedcourseteachers contains the teachers that should be in the course. + // - $connectedcurrentcourseteachers contains the current teachers in the course. + // - $connectedintendedcourseteachers contains the teachers that should be in the course. $teacherstoenrol = array_diff($connectedintendedcourseteachers, $connectedcurrentcourseteachers); if ($teacherstoenrol) { $this->mtrace('Add teacher role to ' . count($teacherstoenrol) . ' users...', 2); @@ -1993,8 +1995,8 @@ public function process_initial_course_team_user_sync(int $courseid, string $gro } // Sync students from Microsoft Teams to Moodle course. - // - $connectedcurrentcoursestudents contains the current students in the course. - // - $connectedintendedcoursestudents contains the students that should be in the course. + // - $connectedcurrentcoursestudents contains the current students in the course. + // - $connectedintendedcoursestudents contains the students that should be in the course. $studentstoenrol = array_diff($connectedintendedcoursestudents, $connectedcurrentcoursestudents); if ($studentstoenrol) { $this->mtrace('Add student role to ' . count($studentstoenrol) . ' users...', 2); @@ -2025,7 +2027,7 @@ public function process_initial_course_team_user_sync(int $courseid, string $gro * * @return void */ - public function save_not_found_groups() : void { + public function save_not_found_groups(): void { global $DB, $SESSION; $this->mtrace('Save non-existing groups to groups cache...'); diff --git a/classes/feature/coursesync/observers.php b/classes/feature/coursesync/observers.php index 3f2b110a8..ba2d38568 100644 --- a/classes/feature/coursesync/observers.php +++ b/classes/feature/coursesync/observers.php @@ -46,7 +46,7 @@ class observers { * @param course_reset_started $event * @return bool */ - public static function handle_course_reset_started(course_reset_started $event) : bool { + public static function handle_course_reset_started(course_reset_started $event): bool { global $CFG, $DB; if (!\local_o365\utils::is_connected()) { @@ -88,6 +88,7 @@ public static function handle_course_reset_started(course_reset_started $event) } } catch (moodle_exception $e) { // Do nothing. + $connectedtoteam = false; } } } else { diff --git a/classes/feature/coursesync/utils.php b/classes/feature/coursesync/utils.php index 1478ae10e..59d58a157 100644 --- a/classes/feature/coursesync/utils.php +++ b/classes/feature/coursesync/utils.php @@ -46,7 +46,7 @@ class utils { * * @return bool True if group creation is enabled. False otherwise. */ - public static function is_enabled() : bool { + public static function is_enabled(): bool { $coursesyncsetting = get_config('local_o365', 'coursesync'); return $coursesyncsetting === 'oncustom' || $coursesyncsetting === 'onall'; } @@ -103,7 +103,7 @@ public static function get_enabled_courses(bool $returnallids = false) { * @param int $courseid The Moodle course ID to check. * @return bool Whether the course is enabled for sync. */ - public static function is_course_sync_enabled(int $courseid) : bool { + public static function is_course_sync_enabled(int $courseid): bool { $coursesyncsetting = get_config('local_o365', 'coursesync'); if ($coursesyncsetting === 'onall') { return true; @@ -170,7 +170,7 @@ public static function get_o365_object(int $courseid) { * @param int $courseid * @return string[]|null */ - public static function get_course_microsoft_365_urls(int $courseid) : ?array { + public static function get_course_microsoft_365_urls(int $courseid): ?array { $object = static::get_o365_object($courseid); if (empty($object->objectid)) { return null; @@ -267,7 +267,7 @@ public static function set_course_sync_enabled(int $courseid, bool $enabled = tr * @param string $currentoid * @return array */ - public static function get_matching_team_options(string $currentoid = '') : array { + public static function get_matching_team_options(string $currentoid = ''): array { global $DB; $teamsoptions = []; @@ -316,11 +316,11 @@ public static function get_matching_team_options(string $currentoid = '') : arra * * @param stdClass $course * @param string $forcedprefix - * @param stdClass $group + * @param stdClass|null $group * * @return string */ - public static function get_team_display_name(stdClass $course, string $forcedprefix = '', stdClass $group = null) { + public static function get_team_display_name(stdClass $course, string $forcedprefix = '', ?stdClass $group = null) { if ($forcedprefix) { $teamdisplayname = $forcedprefix; } else { @@ -367,7 +367,7 @@ public static function get_team_display_name(stdClass $course, string $forcedpre * * @return array */ - public static function get_sample_team_group_names() : array { + public static function get_sample_team_group_names(): array { $teamgroupamesamplecourse = static::get_team_group_name_sample_course(); return [static::get_team_display_name($teamgroupamesamplecourse), static::get_group_mail_alias($teamgroupamesamplecourse)]; @@ -380,7 +380,7 @@ public static function get_sample_team_group_names() : array { * * @return string */ - public static function get_group_mail_alias(stdClass $course) : string { + public static function get_group_mail_alias(stdClass $course): string { $groupmailaliasprefix = get_config('local_o365', 'group_mail_alias_prefix'); if ($groupmailaliasprefix) { $groupmailaliasprefix = static::clean_up_group_mail_alias($groupmailaliasprefix); @@ -428,7 +428,7 @@ public static function get_group_mail_alias(stdClass $course) : string { public static function clean_up_group_mail_alias(string $mailalias) { $notallowedbasicchars = ['@', '(', ')', "\\", '[', ']', '"', ';', ':', '.', '<', '>', ' ']; $chars = preg_split( '//u', $mailalias, -1, PREG_SPLIT_NO_EMPTY); - foreach($chars as $key => $char){ + foreach ($chars as $key => $char) { $charorder = ord($char); if ($charorder < 0 || $charorder > 127 || in_array($char, $notallowedbasicchars)) { unset($chars[$key]); @@ -443,7 +443,7 @@ public static function clean_up_group_mail_alias(string $mailalias) { * * @return stdClass */ - public static function get_team_group_name_sample_course() : stdClass { + public static function get_team_group_name_sample_course(): stdClass { $samplecourse = new stdClass(); $samplecourse->fullname = 'Sample course 15'; $samplecourse->shortname = 'sample 15'; @@ -459,7 +459,7 @@ public static function get_team_group_name_sample_course() : stdClass { * @param array $userids * @return array */ - public static function get_user_object_ids_by_user_ids(array $userids) : array { + public static function get_user_object_ids_by_user_ids(array $userids): array { global $DB; if ($userids) { @@ -540,7 +540,7 @@ public static function get_user_object_record_id_by_user_id(int $userid) { * @param int $courseid * @return array */ - public static function get_team_owner_object_ids_by_course_id(int $courseid) : array { + public static function get_team_owner_object_ids_by_course_id(int $courseid): array { $teamownerobjectids = []; $teamowneruserids = static::get_team_owner_user_ids_by_course_id($courseid); if ($teamowneruserids) { @@ -556,7 +556,7 @@ public static function get_team_owner_object_ids_by_course_id(int $courseid) : a * @param int $courseid ID of Moodle course * @return array array containing IDs of teachers. */ - public static function get_team_owner_user_ids_by_course_id(int $courseid) : array { + public static function get_team_owner_user_ids_by_course_id(int $courseid): array { $context = context_course::instance($courseid); $teamownerusers = get_enrolled_users($context, 'local/o365:teamowner', 0, 'u.*', null, 0, 0, true); $teamowneruserids = []; @@ -576,7 +576,7 @@ public static function get_team_owner_user_ids_by_course_id(int $courseid) : arr * @param array $teamownerobjectids * @return array */ - public static function get_team_member_object_ids_by_course_id(int $courseid, array $teamownerobjectids = []) : array { + public static function get_team_member_object_ids_by_course_id(int $courseid, array $teamownerobjectids = []): array { $teammemberobjectids = []; $teammemberuserids = static::get_team_member_user_ids_by_course_id($courseid); if ($teammemberuserids) { @@ -594,7 +594,7 @@ public static function get_team_member_object_ids_by_course_id(int $courseid, ar * @param int $courseid ID of the Moodle course * @return array */ - public static function get_team_member_user_ids_by_course_id(int $courseid) : array { + public static function get_team_member_user_ids_by_course_id(int $courseid): array { $context = context_course::instance($courseid); $teammemberusers = get_enrolled_users($context, 'local/o365:teammember', 0, 'u.*', null, 0, 0, true); $teammemberuserids = []; @@ -614,7 +614,7 @@ public static function get_team_member_user_ids_by_course_id(int $courseid) : ar * @param array $members * @return array */ - public static function arrange_group_users_in_chunks(array $owners, array $members) : array { + public static function arrange_group_users_in_chunks(array $owners, array $members): array { $userchunks = []; $ownerchunks = array_chunk($owners, 20); @@ -686,6 +686,7 @@ public static function migrate_existing_groups() { } } catch (moodle_exception $e) { // Cannot get graph client, nothing to do. + return; } } @@ -698,7 +699,7 @@ public static function migrate_existing_groups() { * @param int $excluderoleid * @return string */ - public static function get_user_group_role_by_moodle_ids(int $userid, int $courseid, int $excluderoleid = 0) : string { + public static function get_user_group_role_by_moodle_ids(int $userid, int $courseid, int $excluderoleid = 0): string { $grouprole = ''; $coursecontext = context_course::instance($courseid); @@ -737,7 +738,7 @@ public static function get_user_group_role_by_moodle_ids(int $userid, int $cours * @return bool */ public static function sync_user_role_in_course_group(int $userid, int $courseid, int $userobjectrecordid = 0, - int $coursegroupobjectrecordid = 0, bool $sdscoursechecked = false, int $excluderoleid = 0) : bool { + int $coursegroupobjectrecordid = 0, bool $sdscoursechecked = false, int $excluderoleid = 0): bool { global $DB; if (empty($userid) || empty($courseid)) { @@ -777,8 +778,8 @@ public static function sync_user_role_in_course_group(int $userid, int $courseid $grouprole = static::get_user_group_role_by_moodle_ids($userid, $courseid, $excluderoleid); // Get group and user object IDs. - $groupobjectid = utils::get_object_id_by_record_id($coursegroupobjectrecordid); - $userobjectid = utils::get_object_id_by_record_id($userobjectrecordid); + $groupobjectid = static::get_object_id_by_record_id($coursegroupobjectrecordid); + $userobjectid = static::get_object_id_by_record_id($userobjectrecordid); // If the user doesn't have any group role, remove the user from the connected group. if (!$grouprole) { @@ -835,7 +836,7 @@ public static function sync_user_role_in_course_group(int $userid, int $courseid * @param string $groupobjectid * @return bool */ - public static function is_team_created_from_group(string $groupobjectid) : bool { + public static function is_team_created_from_group(string $groupobjectid): bool { global $DB; return $DB->record_exists('local_o365_objects', diff --git a/classes/feature/sds/task/sync.php b/classes/feature/sds/task/sync.php index bc37ef7dc..d90d4bfb5 100644 --- a/classes/feature/sds/task/sync.php +++ b/classes/feature/sds/task/sync.php @@ -33,8 +33,6 @@ use local_o365\utils; use moodle_exception; -defined('MOODLE_INTERNAL') || die(); - /** * Scheduled task to run SDS sync. */ @@ -44,7 +42,7 @@ class sync extends scheduled_task { * * @return string */ - public function get_name() : string { + public function get_name(): string { return get_string('task_sds_sync', 'local_o365'); } @@ -54,7 +52,7 @@ public function get_name() : string { * @param unified $apiclient The unified API client. * @return bool */ - public static function runsync(unified $apiclient) : bool { + public static function runsync(unified $apiclient): bool { global $DB, $CFG; require_once($CFG->dirroot . '/user/lib.php'); @@ -438,7 +436,7 @@ public static function mtrace(string $str, int $level = 0) { * @return object The course object. */ public static function get_or_create_class_course(string $classobjectid, string $shortname, string $fullname, - int $categoryid = 0) : object { + int $categoryid = 0): object { global $DB, $CFG; require_once($CFG->dirroot . '/course/lib.php'); @@ -458,12 +456,12 @@ public static function get_or_create_class_course(string $classobjectid, string } // Create new course category and object record. - $data = ['category' => $categoryid, 'shortname' => $shortname, 'fullname' => $fullname, 'idnumber' => $classobjectid,]; + $data = ['category' => $categoryid, 'shortname' => $shortname, 'fullname' => $fullname, 'idnumber' => $classobjectid]; $course = create_course((object) $data); $now = time(); $objectrec = ['type' => 'sdssection', 'subtype' => 'course', 'objectid' => $classobjectid, 'moodleid' => $course->id, - 'o365name' => $shortname, 'tenant' => '', 'timecreated' => $now, 'timemodified' => $now,]; + 'o365name' => $shortname, 'tenant' => '', 'timecreated' => $now, 'timemodified' => $now]; $DB->insert_record('local_o365_objects', $objectrec); return $course; @@ -476,7 +474,7 @@ public static function get_or_create_class_course(string $classobjectid, string * @param string $schoolname The name of the school. * @return core_course_category A course category object for the retrieved or created course category. */ - public static function get_or_create_school_coursecategory(string $schoolobjectid, string $schoolname) : core_course_category { + public static function get_or_create_school_coursecategory(string $schoolobjectid, string $schoolname): core_course_category { global $DB; // Look for existing category. @@ -494,7 +492,7 @@ public static function get_or_create_school_coursecategory(string $schoolobjecti } // Create new course category and object record. - $data = ['visible' => 1, 'name' => $schoolname, 'idnumber' => $schoolobjectid,]; + $data = ['visible' => 1, 'name' => $schoolname, 'idnumber' => $schoolobjectid]; if (strlen($data['name']) > 255) { static::mtrace('School name was over 255 chars when creating course category, truncating to 255.'); $data['name'] = substr($data['name'], 0, 255); @@ -504,7 +502,7 @@ public static function get_or_create_school_coursecategory(string $schoolobjecti $now = time(); $objectrec = ['type' => 'sdsschool', 'subtype' => 'coursecat', 'objectid' => $schoolobjectid, 'moodleid' => $coursecat->id, - 'o365name' => $schoolname, 'tenant' => '', 'timecreated' => $now, 'timemodified' => $now,]; + 'o365name' => $schoolname, 'tenant' => '', 'timecreated' => $now, 'timemodified' => $now]; $DB->insert_record('local_o365_objects', $objectrec); return $coursecat; @@ -515,7 +513,7 @@ public static function get_or_create_school_coursecategory(string $schoolobjecti * * @return bool */ - public function execute() : bool { + public function execute(): bool { if (utils::is_connected() !== true) { static::mtrace('local_o365 reported unconfigured during SDS sync task, so exiting.'); return false; @@ -573,6 +571,7 @@ public static function clean_up_sds_sync_records() { $sectionsinenabledschools = array_merge($sectionsinenabledschools, $schoolclasses); } catch (moodle_exception $e) { // Do nothing. + static::mtrace('Error getting school classes. Details: ' . $e->getMessage(), 2); } } foreach ($sectionsinenabledschools as $sectionsinenabledschool) { diff --git a/classes/feature/sds/utils.php b/classes/feature/sds/utils.php index 9a4bfd22a..da20c9472 100644 --- a/classes/feature/sds/utils.php +++ b/classes/feature/sds/utils.php @@ -43,7 +43,7 @@ class utils { * * @return unified|null The SDS API client. */ - public static function get_apiclient() : ?unified { + public static function get_apiclient(): ?unified { $httpclient = new httpclient(); try { $clientdata = clientdata::instance_from_oidc(); @@ -69,7 +69,7 @@ public static function get_apiclient() : ?unified { * @param unified|null $apiclient * @return array */ - public static function get_profile_sync_status_with_id_name(unified $apiclient = null) : array { + public static function get_profile_sync_status_with_id_name(?unified $apiclient = null): array { $profilesyncenabled = false; $schoolid = ''; $schoolname = ''; @@ -112,7 +112,7 @@ public static function get_profile_sync_status_with_id_name(unified $apiclient = * * @return array[] */ - public static function get_sds_profile_sync_api_requirements() : array { + public static function get_sds_profile_sync_api_requirements(): array { $idandnamemappings = []; $additionalprofilemappings = []; diff --git a/classes/feature/userconnections/filtering.php b/classes/feature/userconnections/filtering.php index 8c2f31cc0..c5af3ae5b 100644 --- a/classes/feature/userconnections/filtering.php +++ b/classes/feature/userconnections/filtering.php @@ -80,13 +80,13 @@ public function get_field($fieldname, $advanced) { * Returns sql where statement based on active user filters. * * @param string $extra sql - * @param array $params named params (recommended prefix ex) + * @param array|null $params named params (recommended prefix ex) * @return array sql string and $params */ - public function get_sql_filter($extra='', array $params=null) { + public function get_sql_filter($extra='', ?array $params=null) { global $SESSION; - $sqls = array(); + $sqls = []; if ($extra != '') { $sqls[] = $extra; } @@ -102,7 +102,7 @@ public function get_sql_filter($extra='', array $params=null) { } $field = $this->_fields[$fname]; foreach ($datas as $i => $data) { - list($s, $p) = $field->get_sql_filter($data); + [$s, $p] = $field->get_sql_filter($data); $sqls[] = $s; $params = $params + $p; } @@ -131,7 +131,7 @@ public function get_filter_o365username() { $datas = $SESSION->user_filtering[$fname]; $field = $this->_fields[$fname]; foreach ($datas as $i => $data) { - list($s, $p) = $field->get_sql_filter($data); + [$s, $p] = $field->get_sql_filter($data); $sqls[] = $s; $params = $params + $p; } diff --git a/classes/feature/usersync/main.php b/classes/feature/usersync/main.php index 3abe97929..5a0826569 100644 --- a/classes/feature/usersync/main.php +++ b/classes/feature/usersync/main.php @@ -68,7 +68,7 @@ class main { * * @throws moodle_exception */ - public function __construct(clientdata $clientdata = null, httpclient $httpclient = null) { + public function __construct(?clientdata $clientdata = null, ?httpclient $httpclient = null) { if (!PHPUNIT_TEST && !defined('BEHAT_SITE_RUNNING')) { $this->clientdata = (!empty($clientdata)) ? $clientdata @@ -190,7 +190,7 @@ public function assign_photo(int $muserid) { // User has no photo. Deleting previous profile photo. $fs = \get_file_storage(); $fs->delete_area_files($context->id, 'user', 'icon'); - $DB->set_field('user', 'picture', 0, array('id' => $muser->id)); + $DB->set_field('user', 'picture', 0, ['id' => $muser->id]); } $result = false; } else { @@ -234,7 +234,7 @@ public function assign_photo(int $muserid) { // User has no photo. Deleting previous profile photo. $fs = \get_file_storage(); $fs->delete_area_files($context->id, 'user', 'icon'); - $DB->set_field('user', 'picture', 0, array('id' => $muser->id)); + $DB->set_field('user', 'picture', 0, ['id' => $muser->id]); } } } @@ -563,7 +563,8 @@ public static function apply_configured_fieldmap(array $entraiduserdata, stdClas if (isset($countrymap[$incoming])) { $countrycode = $incoming; } else { - $countrycode = array_search($entraiduserdata[$remotefield], get_string_manager()->get_list_of_countries()); + $countrycode = array_search($entraiduserdata[$remotefield], + get_string_manager()->get_list_of_countries()); } $user->$localfield = (!empty($countrycode)) ? $countrycode : ''; break; @@ -803,7 +804,7 @@ protected function check_usercreationrestriction($entraiduserdata) { return false; } else { - utils:debug('Invalid extension attribute ID', __METHOD__); + utils::debug('Invalid extension attribute ID', __METHOD__); return false; } } else { @@ -1012,7 +1013,7 @@ public static function sync_option_enabled($option) { * @param string $bindingusernameclaim * @return bool Success/Failure */ - public function sync_users(array $entraidusers = array(), string $bindingusernameclaim = 'userPrincipalName') { + public function sync_users(array $entraidusers = [], string $bindingusernameclaim = 'userPrincipalName') { global $DB, $CFG; $usersyncsettings = $this->get_sync_options(); @@ -1158,7 +1159,8 @@ public function sync_users(array $entraidusers = array(), string $bindingusernam LEFT JOIN {local_o365_connections} conn ON conn.muserid = u.id LEFT JOIN {local_o365_appassign} assign ON assign.muserid = u.id LEFT JOIN {local_o365_objects} obj ON obj.type = ? AND obj.moodleid = u.id - WHERE tok.oidcusername '.$useridentifiersql.' AND u.username '.$usernamesql.' AND u.mnethostid = ? AND u.deleted = ? '; + WHERE tok.oidcusername ' . $useridentifiersql . ' AND u.username ' . $usernamesql . ' AND u.mnethostid = ? + AND u.deleted = ? '; $params = array_merge(['user'], $useridentifierparams, $usernameparams, [$CFG->mnet_localhost_id, '0']); $linkedexistingusers = $DB->get_records_sql($sql, $params); @@ -1258,7 +1260,8 @@ public function sync_users(array $entraidusers = array(), string $bindingusernam $existinguserrecord->suspended = $renamedmoodleuser->suspended; $existinguserrecord->auth = $renamedmoodleuser->auth; - $connected = $this->sync_existing_user($usersyncsettings, $entraiduser, $existinguserrecord, $exactmatch); + $connected = $this->sync_existing_user($usersyncsettings, $entraiduser, $existinguserrecord, + $exactmatch); $existinguser = $renamedmoodleuser; } } else { @@ -1281,7 +1284,8 @@ public function sync_users(array $entraidusers = array(), string $bindingusernam if (isset($entraiduser['id']) && $entraiduser['id'] && $existingusermatching = $DB->get_record('local_o365_objects', ['type' => 'user', 'objectid' => $entraiduser['id']])) { - $possibleo365names = [$entraiduser['useridentifierlower'], $entraiduser['convertedidentifier'], $entraiduser['useridentifier']]; + $possibleo365names = [$entraiduser['useridentifierlower'], $entraiduser['convertedidentifier'], + $entraiduser['useridentifier']]; if (isset($entraiduser['upnsplit0'])) { $possibleo365names[] = $entraiduser['upnsplit0']; } @@ -1321,7 +1325,8 @@ public function sync_users(array $entraidusers = array(), string $bindingusernam $DB->update_record('local_o365_objects', $existingusermatching); // Update token record. - if ($existingtoken = $DB->get_record('auth_oidc_token', ['userid' => $renamedmoodleuser->id])) { + if ($existingtoken = $DB->get_record('auth_oidc_token', + ['userid' => $renamedmoodleuser->id])) { $existingtoken->useridentifier = $entraiduser['useridentifier']; $existingtoken->username = $username; $DB->update_record('auth_oidc_token', $existingtoken); @@ -1607,7 +1612,8 @@ protected function sync_existing_user($syncoptions, $entraiduserdata, $existingu // Match user if needed. if ($existinguser->auth !== 'oidc') { $this->mtrace('Found a user in Microsoft Entra ID that seems to match a user in Moodle'); - $this->mtrace(sprintf('moodle username: %s, Entra ID user identifier: %s', $existinguser->username, $entraiduserdata['useridentifierlower'])); + $this->mtrace(sprintf('moodle username: %s, Entra ID user identifier: %s', $existinguser->username, + $entraiduserdata['useridentifierlower'])); return $this->sync_users_matchuser($syncoptions, $entraiduserdata, $existinguser, $exactmatch); } else { $this->mtrace('The user is already using OIDC for authentication.'); diff --git a/classes/form/cohortsync.php b/classes/form/cohortsync.php index feb0d7c61..47be34d53 100644 --- a/classes/form/cohortsync.php +++ b/classes/form/cohortsync.php @@ -43,7 +43,7 @@ class cohortsync extends moodleform { /** * Define the form elements. */ - public function definition() : void { + public function definition(): void { $mform = $this->_form; $cohortsyncmain = $this->_customdata['cohortsyncmain']; diff --git a/classes/form/courserequestform.php b/classes/form/courserequestform.php index 2e3767f89..6a823e8b6 100644 --- a/classes/form/courserequestform.php +++ b/classes/form/courserequestform.php @@ -44,7 +44,7 @@ class courserequestform extends course_request_form { * * @return void */ - function definition() { + public function definition() { global $CFG, $DB, $USER; $mform =& $this->_form; @@ -108,7 +108,7 @@ function definition() { $select = $mform->addElement('select', 'team', get_string('courserequest_teams', 'local_o365'), []); $mform->addHelpButton('team', 'courserequest_teams', 'local_o365'); - // Populate the select element based on the availability of unmatched teams + // Populate the select element based on the availability of unmatched teams. if (!empty($unmatchedteams)) { foreach ($unmatchedteams as $unmatchedteam) { $select->addOption($unmatchedteam['displayName'], $unmatchedteam['id']); @@ -118,7 +118,7 @@ function definition() { $mform->disabledIf('team', '', 'eq', ''); } - // Add client-side validation + // Add client-side validation. $mform->addRule('team', get_string('courserequest_emptyteams', 'local_o365'), 'required', null, 'client'); } } @@ -144,11 +144,11 @@ function definition() { /** * Custom validation function. * - * @param $data - * @param $files + * @param array $data + * @param array $files * @return array */ - public function validation($data, $files) : array { + public function validation($data, $files): array { global $DB; $errors = parent::validation($data, $files); diff --git a/classes/form/teamstabconfiguration.php b/classes/form/teamstabconfiguration.php index edf876021..0083f5b6b 100644 --- a/classes/form/teamstabconfiguration.php +++ b/classes/form/teamstabconfiguration.php @@ -52,7 +52,7 @@ public function definition() { if ($courseoptions) { // User can access at least one course, show tab name field and course selector. $mform->addElement('text', 'local_o365_teams_tab_name', get_string('tab_name', 'local_o365'), - array('onchange' => 'onTabNameChange()')); + ['onchange' => 'onTabNameChange()']); $mform->setType('local_o365_teams_tab_name', PARAM_TEXT); $tabname = get_config('local_o365', 'teams_moodle_tab_name'); if (!$tabname) { @@ -62,7 +62,7 @@ public function definition() { $courseselector = $mform->createElement('select', 'local_o365_teams_course', get_string('course_selector_label', 'local_o365'), - $courseoptions, array('onchange' => 'onCourseChange()')); + $courseoptions, ['onchange' => 'onCourseChange()']); $courseselector->setSize(100); $courseselector->setMultiple(true); @@ -84,7 +84,7 @@ public function definition() { private function get_course_options() { global $DB, $USER; - $courseoptions = array(); + $courseoptions = []; if (is_siteadmin($USER->id)) { $courses = $DB->get_records('course', ['visible' => 1]); diff --git a/classes/healthcheck/healthcheckinterface.php b/classes/healthcheck/healthcheckinterface.php index d23e8d028..67696189c 100644 --- a/classes/healthcheck/healthcheckinterface.php +++ b/classes/healthcheck/healthcheckinterface.php @@ -25,15 +25,25 @@ namespace local_o365\healthcheck; -defined('MOODLE_INTERNAL') || die(); - /** * Interface for all health checks. */ interface healthcheckinterface { + /** + * @var int SEVERITY_OK + */ const SEVERITY_OK = 0; + /** + * @var int SEVERITY_TRIVIAL + */ const SEVERITY_TRIVIAL = 1; + /** + * @var int SEVERITY_WARNING + */ const SEVERITY_WARNING = 2; + /** + * @var int SEVERITY_FATAL + */ const SEVERITY_FATAL = 3; /** diff --git a/classes/healthcheck/ratelimit.php b/classes/healthcheck/ratelimit.php index d56cf56e7..df8ba941c 100644 --- a/classes/healthcheck/ratelimit.php +++ b/classes/healthcheck/ratelimit.php @@ -25,8 +25,6 @@ namespace local_o365\healthcheck; -defined('MOODLE_INTERNAL') || die(); - /** * Checks current recorded rate limit */ diff --git a/classes/httpclient.php b/classes/httpclient.php index e67ab1535..d28396b0a 100644 --- a/classes/httpclient.php +++ b/classes/httpclient.php @@ -26,24 +26,26 @@ namespace local_o365; +use curl; use moodle_exception; +use stdClass; defined('MOODLE_INTERNAL') || die(); global $CFG; -require_once($CFG->dirroot.'/lib/filelib.php'); +require_once($CFG->dirroot . '/lib/filelib.php'); /** * An httpclientinterface implementation, using curl class as backend and adding patch and merge methods. */ -class httpclient extends \curl implements \local_o365\httpclientinterface { +class httpclient extends curl implements httpclientinterface { /** - * Generate a client tag. + * Generate client tag headers. * - * @return string A client tag. + * @return string[] */ - protected function get_clienttag_headers() { + protected function get_clienttag_headers(): array { global $CFG; $iid = sha1($CFG->wwwroot); @@ -55,9 +57,10 @@ protected function get_clienttag_headers() { $params = "lang=PHP; os={$ostype}; os_version={$osver}; arch={$arch}; version={$ver}; MoodleInstallId={$iid}"; $clienttag = "Moodle/{$mdlver} ({$params})"; + return [ - 'User-Agent: '.$clienttag, - 'X-ClientService-ClientTag: '.$clienttag, + 'User-Agent: ' . $clienttag, + 'X-ClientService-ClientTag: ' . $clienttag, ]; } @@ -66,10 +69,12 @@ protected function get_clienttag_headers() { * * @return string The current plugin version. */ - protected function get_plugin_version() { + protected function get_plugin_version(): string { global $CFG; - $plugin = new \stdClass; - require_once($CFG->dirroot.'/local/o365/version.php'); + + $plugin = new stdClass; + require_once($CFG->dirroot . '/local/o365/version.php'); + return $plugin->release; } @@ -78,8 +83,9 @@ protected function get_plugin_version() { * * @return string The current Moodle version. */ - protected function get_moodle_version() { + protected function get_moodle_version(): string { global $CFG; + return $CFG->release; } @@ -89,13 +95,13 @@ protected function get_moodle_version() { * @param string $url * @param array|string $params * @param array $options - * @return bool + * @return bool|string */ - public function patch($url, $params = '', $options = array()) { + public function patch($url, $params = '', $options = []): bool|string { $options['CURLOPT_CUSTOMREQUEST'] = 'PATCH'; if (is_array($params)) { - $this->_tmp_file_post_params = array(); + $this->_tmp_file_post_params = []; foreach ($params as $key => $value) { if ($value instanceof stored_file) { $value->add_to_curl_request($this, $key); @@ -109,6 +115,7 @@ public function patch($url, $params = '', $options = array()) { // Var $params is the raw post data. $options['CURLOPT_POSTFIELDS'] = $params; } + return $this->request($url, $options); } @@ -118,13 +125,13 @@ public function patch($url, $params = '', $options = array()) { * @param string $url * @param array|string $params * @param array $options - * @return bool + * @return bool|string */ - public function merge($url, $params = '', $options = array()) { + public function merge($url, $params = '', $options = []): bool|string { $options['CURLOPT_CUSTOMREQUEST'] = 'MERGE'; if (is_array($params)) { - $this->_tmp_file_post_params = array(); + $this->_tmp_file_post_params = []; foreach ($params as $key => $value) { if ($value instanceof stored_file) { $value->add_to_curl_request($this, $key); @@ -138,6 +145,7 @@ public function merge($url, $params = '', $options = array()) { // Var $params is the raw post data. $options['CURLOPT_POSTFIELDS'] = $params; } + return $this->request($url, $options); } @@ -147,9 +155,9 @@ public function merge($url, $params = '', $options = array()) { * @param string $url * @param array $params * @param array $options - * @return bool + * @return bool|string */ - public function put($url, $params = array(), $options = array()) { + public function put($url, $params = [], $options = []): bool|string { if (!isset($params['file'])) { throw new moodle_exception('errorhttpclientnofileinput', 'local_o365'); } @@ -168,12 +176,10 @@ public function put($url, $params = array(), $options = array()) { $options['CURLOPT_PUT'] = 1; $options['CURLOPT_INFILESIZE'] = $size; $options['CURLOPT_INFILE'] = $fp; - if (!isset($this->options['CURLOPT_USERPWD'])) { - $this->setopt(array('CURLOPT_USERPWD' => 'anonymous: noreply@moodle.org')); - } $ret = $this->request($url, $options); fclose($fp); + return $ret; } @@ -182,10 +188,11 @@ public function put($url, $params = array(), $options = array()) { * * @param string $url * @param array $options - * @return bool + * @return bool|string */ - public function download_file($url, $options = array()) { - $url = str_replace(array('+', ' '), '%20', $url); + public function download_file($url, $options = []): bool|string { + $url = str_replace(['+', ' '], '%20', $url); + return $this->request($url, $options); } } diff --git a/classes/httpclientinterface.php b/classes/httpclientinterface.php index 0037bb511..aa5b186bf 100644 --- a/classes/httpclientinterface.php +++ b/classes/httpclientinterface.php @@ -25,41 +25,39 @@ namespace local_o365; -defined('MOODLE_INTERNAL') || die(); - /** * HTTP Client Interface. */ interface httpclientinterface { - /** - * HTTP POST method - * - * @param string $url - * @param array|string $params - * @param array $options - * @return bool - */ - public function post($url, $params = '', $options = array()); + /** + * HTTP POST method + * + * @param string $url + * @param array|string $params + * @param array $options + * @return bool + */ + public function post($url, $params = '', $options = []); - /** - * HTTP GET method - * - * @param string $url - * @param array $params - * @param array $options - * @return bool - */ - public function get($url, $params = array(), $options = array()); + /** + * HTTP GET method + * + * @param string $url + * @param array $params + * @param array $options + * @return bool + */ + public function get($url, $params = [], $options = []); - /** - * HTTP PATCH method - * - * @param string $url - * @param array|string $params - * @param array $options - * @return bool - */ - public function patch($url, $params = '', $options = array()); + /** + * HTTP PATCH method + * + * @param string $url + * @param array|string $params + * @param array $options + * @return bool + */ + public function patch($url, $params = '', $options = []); /** * HTTP DELETE method @@ -69,7 +67,7 @@ public function patch($url, $params = '', $options = array()); * @param array $options * @return bool */ - public function delete($url, $param = array(), $options = array()); + public function delete($url, $param = [], $options = []); /** * Set HTTP Request Header @@ -78,8 +76,8 @@ public function delete($url, $param = array(), $options = array()); */ public function setheader($header); - /** - * Resets the HTTP Request headers (to prepare for the new request) - */ + /** + * Resets the HTTP Request headers (to prepare for the new request) + */ public function resetheader(); } diff --git a/classes/oauth2/apptoken.php b/classes/oauth2/apptoken.php index 0e29e25cb..32fdd531f 100644 --- a/classes/oauth2/apptoken.php +++ b/classes/oauth2/apptoken.php @@ -111,7 +111,7 @@ public static function get_app_token($tokenresource, \local_o365\oauth2\clientda $params = http_build_query($params, '', '&'); $header = [ 'Content-Type: application/x-www-form-urlencoded', - 'Content-Length: '.strlen($params) + 'Content-Length: ' . strlen($params), ]; $httpclient->resetheader(); $httpclient->setheader($header); @@ -133,7 +133,7 @@ public static function get_app_token($tokenresource, \local_o365\oauth2\clientda } $debuginfo = [ 'tokenresult' => $tokenresult, - 'resource' => $tokenresource + 'resource' => $tokenresource, ]; \local_o365\utils::debug($errmsg, __METHOD__, $debuginfo); return false; @@ -168,7 +168,7 @@ public function refresh() { 'scope' => $this->scope, 'token' => $this->token, 'expiry' => $this->expiry, - 'tokenresource' => $this->tokenresource + 'tokenresource' => $this->tokenresource, ]; $this->update_stored_token($existingtoken, $newtoken); } else { diff --git a/classes/oauth2/clientdata.php b/classes/oauth2/clientdata.php index c9721f760..4fe54a2cc 100644 --- a/classes/oauth2/clientdata.php +++ b/classes/oauth2/clientdata.php @@ -47,7 +47,7 @@ class clientdata { /** @var string The token endpoint URI. */ protected $tokenendpoint; - /** @var boolean The app-only token endpoint URI. */ + /** @var bool The app-only token endpoint URI. */ protected $apptokenendpoint = false; /** diff --git a/classes/oauth2/token.php b/classes/oauth2/token.php index 1d6b98b0f..961b9a81a 100644 --- a/classes/oauth2/token.php +++ b/classes/oauth2/token.php @@ -27,8 +27,6 @@ use moodle_exception; -defined('MOODLE_INTERNAL') || die(); - /** * Represents an oauth2 token. */ @@ -207,7 +205,7 @@ public static function jump_tokenresource(\local_o365\oauth2\token $token, $newt $header = [ 'Content-Type: application/x-www-form-urlencoded', - 'Content-Length: '.strlen($params) + 'Content-Length: ' . strlen($params), ]; $httpclient->resetheader(); $httpclient->setheader($header); @@ -260,7 +258,7 @@ public static function get_for_new_resource($userid, $tokenresource, \local_o365 $header = [ 'Content-Type: application/x-www-form-urlencoded', - 'Content-Length: '.strlen($params) + 'Content-Length: ' . strlen($params), ]; $httpclient->resetheader(); $httpclient->setheader($header); @@ -282,7 +280,7 @@ public static function get_for_new_resource($userid, $tokenresource, \local_o365 } $debuginfo = [ 'tokenresult' => $tokenresult, - 'resource' => $tokenresource + 'resource' => $tokenresource, ]; \local_o365\utils::debug($errmsg, __METHOD__, $debuginfo); } @@ -412,7 +410,7 @@ public function refresh() { $header = [ 'Content-Type: application/x-www-form-urlencoded', - 'Content-Length: '.strlen($params) + 'Content-Length: ' . strlen($params), ]; $this->httpclient->resetheader(); $this->httpclient->setheader($header); @@ -436,7 +434,7 @@ public function refresh() { 'token' => $this->token, 'expiry' => $this->expiry, 'refreshtoken' => $this->refreshtoken, - 'tokenresource' => $this->tokenresource + 'tokenresource' => $this->tokenresource, ]; $this->update_stored_token($existingtoken, $newtoken); } diff --git a/classes/obj/o365user.php b/classes/obj/o365user.php index f6f1ac829..5fe1b9eb6 100644 --- a/classes/obj/o365user.php +++ b/classes/obj/o365user.php @@ -25,10 +25,6 @@ namespace local_o365\obj; -use local_o365\utils; - -defined('MOODLE_INTERNAL') || die(); - /** * Class representing Microsoft 365 user information. */ diff --git a/classes/observers.php b/classes/observers.php index 9ac6a9d85..5b1f23915 100644 --- a/classes/observers.php +++ b/classes/observers.php @@ -81,7 +81,7 @@ class observers { * @param user_authed $event The triggered event. * @return bool Success/Failure. */ - public static function handle_oidc_user_authed(user_authed $event) : bool { + public static function handle_oidc_user_authed(user_authed $event): bool { require_login(); require_capability('moodle/site:config', context_system::instance()); @@ -146,6 +146,7 @@ public static function handle_oidc_user_authed(user_authed $event) : bool { } } catch (moodle_exception $e) { // Do nothing. + $domainsfetched = false; } if (!$domainsfetched) { @@ -172,7 +173,7 @@ public static function handle_oidc_user_authed(user_authed $event) : bool { * @param user_connected $event The triggered event. * @return bool Success/Failure. */ - public static function handle_oidc_user_connected(user_connected $event) : bool { + public static function handle_oidc_user_connected(user_connected $event): bool { global $DB; if (utils::is_connected() !== true) { @@ -269,7 +270,7 @@ public static function handle_oidc_user_connected(user_connected $event) : bool * @param user_created $event The triggered event. * @return bool Success/Failure. */ - public static function handle_user_created(user_created $event) : bool { + public static function handle_user_created(user_created $event): bool { global $DB; if (utils::is_connected() !== true) { @@ -297,7 +298,7 @@ public static function handle_user_created(user_created $event) : bool { * @param user_disconnected $event The triggered event. * @return bool Success/Failure. */ - public static function handle_oidc_user_disconnected(user_disconnected $event) : bool { + public static function handle_oidc_user_disconnected(user_disconnected $event): bool { global $DB; $eventdata = $event->get_data(); @@ -321,7 +322,7 @@ public static function handle_oidc_user_disconnected(user_disconnected $event) : * @param user_loggedin $event The triggered event. * @return bool Success/Failure. */ - public static function handle_oidc_user_loggedin(user_loggedin $event) : bool { + public static function handle_oidc_user_loggedin(user_loggedin $event): bool { if (utils::is_connected() !== true) { return false; } @@ -341,7 +342,7 @@ public static function handle_oidc_user_loggedin(user_loggedin $event) : bool { * @param int $userid The ID of the user we want more information about. * @return bool Success/Failure. */ - public static function get_additional_user_info(int $userid) : bool { + public static function get_additional_user_info(int $userid): bool { global $DB; try { @@ -417,7 +418,7 @@ public static function get_additional_user_info(int $userid) : bool { * @param user_enrolment_updated $event The triggered event. * @return bool Success/Failure. */ - public static function handle_user_enrolment_updated(user_enrolment_updated $event) : bool { + public static function handle_user_enrolment_updated(user_enrolment_updated $event): bool { // Do nothing if sync direction is Teams to Moodle. $courseusersyncdirection = get_config('local_o365', 'courseusersyncdirection'); if ($courseusersyncdirection == COURSE_USER_SYNC_DIRECTION_TEAMS_TO_MOODLE) { @@ -442,7 +443,7 @@ public static function handle_user_enrolment_updated(user_enrolment_updated $eve * @param enrol_instance_updated $event * @return bool */ - public static function handle_enrol_instance_updated(enrol_instance_updated $event) : bool { + public static function handle_enrol_instance_updated(enrol_instance_updated $event): bool { global $DB; // Do nothing if sync direction is Teams to Moodle. @@ -505,16 +506,16 @@ public static function handle_course_created(course_created $event): bool { $coursecreatedfromcustomcourserequest = false; - // Process course request approval + // Process course request approval. $courseid = $event->objectid; $course = get_course($courseid); $shortnametocheck = $course->shortname; - // First, try to get a record with an exact match on shortname + // First, try to get a record with an exact match on shortname. $customrequest = $DB->get_record('local_o365_course_request', ['courseshortname' => $shortnametocheck, 'requeststatus' => feature\courserequest\main::COURSE_REQUEST_STATUS_PENDING]); - // If no exact match, try removing the suffix _(number) + // If no exact match, try removing the suffix _(number). if (!$customrequest && preg_match('/^(.+)_(\d+)$/', $course->shortname, $matches)) { $shortnametocheck = $matches[1]; $customrequest = $DB->get_record('local_o365_course_request', ['courseshortname' => $shortnametocheck, @@ -551,7 +552,7 @@ public static function handle_course_created(course_created $event): bool { * * @return bool */ - public static function handle_course_restored(course_restored $event) : bool { + public static function handle_course_restored(course_restored $event): bool { if (utils::is_connected() !== true) { return false; } @@ -580,7 +581,7 @@ public static function handle_course_restored(course_restored $event) : bool { * @param course_updated $event The triggered event. * @return bool Success/Failure. */ - public static function handle_course_updated(course_updated $event) : bool { + public static function handle_course_updated(course_updated $event): bool { if (utils::is_connected() !== true) { return false; } @@ -614,7 +615,7 @@ public static function handle_course_updated(course_updated $event) : bool { * @param course_deleted $event The triggered event. * @return bool Success/Failure. */ - public static function handle_course_deleted(course_deleted $event) : bool { + public static function handle_course_deleted(course_deleted $event): bool { global $DB; if (utils::is_connected() !== true) { @@ -647,7 +648,7 @@ public static function handle_course_deleted(course_deleted $event) : bool { * @param role_assigned $event The triggered event. * @return bool Success/Failure. */ - public static function handle_role_assigned(role_assigned $event) : bool { + public static function handle_role_assigned(role_assigned $event): bool { // Do nothing if sync direction is Teams to Moodle. $courseusersyncdirection = get_config('local_o365', 'courseusersyncdirection'); if ($courseusersyncdirection == COURSE_USER_SYNC_DIRECTION_TEAMS_TO_MOODLE) { @@ -676,7 +677,7 @@ public static function handle_role_assigned(role_assigned $event) : bool { * @param role_unassigned $event The triggered event. * @return bool Success/Failure. */ - public static function handle_role_unassigned(role_unassigned $event) : bool { + public static function handle_role_unassigned(role_unassigned $event): bool { // Do nothing if sync direction is Teams to Moodle. $courseusersyncdirection = get_config('local_o365', 'courseusersyncdirection'); if ($courseusersyncdirection == COURSE_USER_SYNC_DIRECTION_TEAMS_TO_MOODLE) { @@ -705,7 +706,7 @@ public static function handle_role_unassigned(role_unassigned $event) : bool { * @param capability_assigned|capability_unassigned $event * @return bool */ - public static function handle_capability_change($event) { + public static function handle_capability_change($event): bool { $roleid = $event->objectid; // Resync owners and members in the groups connected to enabled Moodle courses. @@ -734,7 +735,7 @@ public static function handle_capability_change($event) { * @param role_deleted $event The triggered event. * @return bool Success/Failure. */ - public static function handle_role_deleted(role_deleted $event) : bool { + public static function handle_role_deleted(role_deleted $event): bool { if (utils::is_connected() !== true) { return false; } @@ -757,7 +758,7 @@ public static function handle_role_deleted(role_deleted $event) : bool { * @param user_deleted $event The triggered event. * @return bool Success/Failure. */ - public static function handle_user_deleted(user_deleted $event) : bool { + public static function handle_user_deleted(user_deleted $event): bool { global $DB; $userid = $event->objectid; $DB->delete_records('local_o365_token', ['user_id' => $userid]); @@ -774,7 +775,7 @@ public static function handle_user_deleted(user_deleted $event) : bool { * * @return bool */ - public static function handle_config_log_created(config_log_created $event) : bool { + public static function handle_config_log_created(config_log_created $event): bool { global $DB; $eventdata = $event->get_data(); @@ -843,7 +844,7 @@ public static function handle_config_log_created(config_log_created $event) : bo * * @return bool */ - public static function handle_cohort_deleted(cohort_deleted $event) : bool { + public static function handle_cohort_deleted(cohort_deleted $event): bool { global $DB; $cohortid = $event->objectid; diff --git a/classes/page/acp.php b/classes/page/acp.php index 1327618ac..7d41d1f20 100644 --- a/classes/page/acp.php +++ b/classes/page/acp.php @@ -120,7 +120,7 @@ public function mode_adminconsent() { $auth = new authcode; $auth->set_httpclient(new httpclient()); $stateparams = ['redirect' => '/admin/settings.php?section=local_o365', 'justauth' => true, 'forceflow' => 'authcode', - 'action' => 'adminconsent',]; + 'action' => 'adminconsent']; $idptype = get_config('auth_oidc', 'idptype'); if ($idptype == AUTH_OIDC_IDP_TYPE_MICROSOFT_IDENTITY_PLATFORM) { $auth->initiateadminconsentrequest($stateparams); @@ -135,7 +135,7 @@ public function mode_adminconsent() { * * @return bool */ - public function checktenantsetup() : bool { + public function checktenantsetup(): bool { $config = get_config('local_o365'); if (empty($config->entratenant)) { return false; @@ -304,7 +304,7 @@ public function mode_tenantsaddgo() { $auth = new authcode; $auth->set_httpclient(new httpclient()); $stateparams = ['redirect' => '/local/o365/acp.php?mode=tenantsadd', 'justauth' => true, 'forceflow' => 'authcode', - 'action' => 'addtenant', 'ignorerestrictions' => true,]; + 'action' => 'addtenant', 'ignorerestrictions' => true]; $idptype = get_config('auth_oidc', 'idptype'); if ($idptype == AUTH_OIDC_IDP_TYPE_MICROSOFT_IDENTITY_PLATFORM) { $auth->initiateadminconsentrequest($stateparams); @@ -598,7 +598,7 @@ public function mode_coursesynccustom() { $search = optional_param('search', '', PARAM_TEXT); $sortdir = strtolower(optional_param('sortdir', 'asc', PARAM_ALPHA)); - $headers = ['fullname' => get_string('fullnamecourse'), 'shortname' => get_string('shortnamecourse'),]; + $headers = ['fullname' => get_string('fullnamecourse'), 'shortname' => get_string('shortnamecourse')]; if (empty($sort) || !isset($headers[$sort])) { $sort = 'fullname'; } @@ -627,7 +627,7 @@ public function mode_coursesynccustom() { if ($sortdir == 'desc') { $sortdir = -1; } - $options = ['recursive' => true, 'sort' => [$sort => $sortdir], 'offset' => $limitfrom, 'limit' => $perpage,]; + $options = ['recursive' => true, 'sort' => [$sort => $sortdir], 'offset' => $limitfrom, 'limit' => $perpage]; $topcat = core_course_category::get(0); $courses = $topcat->get_courses($options); $totalcount = $topcat->get_courses_count($options); @@ -707,7 +707,7 @@ public function mode_coursesynccustom() { var local_o365_coursesync_all_set_feature = function(state) { if (confirm("' . get_string('acp_coursesynccustom_confirm_all_action', 'local_o365') . '")) { var enabled = (state == 1) ? true : false; - + // Send data to server $.ajax({ url: \'' . $allchangeendpoint->out(false) . '\', @@ -879,7 +879,7 @@ public function mode_teamconnections() { $search = optional_param('search', '', PARAM_TEXT); $sortdir = strtolower(optional_param('sortdir', 'asc', PARAM_ALPHA)); - $headers = ['fullname' => get_string('fullnamecourse'), 'shortname' => get_string('shortnamecourse'),]; + $headers = ['fullname' => get_string('fullnamecourse'), 'shortname' => get_string('shortnamecourse')]; if (empty($sort) || !isset($headers[$sort])) { $sort = 'fullname'; } @@ -908,7 +908,7 @@ public function mode_teamconnections() { if ($sortdir == 'desc') { $sortdir = -1; } - $options = ['recursive' => true, 'sort' => [$sort => $sortdir], 'offset' => $limitfrom, 'limit' => $perpage,]; + $options = ['recursive' => true, 'sort' => [$sort => $sortdir], 'offset' => $limitfrom, 'limit' => $perpage]; $topcat = core_course_category::get(0); $courses = $topcat->get_courses($options); $totalcount = $topcat->get_courses_count($options); @@ -1013,7 +1013,7 @@ public function mode_teamconnections() { $courseurl = new moodle_url('/course/view.php', ['id' => $course->id]); - $rowdata = [html_writer::link($courseurl, $course->fullname), $course->shortname, $existingconnection, $actionsfield,]; + $rowdata = [html_writer::link($courseurl, $course->fullname), $course->shortname, $existingconnection, $actionsfield]; $table->data[] = $rowdata; } @@ -1728,7 +1728,7 @@ public function mode_userconnections() { $searchurl = new moodle_url('/local/o365/acp.php', ['mode' => 'userconnections']); $filterfields = ['o365username' => 0, 'realname' => 0, 'username' => 0, 'idnumber' => 1, 'firstname' => 1, 'lastname' => 1, - 'email' => 1,]; + 'email' => 1]; $ufiltering = new filtering($filterfields, $searchurl); [$extrasql, $params] = $ufiltering->get_sql_filter(); [$o365usernamesql, $o365usernameparams] = $ufiltering->get_filter_o365username(); @@ -1751,7 +1751,7 @@ public function mode_userconnections() { * @return bool * @throws moodle_exception */ - public function mode_userconnections_resync() : bool { + public function mode_userconnections_resync(): bool { global $DB; $userid = required_param('userid', PARAM_INT); confirm_sesskey(); @@ -1829,14 +1829,14 @@ public function mode_userconnections_manualmatch() { } // Check if a o365 user object record already exists. - $params = ['moodleid' => $userid, 'type' => 'user',]; + $params = ['moodleid' => $userid, 'type' => 'user']; $existingobject = $DB->get_record('local_o365_objects', $params); if (!empty($existingobject) && $existingobject->o365name === $o365username) { throw new moodle_exception('acp_userconnections_manualmatch_error_muserconnected2', 'local_o365'); } $uselogin = (!empty($fromform->uselogin)) ? 1 : 0; - $matchrec = (object) ['muserid' => $userid, 'entraidupn' => $o365username, 'uselogin' => $uselogin,]; + $matchrec = (object) ['muserid' => $userid, 'entraidupn' => $o365username, 'uselogin' => $uselogin]; $DB->insert_record('local_o365_connections', $matchrec); redirect(new moodle_url('/local/o365/acp.php', ['mode' => 'userconnections'])); die(); @@ -1871,7 +1871,7 @@ public function mode_userconnections_unmatch() { $this->standard_header(); $message = get_string('acp_userconnections_table_unmatch_confirmmsg', 'local_o365', $user->username); $message .= '

'; - $urlparams = ['mode' => 'userconnections_unmatch', 'userid' => $userid, 'confirmed' => 1, 'sesskey' => sesskey(),]; + $urlparams = ['mode' => 'userconnections_unmatch', 'userid' => $userid, 'confirmed' => 1, 'sesskey' => sesskey()]; $url = new moodle_url('/local/o365/acp.php', $urlparams); $label = get_string('acp_userconnections_table_unmatch', 'local_o365'); $message .= html_writer::link($url, $label); @@ -1907,7 +1907,7 @@ public function mode_userconnections_disconnect() { $this->standard_header(); $message = get_string('acp_userconnections_table_disconnect_confirmmsg', 'local_o365', $user->username); $message .= '

'; - $urlparams = ['mode' => 'userconnections_disconnect', 'userid' => $userid, 'confirmed' => 1, 'sesskey' => sesskey(),]; + $urlparams = ['mode' => 'userconnections_disconnect', 'userid' => $userid, 'confirmed' => 1, 'sesskey' => sesskey()]; $url = new moodle_url('/local/o365/acp.php', $urlparams); $label = get_string('acp_userconnections_table_disconnect', 'local_o365'); $message .= html_writer::link($url, $label); diff --git a/classes/page/ajax.php b/classes/page/ajax.php index 1f94f79b0..c9ffc624f 100644 --- a/classes/page/ajax.php +++ b/classes/page/ajax.php @@ -36,8 +36,6 @@ use stdClass; use webservice; -defined('MOODLE_INTERNAL') || die(); - /** * Ajax page. */ @@ -361,7 +359,7 @@ public function mode_checkteamsmoodlesetup() { // Enable REST protocol. $webservice = 'rest'; $availablewebservices = core_component::get_plugin_list('webservice'); - $activewebservices = empty($CFG->webserviceprotocols) ? array() : explode(',', $CFG->webserviceprotocols); + $activewebservices = empty($CFG->webserviceprotocols) ? [] : explode(',', $CFG->webserviceprotocols); foreach ($activewebservices as $key => $active) { if (empty($availablewebservices[$active])) { unset($activewebservices[$key]); @@ -386,9 +384,7 @@ public function mode_checkteamsmoodlesetup() { if (!$o365service->enabled) { $o365service->enabled = 1; $webservicemanager->update_external_service($o365service); - $params = array( - 'objectid' => $o365service->id - ); + $params = ['objectid' => $o365service->id]; $event = \core\event\webservice_service_updated::create($params); $event->trigger(); $data->success[] = get_string('settings_notice_o365serviceenabled', 'local_o365'); diff --git a/classes/page/base.php b/classes/page/base.php index 5a1acf74c..1536022fa 100644 --- a/classes/page/base.php +++ b/classes/page/base.php @@ -25,8 +25,6 @@ namespace local_o365\page; -defined('MOODLE_INTERNAL') || die(); - /** * Basic page-style class handling page setup and page modes. */ diff --git a/classes/privacy/provider.php b/classes/privacy/provider.php index 9518ff996..ee9f7d42a 100644 --- a/classes/privacy/provider.php +++ b/classes/privacy/provider.php @@ -25,14 +25,22 @@ namespace local_o365\privacy; -use \core_privacy\local\metadata\collection; -use \core_privacy\local\request\contextlist; -use \core_privacy\local\request\approved_contextlist; -use \core_privacy\local\request\writer; +use context; +use core_privacy\local\metadata\collection; +use core_privacy\local\request\approved_userlist; +use core_privacy\local\request\contextlist; +use core_privacy\local\request\approved_contextlist; +use core_privacy\local\request\core_userlist_provider; +use core_privacy\local\request\userlist; +use core_privacy\local\request\writer; +use stdClass; defined('MOODLE_INTERNAL') || die(); -interface local_o365_userlist extends \core_privacy\local\request\core_userlist_provider { +/** + * Local userlist provider for local_o365. + */ +interface local_o365_userlist extends core_userlist_provider { }; /** @@ -44,12 +52,12 @@ class provider implements local_o365_userlist { /** - * Returns meta data about this system. + * Returns metadata about this system. * * @param collection $collection The initialised collection to add items to. * @return collection A listing of user data stored through this system. */ - public static function get_metadata(collection $collection) : collection { + public static function get_metadata(collection $collection): collection { $tables = [ 'local_o365_calidmap' => [ @@ -132,8 +140,8 @@ public static function get_metadata(collection $collection) : collection { * @param int $userid The user to search. * @return contextlist $contextlist The contextlist containing the list of contexts used in this plugin. */ - public static function get_contexts_for_userid(int $userid) : contextlist { - $contextlist = new \core_privacy\local\request\contextlist(); + public static function get_contexts_for_userid(int $userid): contextlist { + $contextlist = new contextlist(); if (self::user_has_o365_data($userid)) { $contextlist->add_user_context($userid); } @@ -143,10 +151,9 @@ public static function get_contexts_for_userid(int $userid) : contextlist { /** * Get the list of users who have data within a context. * - * @param \core_privacy\local\request\userlist $userlist The userlist containing the list of users who have data in this - * context/plugin combination. + * @param userlist $userlist The userlist containing the list of users who have data in this context/plugin combination. */ - public static function get_users_in_context(\core_privacy\local\request\userlist $userlist) { + public static function get_users_in_context(userlist $userlist) { $context = $userlist->get_context(); if (!$context instanceof \context_user) { return; @@ -173,7 +180,7 @@ public static function export_user_data(approved_contextlist $contextlist) { foreach ($records as $record) { writer::with_context($context)->export_data([ get_string('privacy:metadata:local_o365', 'local_o365'), - get_string('privacy:metadata:'.$table, 'local_o365') + get_string('privacy:metadata:'.$table, 'local_o365'), ], $record); } } @@ -184,7 +191,7 @@ public static function export_user_data(approved_contextlist $contextlist) { * * @param context $context The specific context to delete data for. */ - public static function delete_data_for_all_users_in_context(\context $context) { + public static function delete_data_for_all_users_in_context(context $context) { if ($context->contextlevel == CONTEXT_USER) { self::delete_user_data($context->instanceid); } @@ -209,10 +216,9 @@ public static function delete_data_for_user(approved_contextlist $contextlist) { /** * Delete multiple users within a single context. * - * @param \core_privacy\local\request\approved_userlist $userlist The approved context and user information to delete - * information for. + * @param approved_userlist $userlist The approved context and user information to delete information for. */ - public static function delete_data_for_users(\core_privacy\local\request\approved_userlist $userlist) { + public static function delete_data_for_users(approved_userlist $userlist) { $context = $userlist->get_context(); if ($context instanceof \context_user) { self::delete_user_data($context->instanceid); @@ -228,7 +234,7 @@ public static function delete_data_for_users(\core_privacy\local\request\approve private static function user_has_o365_data(int $userid) { global $DB; - $userdata = new \stdClass; + $userdata = new stdClass; $userdata->id = $userid; $user = $DB->get_record('user', ['id' => $userid]); if (!empty($user)) { @@ -252,7 +258,7 @@ private static function user_has_o365_data(int $userid) { private static function delete_user_data(int $userid) { global $DB; - $userdata = new \stdClass; + $userdata = new stdClass; $userdata->id = $userid; $user = $DB->get_record('user', ['id' => $userid]); if (!empty($user)) { @@ -267,10 +273,10 @@ private static function delete_user_data(int $userid) { /** * Get a map of database tables that contain user data, and the filters to get records for a user. * - * @param \stdClass $user The user to get the map for. + * @param stdClass $user The user to get the map for. * @return array The table user map. */ - protected static function get_table_user_map(\stdClass $user) : array { + protected static function get_table_user_map(stdClass $user): array { $tables = [ 'local_o365_calidmap' => ['userid' => $user->id], 'local_o365_calsub' => ['user_id' => $user->id], diff --git a/classes/rest/o365api.php b/classes/rest/o365api.php index 27b875f8f..38e5822bb 100644 --- a/classes/rest/o365api.php +++ b/classes/rest/o365api.php @@ -27,8 +27,6 @@ use moodle_exception; -defined('MOODLE_INTERNAL') || die(); - /** * Abstract base class for all o365 REST api classes. */ @@ -345,7 +343,7 @@ public function geturl($url, $options = []) { if ($tokenvalid !== true) { throw new moodle_exception('erroro365apiinvalidtoken', 'local_o365'); } - $header = ['Authorization: Bearer ' . $this->token->get_token(),]; + $header = ['Authorization: Bearer ' . $this->token->get_token()]; $this->httpclient->resetheader(); $this->httpclient->setheader($header); return $this->httpclient->get($url, '', $options); diff --git a/classes/rest/unified.php b/classes/rest/unified.php index aeb6643cd..7a42d20b2 100644 --- a/classes/rest/unified.php +++ b/classes/rest/unified.php @@ -53,7 +53,7 @@ class unified extends o365api { * * @return bool Whether the API client is configured. */ - public static function is_configured() : bool { + public static function is_configured(): bool { // Since legacy APIs are removed, unified is always configured. return true; } @@ -63,7 +63,7 @@ public static function is_configured() : bool { * * @return string The resource for oauth2 tokens. */ - public static function get_tokenresource() : string { + public static function get_tokenresource(): string { $oidcresource = get_config('auth_oidc', 'oidcresource'); if (!empty($oidcresource)) { return $oidcresource; @@ -92,7 +92,7 @@ public function get_apiuri() { * @param string $apimethod The API method being called. * @return string a simplified api area string. */ - protected function generate_apiarea(string $apimethod) : string { + protected function generate_apiarea(string $apimethod): string { $apimethod = explode('/', $apimethod); foreach ($apimethod as $apicomponent) { $validareas = ['applications', 'groups', 'calendars', 'events', 'trendingaround', 'users']; @@ -205,7 +205,7 @@ public function paginatedapicall($httpmethod, $apimethod, $odataqueries = [], $e if (!empty($result['value']) && is_array($result['value'])) { $content = array_merge($content, $result['value']); } - + if (isset($result['odata.nextLink'])) { $skiptoken = $this->extract_param_from_link($result['odata.nextLink'], $skipparam); } else if (isset($result['@odata.nextLink'])) { @@ -236,7 +236,7 @@ public function paginatedapicall($httpmethod, $apimethod, $odataqueries = [], $e * @return bool True if tenant succeeded, false if not. * @throws moodle_exception */ - public function test_tenant(string $tenant) : bool { + public function test_tenant(string $tenant): bool { if (!is_string($tenant)) { throw new moodle_exception('errortenantvaluenotstring', 'local_o365'); } @@ -254,7 +254,7 @@ public function test_tenant(string $tenant) : bool { * @return string * @throws moodle_exception */ - public function get_default_domain_name_in_tenant() : string { + public function get_default_domain_name_in_tenant(): string { $response = $this->apicall('get', '/domains'); $response = $this->process_apicall_response($response, ['value' => null]); foreach ($response['value'] as $domain) { @@ -301,7 +301,7 @@ public function get_all_domain_names_in_tenant() { * @return string The OneDrive URL string. * @throws moodle_exception */ - public function get_odburl() : string { + public function get_odburl(): string { $tenant = $this->get_default_domain_name_in_tenant(); $suffix = '.onmicrosoft.com'; $sufflen = strlen($suffix); @@ -319,7 +319,7 @@ public function get_odburl() : string { * @param clientdata $clientdata oAuth2 Credentials * @return bool Whether the received resource is valid or not. */ - public function validate_resource(string $tokenresource, clientdata $clientdata) : bool { + public function validate_resource(string $tokenresource, clientdata $clientdata): bool { $cleanresource = clean_param($tokenresource, PARAM_URL); if ($cleanresource !== $tokenresource) { return false; @@ -337,13 +337,13 @@ public function validate_resource(string $tokenresource, clientdata $clientdata) * @param string $appobjectid * @return string|null */ - public function assign_user(int $muserid, string $userobjectid, string $appobjectid) : ?string { + public function assign_user(int $muserid, string $userobjectid, string $appobjectid): ?string { global $DB; $record = $DB->get_record('local_o365_appassign', ['muserid' => $muserid]); if (empty($record) || $record->assigned == 0) { $roleid = '00000000-0000-0000-0000-000000000000'; $endpoint = '/users/' . $userobjectid . '/appRoleAssignments/'; - $params = ['id' => $roleid, 'resourceId' => $appobjectid, 'principalId' => $userobjectid,]; + $params = ['id' => $roleid, 'resourceId' => $appobjectid, 'principalId' => $userobjectid]; $response = $this->betaapicall('post', $endpoint, json_encode($params)); if (empty($record)) { $record = new stdClass(); @@ -365,7 +365,7 @@ public function assign_user(int $muserid, string $userobjectid, string $appobjec * @return array List of groups. * @throws moodle_exception */ - public function get_groups() : array { + public function get_groups(): array { $endpoint = '/groups'; return $this->paginatedapicall('get', $endpoint); @@ -380,7 +380,7 @@ public function get_groups() : array { * @return array|null * @throws moodle_exception */ - public function create_group(string $name, string $mailnickname = null, array $extra = null) : ?array { + public function create_group(string $name, ?string $mailnickname = null, ?array $extra = null): ?array { if (empty($mailnickname)) { $mailnickname = $name; } @@ -443,7 +443,7 @@ public function create_group(string $name, string $mailnickname = null, array $e * @return string Null string on success, json string on failure. * @throws moodle_exception */ - public function update_group(array $groupdata) : string { + public function update_group(array $groupdata): string { // Check for required parameters. if (empty($groupdata['id'])) { throw new moodle_exception('invalidgroupdata', 'local_o365'); @@ -474,7 +474,7 @@ public function update_group(array $groupdata) : string { * @return array Array of returned o365 group data. * @throws moodle_exception */ - public function get_group(string $objectid) : array { + public function get_group(string $objectid): array { $response = $this->apicall('get', '/groups/' . $objectid); $expectedparams = ['id' => null]; return $this->process_apicall_response($response, $expectedparams); @@ -484,10 +484,11 @@ public function get_group(string $objectid) : array { * Get group urls. * * @param string $objectid The object ID of the group. - * @return array Array of returned o365 group urls, null on no group data found. + * @return array|null Array of returned o365 group urls, null on no group data found. + * @throws \dml_exception * @throws moodle_exception */ - public function get_group_urls(string $objectid) : ?array { + public function get_group_urls(string $objectid): ?array { $group = $this->get_group($objectid); if (empty($group['mailNickname'])) { return null; @@ -508,12 +509,13 @@ public function get_group_urls(string $objectid) : ?array { ]; try { [$rawteam, $teamurl, $lockstatus] = $this->get_team($objectid); - if ($teamurl) { - $o365urls['team'] = $teamurl; - } } catch (moodle_exception $e) { - // Do nothing. + $teamurl = null; + } + if ($teamurl) { + $o365urls['team'] = $teamurl; } + return $o365urls; } @@ -550,10 +552,10 @@ public function get_team(string $objectid) { * Get a group by its displayName * * @param string $name The group name, - * @return array Array of group information, or null if group not found. + * @return array|null Array of group information, or null if group not found. * @throws moodle_exception */ - public function get_group_by_name(string $name) : ?array { + public function get_group_by_name(string $name): ?array { $response = $this->apicall('get', '/groups?$filter=displayName' . rawurlencode(' eq \'' . $name . '\'')); $expectedparams = ['value' => null]; $groups = $this->process_apicall_response($response, $expectedparams); @@ -580,7 +582,7 @@ public function delete_group(string $objectid) { * @return array Array of returned information. * @throws moodle_exception */ - public function list_deleted_groups() : array { + public function list_deleted_groups(): array { $endpoint = '/directory/deleteditems/Microsoft.Graph.Group'; return $this->paginatedapicall('get', $endpoint, [], ['value' => null], true); @@ -593,7 +595,7 @@ public function list_deleted_groups() : array { * @return array Array of returned information. * @throws moodle_exception */ - public function restore_deleted_group(string $objectid) : array { + public function restore_deleted_group(string $objectid): array { $response = $this->betaapicall('post', '/directory/deleteditems/' . $objectid . '/restore'); return $this->process_apicall_response($response); } @@ -605,7 +607,7 @@ public function restore_deleted_group(string $objectid) : array { * @return array Array of returned members. * @throws moodle_exception */ - public function get_group_members(string $groupobjectid) : array { + public function get_group_members(string $groupobjectid): array { $endpoint = '/groups/' . $groupobjectid . '/members'; return $this->paginatedapicall('get', $endpoint); @@ -615,10 +617,10 @@ public function get_group_members(string $groupobjectid) : array { * Get a list of group owners. * * @param string $groupobjectid The object ID of the group. - * @return array Array of returned owners. + * @return array|null Array of returned owners. * @throws moodle_exception */ - public function get_group_owners(string $groupobjectid) : ?array { + public function get_group_owners(string $groupobjectid): ?array { $endpoint = '/groups/' . $groupobjectid . '/owners'; return $this->paginatedapicall('get', $endpoint); @@ -633,7 +635,7 @@ public function get_group_owners(string $groupobjectid) : ?array { * @return array|null Returned response, or null if error. * @throws moodle_exception */ - public function get_group_files(string $groupid, string $parentid = '', string $skiptoken = '') : ?array { + public function get_group_files(string $groupid, string $parentid = '', string $skiptoken = ''): ?array { if (!empty($parentid) && $parentid !== '/') { $endpoint = "/groups/$groupid/drive/items/$parentid/children"; } else { @@ -664,7 +666,7 @@ public function get_group_files(string $groupid, string $parentid = '', string $ * @return array|null The file's content. * @throws moodle_exception */ - public function get_group_file_metadata(string $groupid, string $fileid) : ?array { + public function get_group_file_metadata(string $groupid, string $fileid): ?array { $response = $this->apicall('get', "/groups/$groupid/drive/items/$fileid"); $expectedparams = ['id' => null]; return $this->process_apicall_response($response, $expectedparams); @@ -678,7 +680,7 @@ public function get_group_file_metadata(string $groupid, string $fileid) : ?arra * @return string Sharing link url. * @throws moodle_exception */ - public function get_group_file_sharing_link(string $groupid, string $fileid) : string { + public function get_group_file_sharing_link(string $groupid, string $fileid): string { $params = ['type' => 'view', 'scope' => 'organization']; $apiresponse = $this->apicall('post', "/groups/$groupid/drive/items/$fileid/createLink", json_encode($params)); $response = $this->process_apicall_response($apiresponse); @@ -686,13 +688,13 @@ public function get_group_file_sharing_link(string $groupid, string $fileid) : s } /** - * Get a file's content by it's file id. + * Get a file's content by its file id. * * @param string $groupid * @param string $fileid The file's ID. * @return string The file's content. */ - public function get_group_file_by_id(string $groupid, string $fileid) : string { + public function get_group_file_by_id(string $groupid, string $fileid): string { return $this->apicall('get', "/groups/$groupid/drive/items/$fileid/content"); } @@ -733,7 +735,7 @@ public function add_owner_to_group_using_group_api(string $groupobjectid, string * @param string $memberobjectid The object ID of the item to remove (can be group object id or user object id). * @return bool */ - public function remove_member_from_group_using_group_api(string $groupobjectid, string $memberobjectid) : bool { + public function remove_member_from_group_using_group_api(string $groupobjectid, string $memberobjectid): bool { $endpoint = '/groups/' . $groupobjectid . '/members/' . $memberobjectid . '/$ref'; $this->betaapicall('delete', $endpoint); if ($this->check_expected_http_code(['204'])) { @@ -750,7 +752,7 @@ public function remove_member_from_group_using_group_api(string $groupobjectid, * @param string $ownerobjectid The object ID of the item to remove (can be group object id or user object id). * @return bool */ - public function remove_owner_from_group_using_group_api(string $groupobjectid, string $ownerobjectid) : bool { + public function remove_owner_from_group_using_group_api(string $groupobjectid, string $ownerobjectid): bool { $endpoint = '/groups/' . $groupobjectid . '/owners/' . $ownerobjectid . '/$ref'; $this->betaapicall('delete', $endpoint); if ($this->check_expected_http_code(['204'])) { @@ -768,7 +770,7 @@ public function remove_owner_from_group_using_group_api(string $groupobjectid, s * @return array|null * @throws moodle_exception */ - public function add_member_to_group_using_teams_api(string $groupobjectid, string $userobjectid) : ?array { + public function add_member_to_group_using_teams_api(string $groupobjectid, string $userobjectid): ?array { $endpoint = '/teams/' . $groupobjectid . '/members'; $data = [ '@odata.type' => '#microsoft.graph.aadUserConversationMember', @@ -788,7 +790,7 @@ public function add_member_to_group_using_teams_api(string $groupobjectid, strin * @return array|null * @throws moodle_exception */ - public function add_owner_to_group_using_teams_api(string $groupobjectid, string $userobjectid) : ?array { + public function add_owner_to_group_using_teams_api(string $groupobjectid, string $userobjectid): ?array { $endpoint = '/teams/' . $groupobjectid . '/members'; $data = [ '@odata.type' => '#microsoft.graph.aadUserConversationMember', @@ -808,7 +810,7 @@ public function add_owner_to_group_using_teams_api(string $groupobjectid, string * @return string * @throws moodle_exception */ - public function get_aad_user_conversation_member_id(string $groupobjectid, string $userobjectid) : string { + public function get_aad_user_conversation_member_id(string $groupobjectid, string $userobjectid): string { $endpoint = '/teams/' . $groupobjectid . '/members/?$filter=microsoft.graph.aadUserConversationMember/userId%20in%20("' . $userobjectid . '")'; @@ -832,7 +834,7 @@ public function get_aad_user_conversation_member_id(string $groupobjectid, strin * @throws moodle_exception */ public function remove_owner_and_member_from_group_using_teams_api(string $groupobjectid, - string $aaduserconversationmemberid) : ?array { + string $aaduserconversationmemberid): ?array { $endpoint = '/teams/' . $groupobjectid . '/members/' . $aaduserconversationmemberid; $response = $this->apicall('delete', $endpoint); @@ -850,7 +852,7 @@ public function remove_owner_and_member_from_group_using_teams_api(string $group * @throws moodle_exception */ public function create_group_file(string $groupid, string $filename, string $content, - string $contenttype = 'text/plain') : ?array { + string $contenttype = 'text/plain'): ?array { $filename = rawurlencode($filename); $endpoint = "/groups/$groupid/drive/root:/$filename:/content"; $fileresponse = $this->apicall('put', $endpoint, ['file' => $content], ['contenttype' => $contenttype]); @@ -864,12 +866,12 @@ public function create_group_file(string $groupid, string $filename, string $con * @param bool $guestuser if the fields are for a guest user. * @return array Array of user fields. */ - protected function get_default_user_fields(bool $guestuser = false) : array { + protected function get_default_user_fields(bool $guestuser = false): array { $defaultfields = ['id', 'userPrincipalName', 'displayName', 'givenName', 'surname', 'mail', 'streetAddress', 'city', 'postalCode', 'state', 'country', 'jobTitle', 'department', 'companyName', 'preferredLanguage', 'employeeId', 'businessPhones', 'faxNumber', 'mobilePhone', 'officeLocation', 'manager', 'teams', 'roles', 'groups', 'accountEnabled', - 'onPremisesExtensionAttributes', 'onPremisesSamAccountName',]; + 'onPremisesExtensionAttributes', 'onPremisesSamAccountName']; if (!$guestuser) { $defaultfields[] = 'preferredName'; } @@ -884,7 +886,7 @@ protected function get_default_user_fields(bool $guestuser = false) : array { * @return array|null Array of user information, or null if failure. * @throws moodle_exception */ - public function get_users($params = 'default') : ?array { + public function get_users($params = 'default'): ?array { $endpoint = "/users"; $odataqueries = []; @@ -912,7 +914,7 @@ public function get_users($params = 'default') : ?array { * @param string|null $deltatoken * @return array */ - public function get_users_delta($params, string $deltatoken = null) : array { + public function get_users_delta($params, ?string $deltatoken = null): array { $endpoint = "/users/delta"; $odataqueries = []; @@ -961,7 +963,7 @@ public function get_users_delta($params, string $deltatoken = null) : array { * @param string $userobjectid - user AD id * @return array|null */ - public function get_user_manager(string $userobjectid) : ?array { + public function get_user_manager(string $userobjectid): ?array { $endpoint = "users/$userobjectid/manager"; $response = $this->apicall('get', $endpoint); try { @@ -980,7 +982,7 @@ public function get_user_manager(string $userobjectid) : ?array { * @return array * @throws moodle_exception */ - public function get_user_groups(string $userobjectid) : array { + public function get_user_groups(string $userobjectid): array { $endpoint = "users/$userobjectid/transitiveMemberOf/microsoft.graph.group"; return $this->paginatedapicall('get', $endpoint); } @@ -992,7 +994,7 @@ public function get_user_groups(string $userobjectid) : array { * @return array * @throws moodle_exception */ - public function get_user_transitive_groups(string $userobjectid) : ?array { + public function get_user_transitive_groups(string $userobjectid): ?array { $endpoint = "users/$userobjectid/getMemberGroups"; return $this->paginatedapicall('post', $endpoint, [], ['value' => null], false, json_encode(['securityEnabledOnly' => false])); @@ -1005,7 +1007,7 @@ public function get_user_transitive_groups(string $userobjectid) : ?array { * @return array * @throws moodle_exception */ - public function get_user_teams(string $userobjectid) : array { + public function get_user_teams(string $userobjectid): array { $endpoint = "users/$userobjectid/joinedTeams"; return $this->paginatedapicall('get', $endpoint); } @@ -1018,7 +1020,7 @@ public function get_user_teams(string $userobjectid) : array { * @return array * @throws moodle_exception */ - public function get_user_objects(string $userobjectid, bool $securityenabledonly = true) : array { + public function get_user_objects(string $userobjectid, bool $securityenabledonly = true): array { $endpoint = "users/$userobjectid/getMemberObjects"; $data = ['securityEnabledOnly' => $securityenabledonly]; return $this->paginatedapicall('post', $endpoint, [], ['value' => null], false, json_encode($data)); @@ -1032,7 +1034,7 @@ public function get_user_objects(string $userobjectid, bool $securityenabledonly * @return array|null * @throws moodle_exception */ - public function get_directory_objects(array $ids, string $types = null) : ?array { + public function get_directory_objects(array $ids, ?string $types = null): ?array { $endpoint = "directoryObjects/getByIds"; $data = ['ids' => $ids]; if (!empty($types)) { @@ -1050,7 +1052,7 @@ public function get_directory_objects(array $ids, string $types = null) : ?array * @param string $param Parameter name. * @return string|null The extracted deltalink value, or null if none found. */ - protected function extract_param_from_link(string $link, string $param) : ?string { + protected function extract_param_from_link(string $link, string $param): ?string { $link = parse_url($link); if (isset($link['query'])) { $output = []; @@ -1068,7 +1070,7 @@ protected function extract_param_from_link(string $link, string $param) : ?strin * @return array Array of returned information. * @throws moodle_exception */ - public function list_deleted_users() : array { + public function list_deleted_users(): array { $endpoint = '/directory/deleteditems/Microsoft.Graph.User'; return $this->paginatedapicall('get', $endpoint, [], ['value' => null], true); @@ -1081,7 +1083,7 @@ public function list_deleted_users() : array { * @return array Array of user data. * @throws moodle_exception */ - public function get_user_by_upn(string $upn) : array { + public function get_user_by_upn(string $upn): array { $endpoint = '/users/' . rawurlencode($upn); $response = $this->apicall('get', $endpoint); $expectedparams = ['id' => null, 'userPrincipalName' => null]; @@ -1092,10 +1094,10 @@ public function get_user_by_upn(string $upn) : array { * Get a list of the user's o365 calendars. * * @param string $upn The user's userPrincipalName - * @return array Returned response + * @return array|null Returned response * @throws moodle_exception */ - public function get_calendars(string $upn) : ?array { + public function get_calendars(string $upn): ?array { $endpoint = '/users/' . $upn . '/calendars'; return $this->paginatedapicall('get', $endpoint, [], ['value' => null], false, '', [], '$skip'); @@ -1109,7 +1111,7 @@ public function get_calendars(string $upn) : ?array { * @return array|null Returned response, or null if error. * @throws moodle_exception */ - public function create_calendar(string $name, string $upn) : ?array { + public function create_calendar(string $name, string $upn): ?array { $calendardata = json_encode(['name' => $name]); $response = $this->apicall('post', '/users/' . $upn . '/calendars', $calendardata); $expectedparams = ['id' => null]; @@ -1132,7 +1134,7 @@ public function create_calendar(string $name, string $upn) : ?array { * @return array|null Returned response, or null if error. * @throws moodle_exception */ - public function update_calendar(string $calendearid, array $updated, string $upn) : ?array { + public function update_calendar(string $calendearid, array $updated, string $upn): ?array { if (empty($calendearid) || empty($updated)) { return []; } @@ -1161,7 +1163,7 @@ public function update_calendar(string $calendearid, array $updated, string $upn * @throws moodle_exception */ public function create_event(string $subject, string $body, int $starttime, int $endtime, array $attendees, array $other, - ?string $calendarid, string $upn) : ?array { + ?string $calendarid, string $upn): ?array { $eventdata = [ 'subject' => $subject, 'body' => [ @@ -1185,7 +1187,7 @@ public function create_event(string $subject, string $body, int $starttime, int 'Address' => $attendee->email, 'Name' => $attendee->firstname.' '.$attendee->lastname, ], - 'type' => 'Resource' + 'type' => 'Resource', ]; } $eventdata = array_merge($eventdata, $other); @@ -1238,7 +1240,7 @@ public function create_group_event(string $subject, string $body, int $starttime 'Address' => $attendee->email, 'Name' => $attendee->firstname.' '.$attendee->lastname, ], - 'type' => 'Resource' + 'type' => 'Resource', ]; } $eventdata = array_merge($eventdata, $other); @@ -1262,7 +1264,7 @@ public function create_group_event(string $subject, string $body, int $starttime * @return array Array of events. * @throws moodle_exception */ - public function get_events(string $calendarid, string $since, string $upn) : array { + public function get_events(string $calendarid, string $since, string $upn): array { core_date::set_default_server_timezone(); $endpoint = (!empty($calendarid)) ? '/users/' . $upn . '/calendars/' . $calendarid . '/events' : '/users/' . $upn . '/calendar/events'; @@ -1287,7 +1289,7 @@ public function get_events(string $calendarid, string $since, string $upn) : arr * @return array|null Returned response, or null if error. * @throws moodle_exception */ - public function update_event(string $outlookeventid, array $updated, string $upn) : ?array { + public function update_event(string $outlookeventid, array $updated, string $upn): ?array { if (empty($outlookeventid) || empty($updated)) { return []; } @@ -1300,10 +1302,10 @@ public function update_event(string $outlookeventid, array $updated, string $upn } if (!empty($updated['starttime'])) { $updateddata['start'] = - ['dateTime' => date('c', $updated['starttime']), 'timeZone' => date('T', $updated['starttime']),]; + ['dateTime' => date('c', $updated['starttime']), 'timeZone' => date('T', $updated['starttime'])]; } if (!empty($updated['endtime'])) { - $updateddata['end'] = ['dateTime' => date('c', $updated['endtime']), 'timeZone' => date('T', $updated['endtime']),]; + $updateddata['end'] = ['dateTime' => date('c', $updated['endtime']), 'timeZone' => date('T', $updated['endtime'])]; } if (!empty($updated['responseRequested'])) { $updateddata['responseRequested'] = $updated['responseRequested']; @@ -1312,7 +1314,7 @@ public function update_event(string $outlookeventid, array $updated, string $upn $updateddata['attendees'] = []; foreach ($updated['attendees'] as $attendee) { $updateddata['attendees'][] = - ['emailAddress' => ['address' => $attendee->email, 'name' => $attendee->firstname . ' ' . $attendee->lastname,], + ['emailAddress' => ['address' => $attendee->email, 'name' => $attendee->firstname . ' ' . $attendee->lastname], 'type' => 'resource']; } } @@ -1329,7 +1331,7 @@ public function update_event(string $outlookeventid, array $updated, string $upn * @param string $upn user's userPrincipalName * @return bool Success/Failure. */ - public function delete_event(string $outlookeventid, string $upn) : bool { + public function delete_event(string $outlookeventid, string $upn): bool { if (!empty($outlookeventid)) { $this->apicall('delete', '/users/' . $upn . '/events/' . $outlookeventid); } @@ -1348,7 +1350,7 @@ public function delete_event(string $outlookeventid, string $upn) : bool { * @throws moodle_exception */ public function create_file(string $parentid, string $filename, string $content, string $contenttype, - string $o365userid) : ?array { + string $o365userid): ?array { $filename = rawurlencode($filename); if (!empty($parentid)) { $endpoint = "/users/$o365userid/drive/items/$parentid:/$filename:/content"; @@ -1369,7 +1371,7 @@ public function create_file(string $parentid, string $filename, string $content, * @return array|null Returned response, or null if error. * @throws moodle_exception */ - public function get_user_files(string $parentid, string $o365userid, string $skiptoken = '') : ?array { + public function get_user_files(string $parentid, string $o365userid, string $skiptoken = ''): ?array { if (!empty($parentid) && $parentid !== '/') { $endpoint = "/users/$o365userid/drive/items/$parentid/children"; } else { @@ -1401,7 +1403,7 @@ public function get_user_files(string $parentid, string $o365userid, string $ski * @return array|null Returned response, or null if error. * @throws moodle_exception */ - public function get_trending_files(string $upn, string $skiptoken = '') : ?array { + public function get_trending_files(string $upn, string $skiptoken = ''): ?array { $endpoint = '/users/' . $upn . '/trendingAround'; $odataqueries = []; @@ -1428,7 +1430,7 @@ public function get_trending_files(string $upn, string $skiptoken = '') : ?array * @return array|null The file's content. * @throws moodle_exception */ - public function get_file_data(string $fileinfo) : ?array { + public function get_file_data(string $fileinfo): ?array { $response = $this->apicall('get', "/$fileinfo"); $expectedparams = ['id' => null]; return $this->process_apicall_response($response, $expectedparams); @@ -1440,7 +1442,7 @@ public function get_file_data(string $fileinfo) : ?array { * @param string $url The file's URL. * @return string The file's content. */ - public function get_file_by_url(string $url) : string { + public function get_file_by_url(string $url): string { return $this->httpclient->download_file($url); } @@ -1452,20 +1454,20 @@ public function get_file_by_url(string $url) : string { * @return array|null The file's metadata. * @throws moodle_exception */ - public function get_file_metadata(string $fileid, string $o365userid) : ?array { + public function get_file_metadata(string $fileid, string $o365userid): ?array { $response = $this->apicall('get', "/users/$o365userid/drive/items/$fileid"); $expectedparams = ['id' => null]; return $this->process_apicall_response($response, $expectedparams); } /** - * Get a file's content by it's file id. + * Get a file's content by its file id. * * @param string $fileid The file's ID. * @param string $o365userid user's Microsoft 365 account object ID * @return string The file's content. */ - public function get_file_by_id(string $fileid, string $o365userid) : string { + public function get_file_by_id(string $fileid, string $o365userid): string { return $this->apicall('get', "/users/$o365userid/drive/items/$fileid/content"); } @@ -1475,7 +1477,7 @@ public function get_file_by_id(string $fileid, string $o365userid) : string { * @return array|null Array of application information, or null if failure. * @throws moodle_exception */ - public function get_application_info() : ?array { + public function get_application_info(): ?array { $oidcconfig = get_config('auth_oidc'); $endpoint = '/applications/?$filter=appId%20eq%20\'' . $oidcconfig->clientid . '\''; $response = $this->betaapicall('get', $endpoint); @@ -1489,7 +1491,7 @@ public function get_application_info() : ?array { * @return array|null Array of application information, or null if failure. * @throws moodle_exception */ - public function get_application_serviceprincipal_info() : ?array { + public function get_application_serviceprincipal_info(): ?array { $oidcconfig = get_config('auth_oidc'); $endpoint = '/servicePrincipals/?$filter=appId%20eq%20\'' . $oidcconfig->clientid . '\''; $response = $this->betaapicall('get', $endpoint); @@ -1500,10 +1502,10 @@ public function get_application_serviceprincipal_info() : ?array { /** * Get the service principal object for the Microsoft Graph API. * - * @return array Array representing service principal object. + * @return array|null Array representing service principal object. * @throws moodle_exception */ - public function get_unified_api_serviceprincipal_info() : ?array { + public function get_unified_api_serviceprincipal_info(): ?array { static $response = null; if (empty($response)) { $graphperms = $this->get_required_permissions('graph'); @@ -1518,9 +1520,9 @@ public function get_unified_api_serviceprincipal_info() : ?array { /** * Get all available permissions for the Microsoft Graph API. * - * @return array Array of available permissions, include descriptions and keys. + * @return array|null Array of available permissions, include descriptions and keys. */ - public function get_available_permissions() : ?array { + public function get_available_permissions(): ?array { $svc = $this->get_unified_api_serviceprincipal_info(); if (empty($svc) || !is_array($svc)) { return null; @@ -1542,7 +1544,7 @@ public function get_available_permissions() : ?array { * * @return array Array of available app-only permissions, indexed by permission name. */ - public function get_graph_available_apponly_permissions() : array { + public function get_graph_available_apponly_permissions(): array { // Get list of permissions and associated IDs. $graphsp = $this->get_unified_api_serviceprincipal_info(); $graphsp = $graphsp['value'][0]; @@ -1559,7 +1561,7 @@ public function get_graph_available_apponly_permissions() : array { * @return array Array of current app-only permissions, indexed by permission name. * @throws moodle_exception */ - public function get_graph_current_apponly_permissions() : array { + public function get_graph_current_apponly_permissions(): array { // Get available permissions. $graphsp = $this->get_unified_api_serviceprincipal_info(); $graphsp = $graphsp['value'][0]; @@ -1603,7 +1605,7 @@ public function get_graph_current_apponly_permissions() : array { * @return array|null Array of application information, or null if failure. * @throws moodle_exception */ - public function get_permission_grants(string $resourceid = '') : ?array { + public function get_permission_grants(string $resourceid = ''): ?array { $appinfo = $this->get_application_serviceprincipal_info(); if (empty($appinfo) || !is_array($appinfo)) { return null; @@ -1623,9 +1625,9 @@ public function get_permission_grants(string $resourceid = '') : ?array { /** * Get currently assigned permissions for the Microsoft Graph API. * - * @return array Array of permission keys. + * @return array|null Array of permission keys. */ - public function get_unified_api_permissions() : ?array { + public function get_unified_api_permissions(): ?array { $apiinfo = $this->get_unified_api_serviceprincipal_info(); if (empty($apiinfo) || !is_array($apiinfo)) { return null; @@ -1649,7 +1651,7 @@ public function get_unified_api_permissions() : ?array { * * @return array Array of required delegated permissions. */ - public function get_graph_required_permissions() : array { + public function get_graph_required_permissions(): array { $allperms = $this->get_required_permissions(); if (isset($allperms['graph'])) { return $allperms['graph']['requiredDelegatedPermissionsUsingAppPermissions']; @@ -1663,7 +1665,7 @@ public function get_graph_required_permissions() : array { * * @return array Array of required application permissions. */ - public function get_graph_required_apponly_permissions() : array { + public function get_graph_required_apponly_permissions(): array { $allperms = $this->get_required_permissions(); if (isset($allperms['graph'])) { return $allperms['graph']['requiredAppPermissions']; @@ -1677,7 +1679,7 @@ public function get_graph_required_apponly_permissions() : array { * * @return array */ - public function check_graph_apponly_permissions() : array { + public function check_graph_apponly_permissions(): array { $this->token->refresh(); $requiredperms = $this->get_graph_required_apponly_permissions(); $currentperms = $this->get_graph_current_apponly_permissions(); @@ -1727,9 +1729,9 @@ public function check_graph_apponly_permissions() : array { /** * Check whether all required permissions are present. * - * @return array Array of missing permissions, permission key as array key, human-readable name as values. + * @return array|null Array of missing permissions, permission key as array key, human-readable name as values. */ - public function check_graph_delegated_permissions() : ?array { + public function check_graph_delegated_permissions(): ?array { $this->token->refresh(); $currentperms = $this->get_unified_api_permissions(); $requiredperms = $this->get_graph_required_permissions(); @@ -1821,7 +1823,7 @@ public function get_photo(string $user) { * @return string Readonly file url. * @throws moodle_exception */ - public function get_sharing_link(string $fileid, string $o365userid) : string { + public function get_sharing_link(string $fileid, string $o365userid): string { $params = ['type' => 'view', 'scope' => 'organization']; $apiresponse = $this->apicall('post', "/users/$o365userid/drive/items/$fileid/createLink", json_encode($params)); $response = $this->process_apicall_response($apiresponse); @@ -1836,7 +1838,7 @@ public function get_sharing_link(string $fileid, string $o365userid) : string { * @return array|null Array of user information, or null if failure. * @throws moodle_exception */ - public function get_user(string $oid, bool $guestuser = false) : ?array { + public function get_user(string $oid, bool $guestuser = false): ?array { $endpoint = "/users/$oid"; $odataqueries = []; @@ -1851,7 +1853,7 @@ public function get_user(string $oid, bool $guestuser = false) : ?array { try { $response = $this->apicall('get', $endpoint); - $expectedparams = ['@odata.context' => $context, 'id' => null, 'userPrincipalName' => null,]; + $expectedparams = ['@odata.context' => $context, 'id' => null, 'userPrincipalName' => null]; $result = $this->process_apicall_response($response, $expectedparams); if (!empty($result['id'])) { @@ -1871,9 +1873,9 @@ public function get_user(string $oid, bool $guestuser = false) : ?array { * @return bool * @throws moodle_exception */ - public function provision_app(string $groupobjectid, string $appid) : bool { + public function provision_app(string $groupobjectid, string $appid): bool { $endpoint = '/teams/' . $groupobjectid . '/installedApps'; - $data = ['teamsApp@odata.bind' => $this->get_apiuri() . '/beta/appCatalogs/teamsApps/' . $appid,]; + $data = ['teamsApp@odata.bind' => $this->get_apiuri() . '/beta/appCatalogs/teamsApps/' . $appid]; $this->betaapicall('post', $endpoint, json_encode($data)); // If the request was successful, it would return 201; otherwise, if the request failed with "duplicate", @@ -1892,7 +1894,7 @@ public function provision_app(string $groupobjectid, string $appid) : bool { * @return string|null * @throws moodle_exception */ - public function get_catalog_app_id(string $externalappid) : ?string { + public function get_catalog_app_id(string $externalappid): ?string { $moodleappid = null; $endpoint = '/appCatalogs/teamsApps?$filter=externalId' . rawurlencode(' eq \'' . $externalappid . '\''); @@ -1914,7 +1916,7 @@ public function get_catalog_app_id(string $externalappid) : ?string { * @return string|null * @throws moodle_exception */ - public function get_general_channel_id(string $groupobjectid) : ?string { + public function get_general_channel_id(string $groupobjectid): ?string { $generalchannelid = null; $endpoint = '/teams/' . $groupobjectid . '/channels?$filter=displayName' . rawurlencode(' eq \'General\''); @@ -1938,7 +1940,7 @@ public function get_general_channel_id(string $groupobjectid) : ?string { * @param array $tabconfiguration * @return string */ - public function add_tab_to_channel(string $groupobjectid, string $channelid, string $appid, array $tabconfiguration) : string { + public function add_tab_to_channel(string $groupobjectid, string $channelid, string $appid, array $tabconfiguration): string { $endpoint = '/teams/' . $groupobjectid . '/channels/' . $channelid . '/tabs'; $tabname = get_config('local_o365', 'teams_moodle_tab_name'); if (!$tabname) { @@ -1946,7 +1948,8 @@ public function add_tab_to_channel(string $groupobjectid, string $channelid, str } $requestparams = ['displayName' => $tabname, 'teamsApp@odata.bind' => $this->get_apiuri() . '/beta/appCatalogs/teamsApps/' . $appid, - 'configuration' => $tabconfiguration,]; + 'configuration' => $tabconfiguration, + ]; return $this->betaapicall('post', $endpoint, json_encode($requestparams)); } @@ -1958,10 +1961,10 @@ public function add_tab_to_channel(string $groupobjectid, string $channelid, str * @param string $displayname * @return string */ - public function update_team_name(string $objectid, string $displayname) : string { + public function update_team_name(string $objectid, string $displayname): string { $endpoint = '/teams/' . $objectid; - $teamdata = ['displayName' => $displayname,]; + $teamdata = ['displayName' => $displayname]; return $this->betaapicall('patch', $endpoint, json_encode($teamdata)); } @@ -2007,7 +2010,7 @@ public function get_timezone(string $upn) { * @return array|null * @throws moodle_exception */ - public function get_teams() : ?array { + public function get_teams(): ?array { $endpoint = '/groups'; $odataqueries = [ '$filter' => 'resourceProvisioningOptions/Any(x:x%20eq%20\'Team\')', @@ -2022,7 +2025,7 @@ public function get_teams() : ?array { * @return array * @throws moodle_exception */ - public function get_schools() : ?array { + public function get_schools(): ?array { $endpoint = '/education/schools'; return $this->paginatedapicall('get', $endpoint); @@ -2035,7 +2038,7 @@ public function get_schools() : ?array { * @return array * @throws moodle_exception */ - public function get_school_classes(string $schoolobjectid) : ?array { + public function get_school_classes(string $schoolobjectid): ?array { $endpoint = '/education/schools/' . $schoolobjectid . '/classes'; return $this->paginatedapicall('get', $endpoint); @@ -2048,7 +2051,7 @@ public function get_school_classes(string $schoolobjectid) : ?array { * @return array * @throws moodle_exception */ - public function get_school_class_teachers(string $classobjectid) : ?array { + public function get_school_class_teachers(string $classobjectid): ?array { $endpoint = '/education/classes/' . $classobjectid . '/teachers'; return $this->paginatedapicall('get', $endpoint); @@ -2061,7 +2064,7 @@ public function get_school_class_teachers(string $classobjectid) : ?array { * @return array|null * @throws moodle_exception */ - public function get_school_class_members(string $classobjectid) : ?array { + public function get_school_class_members(string $classobjectid): ?array { $endpoint = '/education/classes/' . $classobjectid . '/members'; return $this->paginatedapicall('get', $endpoint); @@ -2074,7 +2077,7 @@ public function get_school_class_members(string $classobjectid) : ?array { * @return array * @throws moodle_exception */ - public function get_school_users(string $schoolobjectid) : ?array { + public function get_school_users(string $schoolobjectid): ?array { $endpoint = '/education/schools/' . $schoolobjectid . '/users'; return $this->paginatedapicall('get', $endpoint); @@ -2085,7 +2088,7 @@ public function get_school_users(string $schoolobjectid) : ?array { * * @return bool */ - public function has_education_license() : bool { + public function has_education_license(): bool { $endpoint = '/organization'; $odataqueries = []; $odataqueries[] = '$select=assignedPlans'; @@ -2123,7 +2126,7 @@ public function has_education_license() : bool { * @throws moodle_exception */ public function create_educationclass_group(string $displayname, string $mailnickname, string $description, string $externalid, - string $externalname) : ?array { + string $externalname): ?array { if (!empty($mailnickname)) { $mailnickname = core_text::strtolower($mailnickname); $mailnickname = preg_replace('/[^a-z0-9_]+/iu', '', $mailnickname); @@ -2198,7 +2201,7 @@ public function update_education_group_with_lms_data(string $groupobjectid, arra * @return bool * @throws moodle_exception */ - public function add_chunk_users_to_group(string $groupobjectid, string $role, array $userobjectids) : bool { + public function add_chunk_users_to_group(string $groupobjectid, string $role, array $userobjectids): bool { $endpoint = '/groups/' . $groupobjectid; if ($role == 'owner') { @@ -2279,7 +2282,7 @@ public function create_standard_team_from_group(string $groupobjectid) { * @param array $expectedhttpcodes * @return bool */ - private function check_expected_http_code(array $expectedhttpcodes) : bool { + private function check_expected_http_code(array $expectedhttpcodes): bool { $httpclientinfo = (array) $this->httpclient->info; return in_array($httpclientinfo['http_code'], $expectedhttpcodes); diff --git a/classes/task/cohortsync.php b/classes/task/cohortsync.php index 847f81d17..46faf5ae3 100644 --- a/classes/task/cohortsync.php +++ b/classes/task/cohortsync.php @@ -25,8 +25,6 @@ namespace local_o365\task; -defined('MOODLE_INTERNAL') || die(); - use core\task\scheduled_task; use local_o365\feature\cohortsync\main; use local_o365\utils; @@ -40,7 +38,7 @@ class cohortsync extends scheduled_task { * * @return string */ - public function get_name() : string { + public function get_name(): string { return get_string('cohortsync_taskname', 'local_o365'); } @@ -49,7 +47,7 @@ public function get_name() : string { * * @return bool */ - public function execute() : bool { + public function execute(): bool { $graphclient = main::get_unified_api(__METHOD__); if (empty($graphclient)) { utils::mtrace("Failed to get Graph API client. Exiting.", 1); @@ -69,7 +67,7 @@ public function execute() : bool { * @param main $cohortsync * @return void */ - private function execute_sync(main $cohortsync) : void { + private function execute_sync(main $cohortsync): void { if ($cohortsync->update_groups_cache()) { utils::clean_up_not_found_groups(); } else { diff --git a/classes/task/coursemembershipsync.php b/classes/task/coursemembershipsync.php index 3a4875b46..fd45990ab 100644 --- a/classes/task/coursemembershipsync.php +++ b/classes/task/coursemembershipsync.php @@ -45,7 +45,7 @@ class coursemembershipsync extends scheduled_task { * * @return string */ - public function get_name() : string { + public function get_name(): string { return get_string('task_coursemembershipsync', 'local_o365'); } @@ -54,7 +54,7 @@ public function get_name() : string { * * @return bool */ - public function execute() : bool { + public function execute(): bool { // If the sync direction is Moodle to Teams, we don't want to sync the course membership. $courseusersyncdirection = get_config('local_o365', 'courseusersyncdirection'); if ($courseusersyncdirection == COURSE_USER_SYNC_DIRECTION_MOODLE_TO_TEAMS) { diff --git a/classes/task/coursesync.php b/classes/task/coursesync.php index 59b50271a..9387c27a0 100644 --- a/classes/task/coursesync.php +++ b/classes/task/coursesync.php @@ -25,16 +25,15 @@ namespace local_o365\task; +use core\task\scheduled_task; use local_o365\feature\coursesync\main; use local_o365\utils; use moodle_exception; -defined('MOODLE_INTERNAL') || die(); - /** * Create any needed groups in Microsoft 365. */ -class coursesync extends \core\task\scheduled_task { +class coursesync extends scheduled_task { /** * Get a descriptive name for this task (shown to admins). * diff --git a/classes/task/groupmembershipsync.php b/classes/task/groupmembershipsync.php index 4908c94ad..df5e6bd7a 100644 --- a/classes/task/groupmembershipsync.php +++ b/classes/task/groupmembershipsync.php @@ -67,4 +67,4 @@ public function execute() { } } } -} \ No newline at end of file +} diff --git a/classes/task/notifysecretexpiry.php b/classes/task/notifysecretexpiry.php index e33d364bc..ebf4b8b79 100644 --- a/classes/task/notifysecretexpiry.php +++ b/classes/task/notifysecretexpiry.php @@ -34,13 +34,16 @@ require_once($CFG->dirroot . '/auth/oidc/lib.php'); +/** + * Notify secret expiry task. + */ class notifysecretexpiry extends scheduled_task { /** * Return a descriptive name of the task. * * @return string */ - public function get_name() : string { + public function get_name(): string { return get_string('task_notifysecretexpiry', 'local_o365'); } @@ -49,7 +52,7 @@ public function get_name() : string { * * @return bool */ - public function execute() : bool { + public function execute(): bool { if (utils::is_connected() !== true) { return false; } @@ -139,7 +142,7 @@ public function execute() : bool { * * @return array */ - private function get_notification_recipient_emails_from_configuration() : array { + private function get_notification_recipient_emails_from_configuration(): array { $recipientemails = []; $recipientssetting = get_config('auth_oidc', 'secretexpiryrecipients'); @@ -161,7 +164,7 @@ private function get_notification_recipient_emails_from_configuration() : array * * @return array */ - private function get_notification_recipients() : array { + private function get_notification_recipients(): array { $notificationrecipients = []; $recipientemails = $this->get_notification_recipient_emails_from_configuration(); diff --git a/classes/task/processcourserequestapproval.php b/classes/task/processcourserequestapproval.php index 13936f7e7..093a99466 100644 --- a/classes/task/processcourserequestapproval.php +++ b/classes/task/processcourserequestapproval.php @@ -25,8 +25,6 @@ namespace local_o365\task; -defined('MOODLE_INTERNAL') || die(); - use core\task\adhoc_task; use local_o365\feature\courserequest\main; use local_o365\feature\coursesync\utils; @@ -40,10 +38,9 @@ class processcourserequestapproval extends adhoc_task { /** * Execute the task. * - * @return void - * @throws moodle_exception + * @return bool */ - public function execute() : bool { + public function execute(): bool { global $DB; $coursedata = $this->get_custom_data(); diff --git a/classes/task/processmatchqueue.php b/classes/task/processmatchqueue.php index 0c97f403d..0a65d25c1 100644 --- a/classes/task/processmatchqueue.php +++ b/classes/task/processmatchqueue.php @@ -51,7 +51,7 @@ class processmatchqueue extends scheduled_task { * * @return string */ - public function get_name() : string { + public function get_name(): string { return get_string('task_processmatchqueue', 'local_o365'); } @@ -79,7 +79,7 @@ public function get_api() { /** * Do the job. */ - public function execute() : bool { + public function execute(): bool { global $DB; if (utils::is_connected() !== true) { diff --git a/classes/task/updatecourserequeststatus.php b/classes/task/updatecourserequeststatus.php index fc14af504..57337cbcd 100644 --- a/classes/task/updatecourserequeststatus.php +++ b/classes/task/updatecourserequeststatus.php @@ -25,8 +25,6 @@ namespace local_o365\task; -defined('MOODLE_INTERNAL') || die(); - use core\task\scheduled_task; use local_o365\feature\courserequest\main; diff --git a/classes/task/usersync.php b/classes/task/usersync.php index 019635834..6195dce5e 100644 --- a/classes/task/usersync.php +++ b/classes/task/usersync.php @@ -31,8 +31,6 @@ use local_o365\utils; use moodle_exception; -defined('MOODLE_INTERNAL') || die(); - /** * Scheduled task to sync users with Microsoft Entra ID. */ @@ -178,7 +176,7 @@ public function execute() { if (!$suspensiontaskhour) { $suspensiontaskhour = 0; } - if(!$suspensiontaskminute) { + if (!$suspensiontaskminute) { $suspensiontaskminute = 0; } $currenthour = date('H'); @@ -186,13 +184,15 @@ public function execute() { if ($currenthour > $suspensiontaskhour) { $existingtaskusersynclastdeletesetting = get_config('local_o365', 'task_usersync_lastdelete'); if ($existingtaskusersynclastdeletesetting != date('Ymd')) { - add_to_config_log('task_usersync_lastdelete', $existingtaskusersynclastdeletesetting, date('Ymd'), 'local_o365'); + add_to_config_log('task_usersync_lastdelete', $existingtaskusersynclastdeletesetting, date('Ymd'), + 'local_o365'); } set_config('task_usersync_lastdelete', date('Ymd'), 'local_o365'); } else if (($currenthour == $suspensiontaskhour) && ($currentminute >= $suspensiontaskminute)) { $existingtaskusersynclastdeletesetting = get_config('local_o365', 'task_usersync_lastdelete'); if ($existingtaskusersynclastdeletesetting != date('Ymd')) { - add_to_config_log('task_usersync_lastdelete', $existingtaskusersynclastdeletesetting, date('Ymd'), 'local_o365'); + add_to_config_log('task_usersync_lastdelete', $existingtaskusersynclastdeletesetting, date('Ymd'), + 'local_o365'); } set_config('task_usersync_lastdelete', date('Ymd'), 'local_o365'); } else { @@ -276,7 +276,8 @@ protected function sync_users($usersync, $users) { case 'sub': case 'preferred_username': default: - $this->mtrace('Unsupported binding username claim: ' . $bindingusernameclaim . '. Falls back to userPrincepalName.'); + $this->mtrace('Unsupported binding username claim: ' . $bindingusernameclaim . + '. Falls back to userPrincepalName.'); $bindingusernameclaim = 'userPrincipalName'; } diff --git a/classes/tests/mockhttpclient.php b/classes/tests/mockhttpclient.php index 1275de8a5..1f2f1943e 100644 --- a/classes/tests/mockhttpclient.php +++ b/classes/tests/mockhttpclient.php @@ -27,8 +27,6 @@ use moodle_exception; -defined('MOODLE_INTERNAL') || die(); - /** * A mock HTTP client allowing set responses. * @@ -84,7 +82,7 @@ public function set_responses(array $responses) { * @return string The set response. * @throws moodle_exception If no responses are available. */ - protected function request($url, $options = array()) { + protected function request($url, $options = []) { $this->requests[] = [ 'url' => $url, 'options' => $options, diff --git a/classes/utils.php b/classes/utils.php index 53f4c474f..6bfe854ef 100644 --- a/classes/utils.php +++ b/classes/utils.php @@ -45,6 +45,9 @@ * General purpose utility class. */ class utils { + /** + * @var string RESOURCE_NOT_EXIST_ERROR + */ const RESOURCE_NOT_EXIST_ERROR = 'does not exist or one of its queried reference-property objects are not present'; /** @@ -76,7 +79,7 @@ public static function is_connected() { $clientdata = clientdata::instance_from_oidc(); $graphresource = unified::get_tokenresource(); try { - $token = utils::get_application_token($graphresource, $clientdata, $httpclient); + $token = static::get_application_token($graphresource, $clientdata, $httpclient); if ($token) { return true; } @@ -158,7 +161,7 @@ public static function is_configured_apponlyaccess() { * * @return bool Whether app-only access is active. */ - public static function is_active_apponlyaccess() : bool { + public static function is_active_apponlyaccess(): bool { return static::is_configured_apponlyaccess() === true && unified::is_configured() === true; } @@ -250,9 +253,9 @@ public static function tostring($val) { $valinfo['errorcode'] = $val->errorcode; $valinfo['module'] = $val->module; } - return print_r($valinfo, true); + return json_encode($valinfo, JSON_PRETTY_PRINT); } else { - return print_r($val, true); + return json_encode($val, JSON_PRETTY_PRINT); } } @@ -287,7 +290,7 @@ public static function debug($message, $where = '', $debugdata = null) { * @return unified A constructed unified API client, or throw an error. * @throws moodle_exception */ - public static function get_api(int $userid = null) { + public static function get_api(?int $userid = null) { $tokenresource = unified::get_tokenresource(); $clientdata = clientdata::instance_from_oidc(); $httpclient = new httpclient(); @@ -466,10 +469,10 @@ public static function disableadditionaltenant(string $tenantid) { /** * Delete an additional tenant from the legacy additional tenant settings. * - * @param $tenant + * @param string $tenant * @return bool|void */ - public static function deletelegacyadditionaltenant($tenant) { + public static function deletelegacyadditionaltenant(string $tenant) { $o365config = get_config('local_o365'); if (empty($o365config->legacymultitenants)) { return true; @@ -493,7 +496,7 @@ public static function deletelegacyadditionaltenant($tenant) { * @param int $userid The ID of the user. * @return string The tenant for the user. Empty string unless different from the host tenant. */ - public static function get_tenant_for_user(int $userid) : string { + public static function get_tenant_for_user(int $userid): string { try { $clientdata = clientdata::instance_from_oidc(); $httpclient = new httpclient(); @@ -506,7 +509,7 @@ public static function get_tenant_for_user(int $userid) : string { return ($tenant != get_config('local_o365', 'entratenant')) ? $tenant : ''; } } catch (moodle_exception $e) { - // Do nothing. + return ''; } return ''; } @@ -530,7 +533,7 @@ public static function get_odburl_for_user($userid) { return ($tenant != get_config('local_o365', 'odburl')) ? $tenant : ''; } } catch (moodle_exception $e) { - // Do nothing. + return ''; } return ''; } @@ -554,7 +557,7 @@ public static function get_microsoft_account_oid_by_user_id(int $userid) { * * @return array */ - public static function get_connected_users() : array { + public static function get_connected_users(): array { global $DB; $connectedusers = []; @@ -574,7 +577,7 @@ public static function get_connected_users() : array { * @param int $baselevel * @return bool */ - public static function update_groups_cache(unified $graphclient, int $baselevel = 0) : bool { + public static function update_groups_cache(unified $graphclient, int $baselevel = 0): bool { global $DB; static::mtrace("Update groups cache.", $baselevel); @@ -646,7 +649,7 @@ public static function update_groups_cache(unified $graphclient, int $baselevel * @param int $baselevel * @return void */ - public static function clean_up_not_found_groups(int $baselevel = 1) : void { + public static function clean_up_not_found_groups(int $baselevel = 1): void { global $DB; static::mtrace('Clean up non-existing groups from database', $baselevel); @@ -677,7 +680,7 @@ public static function clean_up_not_found_groups(int $baselevel = 1) : void { * @param string $eol * @return void */ - public static function mtrace(string $message, int $level = 0, string $eol = "\n") { + public static function mtrace(string $message, int $level = 0, string $eol = "\n"): void { if ($level) { $message = str_repeat('...', $level) . ' ' . $message; } @@ -690,7 +693,7 @@ public static function mtrace(string $message, int $level = 0, string $eol = "\n * @param string $errormessage * @return string|null */ - public static function extract_guid_from_error_message(string $errormessage) : ?string { + public static function extract_guid_from_error_message(string $errormessage): ?string { $pattern = '/[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}/'; preg_match($pattern, $errormessage, $matches); return $matches[0] ?? null; diff --git a/classes/webservices/create_onenoteassignment.php b/classes/webservices/create_onenoteassignment.php index de1de3906..9cb4111d9 100644 --- a/classes/webservices/create_onenoteassignment.php +++ b/classes/webservices/create_onenoteassignment.php @@ -27,6 +27,7 @@ defined('MOODLE_INTERNAL') || die(); +use context_course; use core_external\external_api; use core_external\external_function_parameters; use core_external\external_single_structure; @@ -34,7 +35,7 @@ global $CFG; -require_once($CFG->dirroot.'/course/modlib.php'); +require_once($CFG->dirroot . '/course/modlib.php'); /** * Create assignment API class. @@ -54,7 +55,7 @@ public static function assignment_create_parameters() { 'section' => new external_value(PARAM_INT, 'section', VALUE_DEFAULT, 0), 'visible' => new external_value(PARAM_BOOL, 'visible', VALUE_DEFAULT, false), 'duedate' => new external_value(PARAM_INT, 'duedate', VALUE_DEFAULT, 0), - ]) + ]), ]); } @@ -65,12 +66,12 @@ public static function assignment_create_parameters() { * @return array An array of parameters, if successful. */ public static function assignment_create($data) { - global $DB, $CFG; + global $CFG; $params = self::validate_parameters(self::assignment_create_parameters(), ['data' => $data]); $params = $params['data']; - $context = \context_course::instance($params['course']); + $context = context_course::instance($params['course']); self::validate_context($context); $defaults = [ @@ -81,7 +82,6 @@ public static function assignment_create($data) { 'duedate' => 0, 'cutoffdate' => 0, 'allowsubmissionsfromdate' => 0, - 'grade' => 0, 'gradingduedate' => 0, 'completionsubmit' => 0, 'teamsubmission' => 0, @@ -98,8 +98,8 @@ public static function assignment_create($data) { 'modulename' => 'assign', 'course' => $course->id, 'section' => $params['section'], - 'visible' => (int)$params['visible'], - 'duedate' => (int)$params['duedate'], + 'visible' => (int) $params['visible'], + 'duedate' => (int) $params['duedate'], 'name' => $params['name'], 'cmidnumber' => '', 'introeditor' => ['text' => $params['intro'], 'format' => FORMAT_HTML, 'itemid' => null], @@ -109,9 +109,10 @@ public static function assignment_create($data) { ]; $modinfo = array_merge($defaults, $modinfo); - $modinfo = create_module((object)$modinfo, $course); + $modinfo = create_module((object) $modinfo, $course); + + $modinfo = utils::get_assignment_return_info($modinfo->coursemodule, $modinfo->course); - $modinfo = \local_o365\webservices\utils::get_assignment_return_info($modinfo->coursemodule, $modinfo->course); return ['data' => [$modinfo]]; } @@ -121,6 +122,6 @@ public static function assignment_create($data) { * @return external_single_structure Object describing return parameters for this webservice method. */ public static function assignment_create_returns() { - return \local_o365\webservices\utils::get_assignment_return_info_schema(); + return utils::get_assignment_return_info_schema(); } } diff --git a/classes/webservices/delete_onenoteassignment.php b/classes/webservices/delete_onenoteassignment.php index 7e7ebef6d..b13135d43 100644 --- a/classes/webservices/delete_onenoteassignment.php +++ b/classes/webservices/delete_onenoteassignment.php @@ -27,6 +27,7 @@ defined('MOODLE_INTERNAL') || die(); +use context_course; use core_external\external_api; use core_external\external_function_parameters; use core_external\external_single_structure; @@ -34,7 +35,7 @@ global $CFG; -require_once($CFG->dirroot.'/course/modlib.php'); +require_once($CFG->dirroot . '/course/modlib.php'); /** * Delete assignment API class. @@ -50,7 +51,7 @@ public static function assignment_delete_parameters() { 'data' => new external_single_structure([ 'coursemodule' => new external_value(PARAM_INT, 'course module id'), 'course' => new external_value(PARAM_INT, 'course id'), - ]) + ]), ]); } @@ -66,14 +67,15 @@ public static function assignment_delete($data) { $params = self::validate_parameters(self::assignment_delete_parameters(), ['data' => $data]); $params = $params['data']; - list($course, $module, $assign) = \local_o365\webservices\utils::verify_assignment($params['coursemodule'], + [$course, $module, $assign] = utils::verify_assignment($params['coursemodule'], $params['course']); - $context = \context_course::instance($params['course']); + $context = context_course::instance($params['course']); self::validate_context($context); // Course_delete_module will throw exception if error, so we can return true b/c if we get there it was successful. course_delete_module($module->id); + return ['result' => true]; } @@ -86,6 +88,7 @@ public static function assignment_delete_returns() { $params = [ 'result' => new external_value(PARAM_BOOL, 'success/failure'), ]; + return new external_single_structure($params); } } diff --git a/classes/webservices/exception/assignnotfound.php b/classes/webservices/exception/assignnotfound.php index 353ebf306..249709ab1 100644 --- a/classes/webservices/exception/assignnotfound.php +++ b/classes/webservices/exception/assignnotfound.php @@ -25,12 +25,12 @@ namespace local_o365\webservices\exception; -defined('MOODLE_INTERNAL') || die(); +use moodle_exception; /** * Exception thrown when an associated assignment record is not found for a given course module. */ -class assignnotfound extends \moodle_exception { +class assignnotfound extends moodle_exception { /** * Constructor. * diff --git a/classes/webservices/exception/couldnotsavegrade.php b/classes/webservices/exception/couldnotsavegrade.php index dd6ff24c4..268d1864b 100644 --- a/classes/webservices/exception/couldnotsavegrade.php +++ b/classes/webservices/exception/couldnotsavegrade.php @@ -25,12 +25,12 @@ namespace local_o365\webservices\exception; -defined('MOODLE_INTERNAL') || die(); +use moodle_exception; /** * Exception thrown when a grade could not be saved in local_o365_update_grade. */ -class couldnotsavegrade extends \moodle_exception { +class couldnotsavegrade extends moodle_exception { /** * Constructor. * diff --git a/classes/webservices/exception/invalidassignment.php b/classes/webservices/exception/invalidassignment.php index 5864d35ff..f62fe6cd7 100644 --- a/classes/webservices/exception/invalidassignment.php +++ b/classes/webservices/exception/invalidassignment.php @@ -25,12 +25,12 @@ namespace local_o365\webservices\exception; -defined('MOODLE_INTERNAL') || die(); +use moodle_exception; /** * Exception thrown when a module is called that is not a OneNote assignment. */ -class invalidassignment extends \moodle_exception { +class invalidassignment extends moodle_exception { /** * Constructor. * diff --git a/classes/webservices/exception/modulenotfound.php b/classes/webservices/exception/modulenotfound.php index c6d9e045f..c6361daf9 100644 --- a/classes/webservices/exception/modulenotfound.php +++ b/classes/webservices/exception/modulenotfound.php @@ -25,12 +25,12 @@ namespace local_o365\webservices\exception; -defined('MOODLE_INTERNAL') || die(); +use moodle_exception; /** * Exception thrown when a module that does not exist is called. */ -class modulenotfound extends \moodle_exception { +class modulenotfound extends moodle_exception { /** * Constructor. * diff --git a/classes/webservices/exception/sectionnotfound.php b/classes/webservices/exception/sectionnotfound.php index aa493ef69..9aeda353d 100644 --- a/classes/webservices/exception/sectionnotfound.php +++ b/classes/webservices/exception/sectionnotfound.php @@ -25,12 +25,12 @@ namespace local_o365\webservices\exception; -defined('MOODLE_INTERNAL') || die(); +use moodle_exception; /** * Exception thrown when a course section that does not exist is used to update an assignment. */ -class sectionnotfound extends \moodle_exception { +class sectionnotfound extends moodle_exception { /** * Constructor. * diff --git a/classes/webservices/read_assignments.php b/classes/webservices/read_assignments.php index 0a546d028..265b5cb0a 100644 --- a/classes/webservices/read_assignments.php +++ b/classes/webservices/read_assignments.php @@ -25,6 +25,9 @@ namespace local_o365\webservices; +use assign; +use context_course; +use context_module; use moodle_exception; defined('MOODLE_INTERNAL') || die(); @@ -36,12 +39,13 @@ use core_external\external_single_structure; use core_external\external_value; use core_external\external_warnings; +use moodle_url; global $CFG; -require_once($CFG->dirroot.'/course/modlib.php'); -require_once($CFG->dirroot.'/user/externallib.php'); -require_once($CFG->dirroot.'/mod/assign/locallib.php'); +require_once($CFG->dirroot . '/course/modlib.php'); +require_once($CFG->dirroot . '/user/externallib.php'); +require_once($CFG->dirroot . '/mod/assign/locallib.php'); /** * Get a list of assignments in one or more courses. @@ -68,7 +72,7 @@ public static function assignments_read_parameters() { VALUE_DEFAULT, [] ), - 'capabilities' => new external_multiple_structure( + 'capabilities' => new external_multiple_structure( new external_value(PARAM_CAPABILITY, 'capability'), 'list of capabilities used to filter courses', VALUE_DEFAULT, @@ -80,7 +84,7 @@ public static function assignments_read_parameters() { 'courseids to not be empty.', VALUE_DEFAULT, false - ) + ), ]); } @@ -94,26 +98,26 @@ public static function assignments_read_parameters() { * @param array $capabilities An array of additional capability checks you wish to be made on the course context. * @param bool $includenotenrolledcourses Wheter to return courses that the user can see even if is not enroled in. * This requires the parameter $courseids to not be empty. - * @return An array of courses and warnings. + * @return array An array of courses and warnings. * @since Moodle 2.4 */ public static function assignments_read($courseids = [], $assignmentids = [], $capabilities = [], $includenotenrolledcourses = false) { - global $USER, $DB, $CFG; + global $USER, $DB; $params = self::validate_parameters( self::assignments_read_parameters(), - array( + [ 'courseids' => $courseids, 'assignmentids' => $assignmentids, 'capabilities' => $capabilities, - 'includenotenrolledcourses' => $includenotenrolledcourses - ) + 'includenotenrolledcourses' => $includenotenrolledcourses, + ] ); $assignmentids = array_flip($params['assignmentids']); - $warnings = array(); - $courses = array(); + $warnings = []; + $courses = []; $fields = 'sortorder,shortname,fullname,timemodified'; // If the courseids list is empty, we return only the courses where the user is enrolled in. @@ -131,12 +135,12 @@ public static function assignments_read($courseids = [], $assignmentids = [], $c foreach ($params['courseids'] as $courseid) { if (!in_array($courseid, $mycourseids)) { unset($courses[$courseid]); - $warnings[] = array( + $warnings[] = [ 'item' => 'course', 'itemid' => $courseid, 'warningcode' => '2', - 'message' => 'User is not enrolled or does not have requested capability' - ); + 'message' => 'User is not enrolled or does not have requested capability', + ]; } else { $courses[$courseid] = $mycourses[$courseid]; } @@ -147,7 +151,7 @@ public static function assignments_read($courseids = [], $assignmentids = [], $c foreach ($courseids as $cid) { try { - $context = \context_course::instance($cid); + $context = context_course::instance($cid); self::validate_context($context); // Check if this course was already loaded (by enrol_get_users_courses). @@ -156,12 +160,12 @@ public static function assignments_read($courseids = [], $assignmentids = [], $c } } catch (moodle_exception $e) { unset($courses[$cid]); - $warnings[] = array( + $warnings[] = [ 'item' => 'course', 'itemid' => $cid, 'warningcode' => '1', - 'message' => 'No access rights in course context ' . $e->getMessage() - ); + 'message' => 'No access rights in course context ' . $e->getMessage(), + ]; continue; } if (count($params['capabilities']) > 0 && !has_all_capabilities($params['capabilities'], $context)) { @@ -169,34 +173,34 @@ public static function assignments_read($courseids = [], $assignmentids = [], $c } } $extrafields = 'm.id as assignmentid, ' . - 'm.course, ' . - 'm.nosubmissions, ' . - 'm.submissiondrafts, ' . - 'm.sendnotifications, '. - 'm.sendlatenotifications, ' . - 'm.sendstudentnotifications, ' . - 'm.duedate, ' . - 'm.allowsubmissionsfromdate, '. - 'm.grade, ' . - 'm.timemodified, '. - 'm.completionsubmit, ' . - 'm.cutoffdate, ' . - 'm.teamsubmission, ' . - 'm.requireallteammemberssubmit, '. - 'm.teamsubmissiongroupingid, ' . - 'm.blindmarking, ' . - 'm.revealidentities, ' . - 'm.attemptreopenmethod, '. - 'm.maxattempts, ' . - 'm.markingworkflow, ' . - 'm.markingallocation, ' . - 'm.requiresubmissionstatement, '. - 'm.intro, '. - 'm.introformat'; - $coursearray = array(); + 'm.course, ' . + 'm.nosubmissions, ' . + 'm.submissiondrafts, ' . + 'm.sendnotifications, ' . + 'm.sendlatenotifications, ' . + 'm.sendstudentnotifications, ' . + 'm.duedate, ' . + 'm.allowsubmissionsfromdate, ' . + 'm.grade, ' . + 'm.timemodified, ' . + 'm.completionsubmit, ' . + 'm.cutoffdate, ' . + 'm.teamsubmission, ' . + 'm.requireallteammemberssubmit, ' . + 'm.teamsubmissiongroupingid, ' . + 'm.blindmarking, ' . + 'm.revealidentities, ' . + 'm.attemptreopenmethod, ' . + 'm.maxattempts, ' . + 'm.markingworkflow, ' . + 'm.markingallocation, ' . + 'm.requiresubmissionstatement, ' . + 'm.intro, ' . + 'm.introformat'; + $coursearray = []; foreach ($courses as $id => $course) { - $assignmentarray = array(); + $assignmentarray = []; // Get a list of assignments for the course. if ($modules = get_coursemodules_in_course('assign', $courses[$id]->id, $extrafields)) { foreach ($modules as $module) { @@ -206,34 +210,34 @@ public static function assignments_read($courseids = [], $assignmentids = [], $c continue; } - $context = \context_module::instance($module->id); + $context = context_module::instance($module->id); try { self::validate_context($context); require_capability('mod/assign:view', $context); } catch (moodle_exception $e) { - $warnings[] = array( + $warnings[] = [ 'item' => 'module', 'itemid' => $module->id, 'warningcode' => '1', - 'message' => 'No access rights in module context' - ); + 'message' => 'No access rights in module context', + ]; continue; } - $configrecords = $DB->get_recordset('assign_plugin_config', array('assignment' => $module->assignmentid)); - $configarray = array(); + $configrecords = $DB->get_recordset('assign_plugin_config', ['assignment' => $module->assignmentid]); + $configarray = []; foreach ($configrecords as $configrecord) { - $configarray[] = array( + $configarray[] = [ 'id' => $configrecord->id, 'assignment' => $configrecord->assignment, 'plugin' => $configrecord->plugin, 'subtype' => $configrecord->subtype, 'name' => $configrecord->name, - 'value' => $configrecord->value - ); + 'value' => $configrecord->value, + ]; } $configrecords->close(); - $assignment = array( + $assignment = [ 'id' => $module->assignmentid, 'cmid' => $module->id, 'course' => $module->course, @@ -259,11 +263,11 @@ public static function assignments_read($courseids = [], $assignmentids = [], $c 'markingworkflow' => $module->markingworkflow, 'markingallocation' => $module->markingallocation, 'requiresubmissionstatement' => $module->requiresubmissionstatement, - 'configs' => $configarray - ); + 'configs' => $configarray, + ]; // Return or not intro and file attachments depending on the plugin settings. - $assign = new \assign($context, null, null); + $assign = new assign($context, null, null); if ($assign->show_intro()) { @@ -272,18 +276,18 @@ public static function assignments_read($courseids = [], $assignmentids = [], $c $fs = get_file_storage(); if ($files = $fs->get_area_files($context->id, 'mod_assign', ASSIGN_INTROATTACHMENT_FILEAREA, - 0, 'timemodified', false)) { + 0, 'timemodified', false)) { - $assignment['introattachments'] = array(); + $assignment['introattachments'] = []; foreach ($files as $file) { $filename = $file->get_filename(); - $assignment['introattachments'][] = array( + $assignment['introattachments'][] = [ 'filename' => $filename, 'mimetype' => $file->get_mimetype(), - 'fileurl' => \moodle_url::make_webservice_pluginfile_url( - $context->id, 'mod_assign', ASSIGN_INTROATTACHMENT_FILEAREA, 0, '/', $filename)->out(false) - ); + 'fileurl' => moodle_url::make_webservice_pluginfile_url( + $context->id, 'mod_assign', ASSIGN_INTROATTACHMENT_FILEAREA, 0, '/', $filename)->out(false), + ]; } } } @@ -291,19 +295,20 @@ public static function assignments_read($courseids = [], $assignmentids = [], $c $assignmentarray[] = $assignment; } } - $coursearray[] = array( + $coursearray[] = [ 'id' => $courses[$id]->id, 'fullname' => $courses[$id]->fullname, 'shortname' => $courses[$id]->shortname, 'timemodified' => $courses[$id]->timemodified, - 'assignments' => $assignmentarray - ); + 'assignments' => $assignmentarray, + ]; } - $result = array( + $result = [ 'courses' => $coursearray, - 'warnings' => $warnings - ); + 'warnings' => $warnings, + ]; + return $result; } @@ -315,7 +320,7 @@ public static function assignments_read($courseids = [], $assignmentids = [], $c */ private static function get_assignments_assignment_structure() { return new external_single_structure( - array( + [ 'id' => new external_value(PARAM_INT, 'assignment id'), 'cmid' => new external_value(PARAM_INT, 'course module id'), 'course' => new external_value(PARAM_INT, 'course id'), @@ -347,14 +352,14 @@ private static function get_assignments_assignment_structure() { 'introformat' => new external_format_value('intro', VALUE_OPTIONAL), 'introattachments' => new external_multiple_structure( new external_single_structure( - array ( + [ 'filename' => new external_value(PARAM_FILE, 'file name'), 'mimetype' => new external_value(PARAM_RAW, 'mime type'), - 'fileurl' => new external_value(PARAM_URL, 'file download url') - ) + 'fileurl' => new external_value(PARAM_URL, 'file download url'), + ] ), 'intro attachments files', VALUE_OPTIONAL - ) - ), 'assignment information object'); + ), + ], 'assignment information object'); } /** @@ -365,14 +370,14 @@ private static function get_assignments_assignment_structure() { */ private static function get_assignments_config_structure() { return new external_single_structure( - array( + [ 'id' => new external_value(PARAM_INT, 'assign_plugin_config id'), 'assignment' => new external_value(PARAM_INT, 'assignment id'), 'plugin' => new external_value(PARAM_TEXT, 'plugin'), 'subtype' => new external_value(PARAM_TEXT, 'subtype'), 'name' => new external_value(PARAM_TEXT, 'name'), - 'value' => new external_value(PARAM_TEXT, 'value') - ), 'assignment configuration object' + 'value' => new external_value(PARAM_TEXT, 'value'), + ], 'assignment configuration object' ); } @@ -384,13 +389,13 @@ private static function get_assignments_config_structure() { */ private static function get_assignments_course_structure() { return new external_single_structure( - array( + [ 'id' => new external_value(PARAM_INT, 'course id'), 'fullname' => new external_value(PARAM_TEXT, 'course full name'), 'shortname' => new external_value(PARAM_TEXT, 'course short name'), 'timemodified' => new external_value(PARAM_INT, 'last time modified'), - 'assignments' => new external_multiple_structure(self::get_assignments_assignment_structure(), 'assignment info') - ), 'course information object' + 'assignments' => new external_multiple_structure(self::get_assignments_assignment_structure(), 'assignment info'), + ], 'course information object' ); } @@ -402,13 +407,12 @@ private static function get_assignments_course_structure() { */ public static function assignments_read_returns() { return new external_single_structure( - array( + [ 'courses' => new external_multiple_structure(self::get_assignments_course_structure(), 'list of courses'), - 'warnings' => new external_warnings('item can be \'course\' (errorcode 1 or 2) or \'module\' (errorcode 1)', + 'warnings' => new external_warnings('item can be \'course\' (errorcode 1 or 2) or \'module\' (errorcode 1)', 'When item is a course then itemid is a course id. When the item is a module then itemid is a module id', - 'errorcode can be 1 (no access rights) or 2 (not enrolled or no permissions)') - ) + 'errorcode can be 1 (no access rights) or 2 (not enrolled or no permissions)'), + ] ); } - } diff --git a/classes/webservices/read_courseusers.php b/classes/webservices/read_courseusers.php index 274b95588..a5d21f523 100644 --- a/classes/webservices/read_courseusers.php +++ b/classes/webservices/read_courseusers.php @@ -25,6 +25,8 @@ namespace local_o365\webservices; +use context_course; +use context_helper; use moodle_exception; use stdClass; @@ -38,7 +40,7 @@ global $CFG; -require_once($CFG->dirroot.'/course/modlib.php'); +require_once($CFG->dirroot . '/course/modlib.php'); /** * Get a list of students in a course by course id. @@ -77,7 +79,7 @@ public static function courseusers_read_parameters() { */ public static function courseusers_read($courseid, $limitfrom = 0, $limitnumber = 0, $userids = []) { global $CFG, $DB; - require_once($CFG->dirroot.'/user/lib.php'); + require_once($CFG->dirroot . '/user/lib.php'); $params = self::validate_parameters( self::courseusers_read_parameters(), @@ -109,10 +111,10 @@ public static function courseusers_read($courseid, $limitfrom = 0, $limitnumber $limitnumber = clean_param($limitnumber, PARAM_INT); if ($courseid == SITEID) { - // TODO exception. + return []; } $course = $DB->get_record('course', ['id' => $courseid], '*', MUST_EXIST); - $context = \context_course::instance($courseid); + $context = context_course::instance($courseid); self::validate_context($context); try { @@ -121,7 +123,7 @@ public static function courseusers_read($courseid, $limitfrom = 0, $limitnumber $exceptionparam = new stdClass(); $exceptionparam->message = $e->getMessage(); $exceptionparam->courseid = $params['courseid']; - throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam); + throw new moodle_exception('errorcoursecontextnotvalid', 'webservice', '', $exceptionparam); } require_capability('moodle/course:viewparticipants', $context); @@ -129,7 +131,7 @@ public static function courseusers_read($courseid, $limitfrom = 0, $limitnumber [$enrolledsql, $enrolledparams] = get_enrolled_sql($context, $withcapability); // For user context preloading. - $ctxselect = ', ' . \context_helper::get_preload_record_columns_sql('ctx'); + $ctxselect = ', ' . context_helper::get_preload_record_columns_sql('ctx'); $ctxjoin = "LEFT JOIN {context} ctx ON (ctx.instanceid = u.id AND ctx.contextlevel = :contextlevel)"; $enrolledparams['contextlevel'] = CONTEXT_USER; @@ -166,7 +168,7 @@ public static function courseusers_read($courseid, $limitfrom = 0, $limitnumber } // Get user info. - \context_helper::preload_from_record($user); + context_helper::preload_from_record($user); if ($userdetails = user_get_user_details($user, $course, $userfields)) { $users[] = $userdetails; } @@ -179,7 +181,7 @@ public static function courseusers_read($courseid, $limitfrom = 0, $limitnumber /** * Returns description of method result value * - * @return external_description + * @return external_multiple_structure */ public static function courseusers_read_returns() { return new external_multiple_structure( diff --git a/classes/webservices/read_onenoteassignment.php b/classes/webservices/read_onenoteassignment.php index d1d676979..2b3f490b4 100644 --- a/classes/webservices/read_onenoteassignment.php +++ b/classes/webservices/read_onenoteassignment.php @@ -27,6 +27,7 @@ defined('MOODLE_INTERNAL') || die(); +use context_course; use core_external\external_api; use core_external\external_function_parameters; use core_external\external_single_structure; @@ -34,7 +35,7 @@ global $CFG; -require_once($CFG->dirroot.'/course/modlib.php'); +require_once($CFG->dirroot . '/course/modlib.php'); /** * Read assignment API class. @@ -50,7 +51,7 @@ public static function assignment_read_parameters() { 'data' => new external_single_structure([ 'coursemodule' => new external_value(PARAM_INT, 'course module id'), 'course' => new external_value(PARAM_INT, 'course id'), - ]) + ]), ]); } @@ -63,13 +64,14 @@ public static function assignment_read_parameters() { public static function assignment_read($data) { $params = self::validate_parameters(self::assignment_read_parameters(), ['data' => $data]); $params = $params['data']; - list($course, $module, $assign) = \local_o365\webservices\utils::verify_assignment($params['coursemodule'], + [$course, $module, $assign] = utils::verify_assignment($params['coursemodule'], $params['course']); - $context = \context_course::instance($params['course']); + $context = context_course::instance($params['course']); self::validate_context($context); - $modinfo = \local_o365\webservices\utils::get_assignment_return_info($module->id, $course->id); + $modinfo = utils::get_assignment_return_info($module->id, $course->id); + return ['data' => [$modinfo]]; } @@ -79,6 +81,6 @@ public static function assignment_read($data) { * @return external_single_structure Object describing return parameters for this webservice method. */ public static function assignment_read_returns() { - return \local_o365\webservices\utils::get_assignment_return_info_schema(); + return utils::get_assignment_return_info_schema(); } } diff --git a/classes/webservices/read_teachercourses.php b/classes/webservices/read_teachercourses.php index 5bc6dfa14..15d09b7cf 100644 --- a/classes/webservices/read_teachercourses.php +++ b/classes/webservices/read_teachercourses.php @@ -25,6 +25,7 @@ namespace local_o365\webservices; +use context_course; use moodle_exception; defined('MOODLE_INTERNAL') || die(); @@ -37,7 +38,7 @@ global $CFG; -require_once($CFG->dirroot.'/course/modlib.php'); +require_once($CFG->dirroot . '/course/modlib.php'); /** * Get a list of courses where the current user is a teacher. @@ -73,7 +74,7 @@ public static function teachercourses_read($courseids = []) { $params = self::validate_parameters( self::teachercourses_read_parameters(), [ - 'courseids' => $courseids + 'courseids' => $courseids, ] ); @@ -86,12 +87,11 @@ public static function teachercourses_read($courseids = []) { $result = []; foreach ($courses as $course) { - if (!empty($courseids) && !isset($courseids[$course->id])) { continue; } - $context = \context_course::instance($course->id, IGNORE_MISSING); + $context = context_course::instance($course->id, IGNORE_MISSING); // Validate the user can execute functions in this course. try { @@ -114,7 +114,7 @@ public static function teachercourses_read($courseids = []) { 'format' => $course->format, 'showgrades' => $course->showgrades, 'lang' => $course->lang, - 'enablecompletion' => $course->enablecompletion + 'enablecompletion' => $course->enablecompletion, ]; } @@ -124,7 +124,7 @@ public static function teachercourses_read($courseids = []) { /** * Returns description of method result value * - * @return external_description + * @return external_multiple_structure */ public static function teachercourses_read_returns() { return new external_multiple_structure( diff --git a/classes/webservices/update_grade.php b/classes/webservices/update_grade.php index 20c6cc0b6..ac8fc8aa2 100644 --- a/classes/webservices/update_grade.php +++ b/classes/webservices/update_grade.php @@ -27,6 +27,9 @@ defined('MOODLE_INTERNAL') || die(); +use assign; +use context_module; +use grading_manager; use local_o365\webservices\exception as exception; use core_external\external_api; use core_external\external_function_parameters; @@ -36,9 +39,9 @@ global $CFG; -require_once($CFG->dirroot.'/course/modlib.php'); -require_once($CFG->dirroot.'/user/externallib.php'); -require_once($CFG->dirroot.'/mod/assign/locallib.php'); +require_once($CFG->dirroot . '/course/modlib.php'); +require_once($CFG->dirroot . '/user/externallib.php'); +require_once($CFG->dirroot . '/mod/assign/locallib.php'); /** * Update a grade. @@ -52,8 +55,8 @@ class update_grade extends external_api { public static function grade_update_parameters() { global $CFG; require_once("$CFG->dirroot/grade/grading/lib.php"); - $instance = new \assign(null, null, null); - $pluginfeedbackparams = array(); + $instance = new assign(null, null, null); + $pluginfeedbackparams = []; foreach ($instance->get_feedback_plugins() as $plugin) { if ($plugin->is_visible()) { @@ -64,21 +67,21 @@ public static function grade_update_parameters() { } } - $advancedgradingdata = array(); - $methods = array_keys(\grading_manager::available_methods(false)); + $advancedgradingdata = []; + $methods = array_keys(grading_manager::available_methods(false)); foreach ($methods as $method) { - require_once($CFG->dirroot.'/grade/grading/form/'.$method.'/lib.php'); - $details = call_user_func('gradingform_'.$method.'_controller::get_external_instance_filling_details'); + require_once($CFG->dirroot . '/grade/grading/form/' . $method . '/lib.php'); + $details = call_user_func('gradingform_' . $method . '_controller::get_external_instance_filling_details'); if (!empty($details)) { - $items = array(); + $items = []; foreach ($details as $key => $value) { $value->required = VALUE_OPTIONAL; unset($value->content->keys['id']); $items[$key] = new external_multiple_structure (new external_single_structure( - array( + [ 'criterionid' => new external_value(PARAM_INT, 'criterion id'), - 'fillings' => $value - ) + 'fillings' => $value, + ] )); } $advancedgradingdata[$method] = new external_single_structure($items, 'items', VALUE_OPTIONAL); @@ -86,20 +89,19 @@ public static function grade_update_parameters() { } return new external_function_parameters( - array( + [ 'assignmentid' => new external_value(PARAM_INT, 'The assignment id to operate on'), 'userid' => new external_value(PARAM_INT, 'The student id to operate on'), 'grade' => new external_value(PARAM_FLOAT, 'The new grade for this user. Ignored if advanced grading used'), 'attemptnumber' => new external_value(PARAM_INT, 'The attempt number (-1 means latest attempt)'), 'addattempt' => new external_value(PARAM_BOOL, 'Allow another attempt if the attempt reopen method is manual'), 'workflowstate' => new external_value(PARAM_ALPHA, 'The next marking workflow state'), - 'applytoall' => new external_value(PARAM_BOOL, 'If true, this grade will be applied ' . - 'to all members ' . - 'of the group (for group assignments).'), - 'plugindata' => new external_single_structure($pluginfeedbackparams, 'plugin data', VALUE_DEFAULT, array()), + 'applytoall' => new external_value(PARAM_BOOL, 'If true, this grade will be applied to all members ' . + 'of the group (for group assignments).'), + 'plugindata' => new external_single_structure($pluginfeedbackparams, 'plugin data', VALUE_DEFAULT, []), 'advancedgradingdata' => new external_single_structure($advancedgradingdata, 'advanced grading data', - VALUE_DEFAULT, array()) - ) + VALUE_DEFAULT, []), + ] ); } @@ -119,35 +121,22 @@ public static function grade_update_parameters() { * @throws exception\couldnotsavegrade * @since Moodle 2.6 */ - public static function grade_update($assignmentid, - $userid, - $grade, - $attemptnumber, - $addattempt, - $workflowstate, - $applytoall, - $plugindata = array(), - $advancedgradingdata = array()) { - global $CFG, $USER, $DB; - - $params = self::validate_parameters(self::grade_update_parameters(), - array('assignmentid' => $assignmentid, - 'userid' => $userid, - 'grade' => $grade, - 'attemptnumber' => $attemptnumber, - 'workflowstate' => $workflowstate, - 'addattempt' => $addattempt, - 'applytoall' => $applytoall, - 'plugindata' => $plugindata, - 'advancedgradingdata' => $advancedgradingdata)); + public static function grade_update($assignmentid, $userid, $grade, $attemptnumber, $addattempt, $workflowstate, $applytoall, + $plugindata = [], $advancedgradingdata = []) { + global $DB; + + $params = self::validate_parameters(self::grade_update_parameters(), ['assignmentid' => $assignmentid, + 'userid' => $userid, 'grade' => $grade, 'attemptnumber' => $attemptnumber, 'workflowstate' => $workflowstate, + 'addattempt' => $addattempt, 'applytoall' => $applytoall, 'plugindata' => $plugindata, + 'advancedgradingdata' => $advancedgradingdata]); $cm = get_coursemodule_from_instance('assign', $params['assignmentid'], 0, false, MUST_EXIST); - $context = \context_module::instance($cm->id); + $context = context_module::instance($cm->id); self::validate_context($context); - $assignment = new \assign($context, $cm, null); + $assignment = new assign($context, $cm, null); - $gradedata = (object)$params['plugindata']; + $gradedata = (object) $params['plugindata']; $gradedata->addattempt = $params['addattempt']; $gradedata->attemptnumber = $params['attemptnumber']; @@ -156,10 +145,10 @@ public static function grade_update($assignmentid, $gradedata->grade = $params['grade']; if (!empty($params['advancedgradingdata'])) { - $advancedgrading = array(); + $advancedgrading = []; $criteria = reset($params['advancedgradingdata']); foreach ($criteria as $key => $criterion) { - $details = array(); + $details = []; foreach ($criterion as $value) { foreach ($value['fillings'] as $filling) { $details[$value['criterionid']] = $filling; @@ -186,7 +175,7 @@ public static function grade_update($assignmentid, return [ 'id' => $graderec->id, - 'itemid' => $graderec->itemid + 'itemid' => $graderec->itemid, ]; } diff --git a/classes/webservices/update_onenoteassignment.php b/classes/webservices/update_onenoteassignment.php index 0b322996d..89b164072 100644 --- a/classes/webservices/update_onenoteassignment.php +++ b/classes/webservices/update_onenoteassignment.php @@ -27,6 +27,7 @@ defined('MOODLE_INTERNAL') || die(); +use context_course; use local_o365\webservices\exception as exception; use core_external\external_api; use core_external\external_function_parameters; @@ -35,7 +36,7 @@ global $CFG; -require_once($CFG->dirroot.'/course/modlib.php'); +require_once($CFG->dirroot . '/course/modlib.php'); /** * Update assignment API class. @@ -55,7 +56,7 @@ public static function assignment_update_parameters() { 'intro' => new external_value(PARAM_TEXT, 'intro', VALUE_DEFAULT, null), 'section' => new external_value(PARAM_INT, 'section', VALUE_DEFAULT, null), 'visible' => new external_value(PARAM_BOOL, 'visible', VALUE_DEFAULT, null), - ]) + ]), ]); } @@ -72,10 +73,10 @@ public static function assignment_update($data) { $params = self::validate_parameters(self::assignment_update_parameters(), ['data' => $data]); $params = $params['data']; - list($course, $module, $assign) = \local_o365\webservices\utils::verify_assignment($params['coursemodule'], + [$course, $module, $assign] = utils::verify_assignment($params['coursemodule'], $params['course']); - $context = \context_course::instance($params['course']); + $context = context_course::instance($params['course']); self::validate_context($context); // Update assignment information. @@ -84,7 +85,7 @@ public static function assignment_update($data) { $updatedassigninfo['name'] = $params['name']; } if (isset($params['intro']) && $params['intro'] !== null) { - $updatedassigninfo['introeditor'] = ['text' => (string)$params['intro'], 'format' => FORMAT_HTML, 'itemid' => null]; + $updatedassigninfo['introeditor'] = ['text' => (string) $params['intro'], 'format' => FORMAT_HTML, 'itemid' => null]; } if (!empty($updatedassigninfo)) { $assignkeys = [ @@ -108,7 +109,7 @@ public static function assignment_update($data) { $assigninfo = [ 'coursemodule' => $module->id, 'cmidnumber' => $module->idnumber, - 'introeditor' => ['text' => (string)$assign->intro, 'format' => FORMAT_HTML, 'itemid' => null], + 'introeditor' => ['text' => (string) $assign->intro, 'format' => FORMAT_HTML, 'itemid' => null], 'assignsubmission_onenote_enabled' => 1, 'assignsubmission_onenote_maxfiles' => 1, 'assignsubmission_onenote_maxsizebytes' => 1024, @@ -121,7 +122,7 @@ public static function assignment_update($data) { } $assigninfo = array_merge($assigninfo, $updatedassigninfo); - update_module((object)$assigninfo); + update_module((object) $assigninfo); } // Update module visibility if requested. @@ -140,7 +141,8 @@ public static function assignment_update($data) { moveto_module($module, $section); } - $modinfo = \local_o365\webservices\utils::get_assignment_return_info($module->id, $course->id); + $modinfo = utils::get_assignment_return_info($module->id, $course->id); + return ['data' => [$modinfo]]; } @@ -150,6 +152,6 @@ public static function assignment_update($data) { * @return external_single_structure Object describing return parameters for this webservice method. */ public static function assignment_update_returns() { - return \local_o365\webservices\utils::get_assignment_return_info_schema(); + return utils::get_assignment_return_info_schema(); } } diff --git a/classes/webservices/utils.php b/classes/webservices/utils.php index 7eb061611..cb022c68e 100644 --- a/classes/webservices/utils.php +++ b/classes/webservices/utils.php @@ -28,11 +28,9 @@ use core_external\external_multiple_structure; use core_external\external_single_structure; use core_external\external_value; -use \local_o365\webservices\exception as exception; +use local_o365\webservices\exception as exception; use moodle_exception; -defined('MOODLE_INTERNAL') || die(); - /** * Webservices utilities. */ @@ -88,6 +86,7 @@ public static function get_assignment_return_info_schema() { ]) ), ]; + return new external_single_structure($params); } @@ -112,6 +111,7 @@ public static function get_assignment_info($coursemoduleid, $courseid) { if (empty($assign)) { throw new exception\assignnotfound(); } + return [$course, $module, $assign]; } @@ -124,6 +124,7 @@ public static function get_assignment_info($coursemoduleid, $courseid) { */ public static function get_assignment_return_info($coursemoduleid, $courseid) { [$course, $module, $assign] = static::get_assignment_info($coursemoduleid, $courseid); + return [ 'course' => $course->id, 'coursemodule' => $module->id, diff --git a/db/access.php b/db/access.php index 2363818ec..92b7cb7a7 100644 --- a/db/access.php +++ b/db/access.php @@ -32,7 +32,7 @@ 'contextlevel' => CONTEXT_COURSE, 'archetypes' => [ 'editingteacher' => CAP_ALLOW, - 'manager' => CAP_ALLOW + 'manager' => CAP_ALLOW, ], ], 'local/o365:viewgroups' => [ diff --git a/db/caches.php b/db/caches.php index 22f161420..e22d27bb1 100644 --- a/db/caches.php +++ b/db/caches.php @@ -27,6 +27,6 @@ $definitions = [ 'groups' => [ - 'mode' => cache_store::MODE_SESSION + 'mode' => cache_store::MODE_SESSION, ], ]; diff --git a/db/services.php b/db/services.php index 4aad3b421..4836c2b84 100644 --- a/db/services.php +++ b/db/services.php @@ -103,5 +103,5 @@ 'restrictedusers' => 0, 'enabled' => 0, 'shortname' => 'o365_webservices', - ] + ], ]; diff --git a/db/tasks.php b/db/tasks.php index 57e4bb2eb..5714a487c 100644 --- a/db/tasks.php +++ b/db/tasks.php @@ -33,7 +33,7 @@ 'hour' => '1', 'day' => '*', 'dayofweek' => '*', - 'month' => '*' + 'month' => '*', ], [ 'classname' => 'local_o365\task\coursesync', @@ -42,7 +42,7 @@ 'hour' => '*', 'day' => '*', 'dayofweek' => '*', - 'month' => '*' + 'month' => '*', ], [ 'classname' => 'local_o365\feature\calsync\task\importfromoutlook', @@ -51,7 +51,7 @@ 'hour' => '*', 'day' => '*', 'dayofweek' => '*', - 'month' => '*' + 'month' => '*', ], [ 'classname' => 'local_o365\task\processmatchqueue', @@ -60,7 +60,7 @@ 'hour' => '*', 'day' => '*', 'dayofweek' => '*', - 'month' => '*' + 'month' => '*', ], [ 'classname' => 'local_o365\feature\sds\task\sync', @@ -69,7 +69,7 @@ 'hour' => '3', 'day' => '*', 'dayofweek' => '*', - 'month' => '*' + 'month' => '*', ], [ 'classname' => 'local_o365\task\notifysecretexpiry', @@ -87,7 +87,7 @@ 'hour' => '*', 'day' => '*', 'dayofweek' => '*', - 'month' => '*' + 'month' => '*', ], [ 'classname' => 'local_o365\task\updatecourserequeststatus', @@ -96,7 +96,7 @@ 'hour' => '*', 'day' => '*', 'dayofweek' => '*', - 'month' => '*' + 'month' => '*', ], [ 'classname' => 'local_o365\task\coursemembershipsync', diff --git a/db/upgrade.php b/db/upgrade.php index 312287442..939e1697c 100644 --- a/db/upgrade.php +++ b/db/upgrade.php @@ -46,7 +46,7 @@ function xmldb_local_o365_upgrade($oldversion) { if (!$dbman->table_exists('local_o365_token')) { $dbman->install_one_table_from_xmldb_file(__DIR__.'/install.xml', 'local_o365_token'); } - upgrade_plugin_savepoint(true, '2014111700', 'local', 'o365'); + upgrade_plugin_savepoint(true, 2014111700, 'local', 'o365'); } if ($oldversion < 2014111702) { @@ -56,21 +56,21 @@ function xmldb_local_o365_upgrade($oldversion) { if (!$dbman->table_exists('local_o365_calidmap')) { $dbman->install_one_table_from_xmldb_file(__DIR__.'/install.xml', 'local_o365_calidmap'); } - upgrade_plugin_savepoint(true, '2014111702', 'local', 'o365'); + upgrade_plugin_savepoint(true, 2014111702, 'local', 'o365'); } if ($oldversion < 2014111703) { $table = new xmldb_table('local_o365_calidmap'); $field = new xmldb_field('outlookeventid', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, 'eventid'); $dbman->change_field_type($table, $field); - upgrade_plugin_savepoint(true, '2014111703', 'local', 'o365'); + upgrade_plugin_savepoint(true, 2014111703, 'local', 'o365'); } if ($oldversion < 2014111707) { if (!$dbman->table_exists('local_o365_cronqueue')) { $dbman->install_one_table_from_xmldb_file(__DIR__.'/install.xml', 'local_o365_cronqueue'); } - upgrade_plugin_savepoint(true, '2014111707', 'local', 'o365'); + upgrade_plugin_savepoint(true, 2014111707, 'local', 'o365'); } if ($oldversion < 2014111710) { @@ -83,7 +83,7 @@ function xmldb_local_o365_upgrade($oldversion) { if (!$dbman->table_exists('local_o365_aaduserdata')) { $dbman->install_one_table_from_xmldb_file(__DIR__.'/install.xml', 'local_o365_aaduserdata'); } - upgrade_plugin_savepoint(true, '2014111710', 'local', 'o365'); + upgrade_plugin_savepoint(true, 2014111710, 'local', 'o365'); } if ($oldversion < 2014111711) { @@ -92,14 +92,14 @@ function xmldb_local_o365_upgrade($oldversion) { if (!$dbman->field_exists($table, $field)) { $dbman->add_field($table, $field); } - upgrade_plugin_savepoint(true, '2014111711', 'local', 'o365'); + upgrade_plugin_savepoint(true, 2014111711, 'local', 'o365'); } if ($oldversion < 2014111715) { if (!$dbman->table_exists('local_o365_spgroupassign')) { $dbman->install_one_table_from_xmldb_file(__DIR__.'/install.xml', 'local_o365_spgroupassign'); } - upgrade_plugin_savepoint(true, '2014111715', 'local', 'o365'); + upgrade_plugin_savepoint(true, 2014111715, 'local', 'o365'); } if ($oldversion < 2014111716) { @@ -122,7 +122,7 @@ function xmldb_local_o365_upgrade($oldversion) { $dbman->add_index($table, $index); } - upgrade_plugin_savepoint(true, '2014111716', 'local', 'o365'); + upgrade_plugin_savepoint(true, 2014111716, 'local', 'o365'); } if ($oldversion < 2015012702) { @@ -133,7 +133,7 @@ function xmldb_local_o365_upgrade($oldversion) { add_to_config_log('sharepointlink', '', $sharepointlink, 'local_o365'); set_config('sharepointlink', $sharepointlink, 'local_o365'); } - upgrade_plugin_savepoint(true, '2015012702', 'local', 'o365'); + upgrade_plugin_savepoint(true, 2015012702, 'local', 'o365'); } if ($oldversion < 2015012704) { @@ -150,7 +150,7 @@ function xmldb_local_o365_upgrade($oldversion) { } set_config('odburl', $config->tenant.'-my.sharepoint.com', 'local_o365'); } - upgrade_plugin_savepoint(true, '2015012704', 'local', 'o365'); + upgrade_plugin_savepoint(true, 2015012704, 'local', 'o365'); } if ($oldversion < 2015012707) { @@ -163,7 +163,7 @@ function xmldb_local_o365_upgrade($oldversion) { if (!$dbman->field_exists($table, $field)) { $dbman->add_field($table, $field); } - upgrade_plugin_savepoint(true, '2015012707', 'local', 'o365'); + upgrade_plugin_savepoint(true, 2015012707, 'local', 'o365'); } if ($oldversion < 2015012708) { @@ -184,7 +184,7 @@ function xmldb_local_o365_upgrade($oldversion) { } $idmaps->close(); - upgrade_plugin_savepoint(true, '2015012708', 'local', 'o365'); + upgrade_plugin_savepoint(true, 2015012708, 'local', 'o365'); } if ($oldversion < 2015012709) { @@ -217,7 +217,7 @@ function xmldb_local_o365_upgrade($oldversion) { } $idmaps->close(); - upgrade_plugin_savepoint(true, '2015012709', 'local', 'o365'); + upgrade_plugin_savepoint(true, 2015012709, 'local', 'o365'); } if ($oldversion < 2015012710) { @@ -231,7 +231,7 @@ function xmldb_local_o365_upgrade($oldversion) { } } $calsubs->close(); - upgrade_plugin_savepoint(true, '2015012710', 'local', 'o365'); + upgrade_plugin_savepoint(true, 2015012710, 'local', 'o365'); } if ($oldversion < 2015012712) { @@ -239,14 +239,14 @@ function xmldb_local_o365_upgrade($oldversion) { $table = new xmldb_table('local_o365_token'); $field = new xmldb_field('scope', XMLDB_TYPE_TEXT, null, null, null, null, null, 'user_id'); $dbman->change_field_type($table, $field); - upgrade_plugin_savepoint(true, '2015012712', 'local', 'o365'); + upgrade_plugin_savepoint(true, 2015012712, 'local', 'o365'); } if ($oldversion < 2015012713) { if (!$dbman->table_exists('local_o365_objects')) { $dbman->install_one_table_from_xmldb_file(__DIR__.'/install.xml', 'local_o365_objects'); } - upgrade_plugin_savepoint(true, '2015012713', 'local', 'o365'); + upgrade_plugin_savepoint(true, 2015012713, 'local', 'o365'); } if ($oldversion < 2015012714) { @@ -255,7 +255,7 @@ function xmldb_local_o365_upgrade($oldversion) { if (!$dbman->field_exists($table, $field)) { $dbman->add_field($table, $field); } - upgrade_plugin_savepoint(true, '2015012714', 'local', 'o365'); + upgrade_plugin_savepoint(true, 2015012714, 'local', 'o365'); } if ($oldversion < 2015012715) { @@ -263,7 +263,7 @@ function xmldb_local_o365_upgrade($oldversion) { $table = new xmldb_table('local_o365_token'); $field = new xmldb_field('scope', XMLDB_TYPE_TEXT, null, null, null, null, null, 'user_id'); $dbman->change_field_type($table, $field); - upgrade_plugin_savepoint(true, '2015012715', 'local', 'o365'); + upgrade_plugin_savepoint(true, 2015012715, 'local', 'o365'); } if ($oldversion < 2015060102) { @@ -272,14 +272,14 @@ function xmldb_local_o365_upgrade($oldversion) { add_to_config_log('aadsync', '1', 'create', 'local_o365'); set_config('aadsync', 'create', 'local_o365'); } - upgrade_plugin_savepoint(true, '2015060102', 'local', 'o365'); + upgrade_plugin_savepoint(true, 2015060102, 'local', 'o365'); } if ($oldversion < 2015060103) { if (!$dbman->table_exists('local_o365_connections')) { $dbman->install_one_table_from_xmldb_file(__DIR__.'/install.xml', 'local_o365_connections'); } - upgrade_plugin_savepoint(true, '2015060103', 'local', 'o365'); + upgrade_plugin_savepoint(true, 2015060103, 'local', 'o365'); } if ($oldversion < 2015060104) { @@ -288,7 +288,7 @@ function xmldb_local_o365_upgrade($oldversion) { if (!$dbman->field_exists($table, $field)) { $dbman->add_field($table, $field); } - upgrade_plugin_savepoint(true, '2015060104', 'local', 'o365'); + upgrade_plugin_savepoint(true, 2015060104, 'local', 'o365'); } if ($oldversion < 2015060109) { @@ -311,14 +311,14 @@ function xmldb_local_o365_upgrade($oldversion) { } } } - upgrade_plugin_savepoint(true, '2015060109', 'local', 'o365'); + upgrade_plugin_savepoint(true, 2015060109, 'local', 'o365'); } if ($oldversion < 2015060111) { // Clean up old "calendarsyncin" task record, if present. Replaced by \local_o365\feature\calsync\task\importfromoutlook. $conditions = ['component' => 'local_o365', 'classname' => '\local_o365\task\calendarsyncin']; $DB->delete_records('task_scheduled', $conditions); - upgrade_plugin_savepoint(true, '2015060111', 'local', 'o365'); + upgrade_plugin_savepoint(true, 2015060111, 'local', 'o365'); } if ($oldversion < 2015111900.01) { @@ -343,7 +343,7 @@ function xmldb_local_o365_upgrade($oldversion) { } } - upgrade_plugin_savepoint(true, '2015111900.01', 'local', 'o365'); + upgrade_plugin_savepoint(true, 2015111900.01, 'local', 'o365'); } if ($oldversion < 2015111900.02) { @@ -351,7 +351,7 @@ function xmldb_local_o365_upgrade($oldversion) { if (!$dbman->table_exists($table)) { $dbman->install_one_table_from_xmldb_file(__DIR__.'/install.xml', 'local_o365_appassign'); } - upgrade_plugin_savepoint(true, '2015111900.02', 'local', 'o365'); + upgrade_plugin_savepoint(true, 2015111900.02, 'local', 'o365'); } if ($oldversion < 2015111901.01) { @@ -359,7 +359,7 @@ function xmldb_local_o365_upgrade($oldversion) { if (!$dbman->table_exists($table)) { $dbman->install_one_table_from_xmldb_file(__DIR__.'/install.xml', 'local_o365_matchqueue'); } - upgrade_plugin_savepoint(true, '2015111901.01', 'local', 'o365'); + upgrade_plugin_savepoint(true, 2015111901.01, 'local', 'o365'); } if ($oldversion < 2015111901.03) { @@ -378,12 +378,12 @@ function xmldb_local_o365_upgrade($oldversion) { if (!$dbman->index_exists($table, $index)) { $dbman->add_index($table, $index); } - upgrade_plugin_savepoint(true, '2015111901.03', 'local', 'o365'); + upgrade_plugin_savepoint(true, 2015111901.03, 'local', 'o365'); } if ($oldversion < 2015111903) { $table = new xmldb_table('local_o365_appassign'); - $index = new xmldb_index('userobjectid', XMLDB_INDEX_UNIQUE, array('userobjectid')); + $index = new xmldb_index('userobjectid', XMLDB_INDEX_UNIQUE, ['userobjectid']); if ($dbman->index_exists($table, $index)) { $dbman->drop_index($table, $index); } @@ -399,17 +399,17 @@ function xmldb_local_o365_upgrade($oldversion) { if (!$dbman->field_exists($table, $field)) { $dbman->add_field($table, $field); } - upgrade_plugin_savepoint(true, '2015111903', 'local', 'o365'); + upgrade_plugin_savepoint(true, 2015111903, 'local', 'o365'); } if ($oldversion < 2015111905) { // Delete custom profile fields for data type o365 and oidc which are no longer used. $fields = $DB->get_records_sql("SELECT * FROM {user_info_field} WHERE datatype IN ('o365', 'oidc')"); foreach ($fields as $field) { - $DB->delete_records('user_info_data', array('fieldid' => $field->id)); - $DB->delete_records('user_info_field', array('id' => $field->id)); + $DB->delete_records('user_info_data', ['fieldid' => $field->id]); + $DB->delete_records('user_info_field', ['id' => $field->id]); } - upgrade_plugin_savepoint(true, '2015111905', 'local', 'o365'); + upgrade_plugin_savepoint(true, 2015111905, 'local', 'o365'); } if ($oldversion < 2015111911.01) { @@ -419,14 +419,14 @@ function xmldb_local_o365_upgrade($oldversion) { $field->setNotNull(false); $dbman->change_field_notnull($table, $field); } - upgrade_plugin_savepoint(true, '2015111911.01', 'local', 'o365'); + upgrade_plugin_savepoint(true, 2015111911.01, 'local', 'o365'); } if ($oldversion < 2015111913) { if (!$dbman->table_exists('local_o365_coursegroupdata')) { $dbman->install_one_table_from_xmldb_file(__DIR__.'/install.xml', 'local_o365_coursegroupdata'); } - upgrade_plugin_savepoint(true, '2015111913', 'local', 'o365'); + upgrade_plugin_savepoint(true, 2015111913, 'local', 'o365'); } if ($oldversion < 2015111913.02) { @@ -438,7 +438,7 @@ function xmldb_local_o365_upgrade($oldversion) { } set_config('creategroups', 'onall', 'local_o365'); } - upgrade_plugin_savepoint(true, '2015111913.02', 'local', 'o365'); + upgrade_plugin_savepoint(true, 2015111913.02, 'local', 'o365'); } if ($oldversion < 2015111914.02) { @@ -452,7 +452,7 @@ function xmldb_local_o365_upgrade($oldversion) { } // O365 savepoint reached. - upgrade_plugin_savepoint(true, '2015111914.02', 'local', 'o365'); + upgrade_plugin_savepoint(true, 2015111914.02, 'local', 'o365'); } if ($oldversion < 2015111914.03) { @@ -469,7 +469,7 @@ function xmldb_local_o365_upgrade($oldversion) { $dbman->drop_index($table, $index); } - upgrade_plugin_savepoint(true, '2015111914.03', 'local', 'o365'); + upgrade_plugin_savepoint(true, 2015111914.03, 'local', 'o365'); } if ($oldversion < 2015111916.01) { @@ -483,7 +483,7 @@ function xmldb_local_o365_upgrade($oldversion) { $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null); // Adding keys to table local_o365_calsettings. - $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); + $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']); // Conditionally launch create table for local_o365_calsettings. if (!$dbman->table_exists($table)) { @@ -502,13 +502,13 @@ function xmldb_local_o365_upgrade($oldversion) { $newsetting = [ 'user_id' => $USER->id, 'o365calid' => $sitecalendar['Id'], - 'timecreated' => time() + 'timecreated' => time(), ]; $newsetting['id'] = $DB->insert_record('local_o365_calsettings', (object)$newsetting); } } - upgrade_plugin_savepoint(true, '2015111916.01', 'local', 'o365'); + upgrade_plugin_savepoint(true, 2015111916.01, 'local', 'o365'); } if ($oldversion < 2016062000.01) { @@ -517,7 +517,7 @@ function xmldb_local_o365_upgrade($oldversion) { add_to_config_log('sharepointcourseselect', $existingsharepointcourseselectsetting, 'off', 'local_o365'); } set_config('sharepointcourseselect', 'off', 'local_o365'); - upgrade_plugin_savepoint(true, '2016062000.01', 'local', 'o365'); + upgrade_plugin_savepoint(true, 2016062000.01, 'local', 'o365'); } if ($oldversion < 2016062000.02) { @@ -528,7 +528,7 @@ function xmldb_local_o365_upgrade($oldversion) { $caps = [ 'auth/oidc:manageconnection' => ['local/o365:manageconnectionlink', 'local/o365:manageconnectionunlink'], 'auth/oidc:manageconnectionconnect' => ['local/o365:manageconnectionlink'], - 'auth/oidc:manageconnectiondisconnect' => ['local/o365:manageconnectionunlink'] + 'auth/oidc:manageconnectiondisconnect' => ['local/o365:manageconnectionunlink'], ]; foreach ($caps as $cap => $addcaps) { $roles = get_roles_with_capability($cap, CAP_ALLOW); @@ -538,8 +538,8 @@ function xmldb_local_o365_upgrade($oldversion) { $newrolecap = $rolecap; unset($newrolecap->id); foreach ($addcaps as $addcap) { - if (!$DB->record_exists('role_capabilities', ['roleid' => $role->id, - 'capability' => $addcap, 'contextid' => $newrolecap->contextid])) { + if (!$DB->record_exists('role_capabilities', + ['roleid' => $role->id, 'capability' => $addcap, 'contextid' => $newrolecap->contextid])) { $newrolecap->capability = $addcap; $DB->insert_record('role_capabilities', $newrolecap); } @@ -560,7 +560,7 @@ function xmldb_local_o365_upgrade($oldversion) { $dbman->add_field($table, $field); } } - upgrade_plugin_savepoint(true, '2016062000.03', 'local', 'o365'); + upgrade_plugin_savepoint(true, 2016062000.03, 'local', 'o365'); } if ($oldversion < 2016062001.01) { @@ -573,7 +573,7 @@ function xmldb_local_o365_upgrade($oldversion) { add_to_config_log('sharepointcourseselect', $sharepointcourseselect, 'none', 'local_o365'); set_config('sharepointcourseselect', 'none', 'local_o365'); } - upgrade_plugin_savepoint(true, '2016062001.01', 'local', 'o365'); + upgrade_plugin_savepoint(true, 2016062001.01, 'local', 'o365'); } if ($oldversion < 2016062004.01) { @@ -590,7 +590,7 @@ function xmldb_local_o365_upgrade($oldversion) { } set_config('disablegraphapi', 0, 'local_o365'); } - upgrade_plugin_savepoint(true, '2016062004.01', 'local', 'o365'); + upgrade_plugin_savepoint(true, 2016062004.01, 'local', 'o365'); } if ($oldversion < 2016120500.05) { @@ -601,7 +601,7 @@ function xmldb_local_o365_upgrade($oldversion) { $dbman->add_field($table, $field); } } - upgrade_plugin_savepoint(true, '2016120500.05', 'local', 'o365'); + upgrade_plugin_savepoint(true, 2016120500.05, 'local', 'o365'); } if ($oldversion < 2016120500.06) { @@ -612,12 +612,12 @@ function xmldb_local_o365_upgrade($oldversion) { $dbman->add_field($table, $field); } } - upgrade_plugin_savepoint(true, '2016120500.06', 'local', 'o365'); + upgrade_plugin_savepoint(true, 2016120500.06, 'local', 'o365'); } if ($oldversion < 2017111301) { mtrace('Warning! This version removes the legacy Microsoft 365 API.'); - upgrade_plugin_savepoint(true, '2017111301', 'local', 'o365'); + upgrade_plugin_savepoint(true, 2017111301, 'local', 'o365'); } if ($oldversion < 2018051702) { @@ -627,39 +627,7 @@ function xmldb_local_o365_upgrade($oldversion) { add_to_config_log('createteams', $existingcreateteamssetting, $coursesyncsetting, 'local_o365'); } set_config('createteams', $coursesyncsetting, 'local_o365'); - upgrade_plugin_savepoint(true, '2018051702', 'local', 'o365'); - } - - if ($oldversion < 2018051703) { - // Commented out since the bot feature has been removed. - /* - if (!$dbman->table_exists('local_o365_notif')) { - $dbman->install_one_table_from_xmldb_file(__DIR__ . '/install.xml', 'local_o365_notif'); - } - */ - - upgrade_plugin_savepoint(true, '2018051703', 'local', 'o365'); - } - - if ($oldversion < 2018051704) { - // Commented out since the bot feature has been removed. - /* - $botappid = get_config('local_o365', 'bot_app_id'); - $botapppassword = get_config('local_o365', 'bot_app_password'); - $botwebhookendpoint = get_config('local_o365', 'bot_webhook_endpoint'); - if ($botappid && $botapppassword && $botwebhookendpoint) { - set_config('bot_feature_enabled', '1', 'local_o365'); - } else { - set_config('bot_feature_enabled', '0', 'local_o365'); - } - */ - upgrade_plugin_savepoint(true, '2018051704', 'local', 'o365'); - } - - if ($oldversion < 2018051705) { - // Commented out since the bot feature has been removed. - // local_o365_check_sharedsecret(); - upgrade_plugin_savepoint(true, '2018051705', 'local', 'o365'); + upgrade_plugin_savepoint(true, 2018051702, 'local', 'o365'); } if ($oldversion < 2020020302) { @@ -1066,6 +1034,7 @@ function xmldb_local_o365_upgrade($oldversion) { } } catch (moodle_exception $e) { // Do nothing. + debugging('Error updating groups cache: ' . $e->getMessage()); } // O365 savepoint reached. @@ -1214,7 +1183,6 @@ function xmldb_local_o365_upgrade($oldversion) { upgrade_plugin_savepoint(true, 2023100905, 'local', 'o365'); } - if ($oldversion < 2023100907) { // Unset "systemtokens" config. unset_config('systemtokens', 'local_o365'); diff --git a/export_manifest.php b/export_manifest.php index 4414aaf3e..e8209e9b8 100644 --- a/export_manifest.php +++ b/export_manifest.php @@ -27,6 +27,8 @@ require_once($CFG->libdir . '/filestorage/zip_archive.php'); require_once($CFG->dirroot . '/local/o365/lib.php'); +require_admin(); + // Mark manifest file as downloaded. $existingmanifestdownloadedsetting = get_config('local_o365', 'manifest_downloaded'); if (!$existingmanifestdownloadedsetting) { diff --git a/lang/cs/local_o365.php b/lang/cs/local_o365.php index fa31c26b6..2c4cafc17 100644 --- a/lang/cs/local_o365.php +++ b/lang/cs/local_o365.php @@ -24,6 +24,9 @@ * @copyright (C) 2014 onwards Microsoft, Inc. (http://microsoft.com/) */ +// phpcs:disable moodle.Files.LangFilesOrdering.IncorrectOrder +// phpcs:disable moodle.Files.LangFilesOrdering.UnexpectedComment + $string['pluginname'] = 'Integrace Microsoft 365'; $string['acp_title'] = 'Ovládací panel správy Microsoft 365'; $string['acp_healthcheck'] = 'Kontrola stavu'; @@ -141,3 +144,6 @@ $string['ucp_syncdir_both'] = 'Aktualizovat Outlook i Moodle'; $string['ucp_title'] = 'Ovládací panel Microsoft 365 / Moodle'; $string['ucp_options'] = 'Možnosti'; + +// phpcs:enable moodle.Files.LangFilesOrdering.IncorrectOrder +// phpcs:enable moodle.Files.LangFilesOrdering.UnexpectedComment diff --git a/lang/de/local_o365.php b/lang/de/local_o365.php index 379adb147..9ba4f3551 100644 --- a/lang/de/local_o365.php +++ b/lang/de/local_o365.php @@ -24,6 +24,9 @@ * @copyright (C) 2014 onwards Microsoft, Inc. (http://microsoft.com/) */ +// phpcs:disable moodle.Files.LangFilesOrdering.IncorrectOrder +// phpcs:disable moodle.Files.LangFilesOrdering.UnexpectedComment + $string['pluginname'] = 'Microsoft 365-Integration'; $string['acp_title'] = 'Microsoft 365-Systemsteuerung'; $string['acp_healthcheck'] = 'Health Check'; @@ -141,3 +144,6 @@ $string['ucp_syncdir_both'] = 'Sowohl Outlook als auch Moodle aktualisieren'; $string['ucp_title'] = 'Microsoft 365/Moodle-Systemsteuerung'; $string['ucp_options'] = 'Optionen'; + +// phpcs:enable moodle.Files.LangFilesOrdering.IncorrectOrder +// phpcs:enable moodle.Files.LangFilesOrdering.UnexpectedComment diff --git a/lang/en/local_o365.php b/lang/en/local_o365.php index 39905ff16..fe9bd2ce6 100644 --- a/lang/en/local_o365.php +++ b/lang/en/local_o365.php @@ -26,6 +26,9 @@ defined('MOODLE_INTERNAL') || die(); +// phpcs:disable moodle.Files.LangFilesOrdering.IncorrectOrder -- The strings are organised by features. +// phpcs:disable moodle.Files.LangFilesOrdering.UnexpectedComment -- The strings are organised by features. + $string['pluginname'] = 'Microsoft 365 Integration'; // Settings - tabs. @@ -167,7 +170,7 @@
  1. Rename the Moodle user.
  2. auth_oidc_token updated with both new values for both "username" and "oidcusername" fields.
  3. -
  4. local_o365_objects user connection record "o365name" field updated to new value.
  5. +
  6. local_o365_objects user connection record "o365name" field updated to new value.
@@ -180,7 +183,7 @@
  1. Rename the Moodle user.
  2. local_o365_objects user connection record is updated.
  3. -
  4. auth_oidc_token updated.
  5. +
  6. auth_oidc_token updated.
@@ -193,7 +196,7 @@
  1. Rename the Moodle user.
  2. local_o365_objects user connection record is updated.
  3. -
  4. auth_oidc_token updated.
  5. +
  6. auth_oidc_token updated.
@@ -205,7 +208,7 @@
  1. Rename the Moodle user.
  2. -
  3. local_o365_objects user connection record is updated.
  4. +
  5. local_o365_objects user connection record is updated.
@@ -1000,8 +1003,11 @@ $string['notification_subject_invalid_secret'] = 'Action required: invalid Azure app secret found'; $string['notification_content_invalid_secret'] = 'Dear site administrator, -The Azure app secret used in your Moodle and Microsoft 365 integration seems to be invalid. This can either be caused by the secret expired, or it has been deleted. +The Azure app secret used in your Moodle and Microsoft 365 integration seems to be invalid. This can either be caused by the secret expired, or it has been deleted. Please review the secret to ensure the integration works as expected.'; // Misc. $string['spsite_group_contributors_desc'] = 'All users who have access to manage files for course {$a}'; + +// phpcs:enable moodle.Files.LangFilesOrdering.IncorrectOrder +// phpcs:enable moodle.Files.LangFilesOrdering.UnexpectedComment diff --git a/lang/es/local_o365.php b/lang/es/local_o365.php index 1682b7e04..5f3b654b3 100644 --- a/lang/es/local_o365.php +++ b/lang/es/local_o365.php @@ -24,6 +24,9 @@ * @copyright (C) 2014 onwards Microsoft, Inc. (http://microsoft.com/) */ +// phpcs:disable moodle.Files.LangFilesOrdering.IncorrectOrder +// phpcs:disable moodle.Files.LangFilesOrdering.UnexpectedComment + $string['pluginname'] = 'Integración de Microsoft 365'; $string['acp_title'] = 'Panel de control de administración de Microsoft 365'; $string['acp_healthcheck'] = 'Comprobación de estado'; @@ -141,3 +144,6 @@ $string['ucp_syncdir_both'] = 'Actualizar Outlook y Moodle'; $string['ucp_title'] = 'Panel de control de Microsoft 365/Moodle'; $string['ucp_options'] = 'Opciones'; + +// phpcs:enable moodle.Files.LangFilesOrdering.IncorrectOrder +// phpcs:enable moodle.Files.LangFilesOrdering.UnexpectedComment diff --git a/lang/fi/local_o365.php b/lang/fi/local_o365.php index e3df73140..7e9214a6d 100644 --- a/lang/fi/local_o365.php +++ b/lang/fi/local_o365.php @@ -24,6 +24,9 @@ * @copyright (C) 2014 onwards Microsoft, Inc. (http://microsoft.com/) */ +// phpcs:disable moodle.Files.LangFilesOrdering.IncorrectOrder +// phpcs:disable moodle.Files.LangFilesOrdering.UnexpectedComment + $string['pluginname'] = 'Microsoft 365 -integrointi'; $string['acp_title'] = 'Microsoft 365 -järjestelmänvalvojan ohjauspaneeli'; $string['acp_healthcheck'] = 'Kuntotarkistus'; @@ -141,3 +144,6 @@ $string['ucp_syncdir_both'] = 'Päivitä Outlook ja Moodle'; $string['ucp_title'] = 'Microsoft 365 / Moodle -ohjauspaneeli'; $string['ucp_options'] = 'Asetukset'; + +// phpcs:enable moodle.Files.LangFilesOrdering.IncorrectOrder +// phpcs:enable moodle.Files.LangFilesOrdering.UnexpectedComment diff --git a/lang/fr/local_o365.php b/lang/fr/local_o365.php index 4a9722647..57d77488e 100644 --- a/lang/fr/local_o365.php +++ b/lang/fr/local_o365.php @@ -24,6 +24,9 @@ * @copyright (C) 2014 onwards Microsoft, Inc. (http://microsoft.com/) */ +// phpcs:disable moodle.Files.LangFilesOrdering.IncorrectOrder +// phpcs:disable moodle.Files.LangFilesOrdering.UnexpectedComment + $string['pluginname'] = 'Intégration de Microsoft 365'; $string['acp_title'] = 'Panneau de configuration d\'administration Microsoft 365'; $string['acp_healthcheck'] = 'Contrôle de l\'état'; @@ -46,7 +49,7 @@ $string['erroro365apinoparentinfo'] = 'Informations du dossier parent introuvables'; $string['erroro365apinotimplemented'] = 'Ces données doivent être remplacées.'; $string['erroro365apinotoken'] = 'Jeton inexistant pour l\'utilisateur et la ressource donnés. Impossible d\'en obtenir un. Le jeton actualisé de l\'utilisateur a-t-il expiré ?'; -$string['erroro365apisiteexistsnolocal'] = 'Le site existe déjà, mais registre local introuvable.';; +$string['erroro365apisiteexistsnolocal'] = 'Le site existe déjà, mais registre local introuvable.'; $string['eventapifail'] = 'Échec de l\'API'; $string['eventcalendarsubscribed'] = 'Utilisateur abonné à un calendrier'; $string['eventcalendarunsubscribed'] = 'Utilisateur désabonné d\'un calendrier'; @@ -141,3 +144,6 @@ $string['ucp_syncdir_both'] = 'Mettre à jour Outlook et Moodle'; $string['ucp_title'] = 'Panneau de configuration Microsoft 365/Moodle'; $string['ucp_options'] = 'Options'; + +// phpcs:enable moodle.Files.LangFilesOrdering.IncorrectOrder +// phpcs:enable moodle.Files.LangFilesOrdering.UnexpectedComment diff --git a/lang/it/local_o365.php b/lang/it/local_o365.php index dbb708429..f288201a7 100644 --- a/lang/it/local_o365.php +++ b/lang/it/local_o365.php @@ -24,6 +24,9 @@ * @copyright (C) 2014 onwards Microsoft, Inc. (http://microsoft.com/) */ +// phpcs:disable moodle.Files.LangFilesOrdering.IncorrectOrder +// phpcs:disable moodle.Files.LangFilesOrdering.UnexpectedComment + $string['pluginname'] = 'Integrazione Microsoft 365'; $string['acp_title'] = 'Pannello di controllo per amministrare Microsoft 365'; $string['acp_healthcheck'] = 'Controllo stato'; @@ -141,3 +144,6 @@ $string['ucp_syncdir_both'] = 'Aggiorna Outlook e Moodle'; $string['ucp_title'] = 'Pannello di controllo di Microsoft 365/Moodle'; $string['ucp_options'] = 'Opzioni'; + +// phpcs:enable moodle.Files.LangFilesOrdering.IncorrectOrder +// phpcs:enable moodle.Files.LangFilesOrdering.UnexpectedComment diff --git a/lang/ja/local_o365.php b/lang/ja/local_o365.php index ffc92edaf..288a66b46 100644 --- a/lang/ja/local_o365.php +++ b/lang/ja/local_o365.php @@ -24,6 +24,9 @@ * @copyright (C) 2014 onwards Microsoft, Inc. (http://microsoft.com/) */ +// phpcs:disable moodle.Files.LangFilesOrdering.IncorrectOrder +// phpcs:disable moodle.Files.LangFilesOrdering.UnexpectedComment + $string['pluginname'] = 'Microsoft 365の統合'; $string['acp_title'] = 'Microsoft 365管理コントロールパネル'; $string['acp_healthcheck'] = '状態チェック'; @@ -141,3 +144,6 @@ $string['ucp_syncdir_both'] = 'OutlookとMoodleを両方更新する'; $string['ucp_title'] = 'Microsoft 365 / Moodleコントロールパネル'; $string['ucp_options'] = 'オプション'; + +// phpcs:enable moodle.Files.LangFilesOrdering.IncorrectOrder +// phpcs:enable moodle.Files.LangFilesOrdering.UnexpectedComment diff --git a/lang/nl/local_o365.php b/lang/nl/local_o365.php index 67d1a6a4d..4936fdf77 100644 --- a/lang/nl/local_o365.php +++ b/lang/nl/local_o365.php @@ -24,6 +24,9 @@ * @copyright (C) 2014 onwards Microsoft, Inc. (http://microsoft.com/) */ +// phpcs:disable moodle.Files.LangFilesOrdering.IncorrectOrder +// phpcs:disable moodle.Files.LangFilesOrdering.UnexpectedComment + $string['pluginname'] = 'Integratie met Microsoft 365'; $string['acp_title'] = 'Configuratiescherm voor Microsoft 365-beheer'; $string['acp_healthcheck'] = 'Statuscontrole'; @@ -141,3 +144,6 @@ $string['ucp_syncdir_both'] = 'Zowel Outlook als Moodle bijwerken'; $string['ucp_title'] = 'Microsoft 365-/Moodle-configuratiescherm'; $string['ucp_options'] = 'Opties'; + +// phpcs:enable moodle.Files.LangFilesOrdering.IncorrectOrder +// phpcs:enable moodle.Files.LangFilesOrdering.UnexpectedComment diff --git a/lang/pl/local_o365.php b/lang/pl/local_o365.php index f2e0ed25d..4d0306e90 100644 --- a/lang/pl/local_o365.php +++ b/lang/pl/local_o365.php @@ -24,6 +24,9 @@ * @copyright (C) 2014 onwards Microsoft, Inc. (http://microsoft.com/) */ +// phpcs:disable moodle.Files.LangFilesOrdering.IncorrectOrder +// phpcs:disable moodle.Files.LangFilesOrdering.UnexpectedComment + $string['pluginname'] = 'Integracja pakietu Microsoft 365'; $string['acp_title'] = 'Panel sterowania administratora pakietu Microsoft 365'; $string['acp_healthcheck'] = 'Sprawdzanie kondycji'; @@ -141,3 +144,6 @@ $string['ucp_syncdir_both'] = 'Zaktualizuj dane w programie Outlook i na platformie Moodle'; $string['ucp_title'] = 'Panel sterowania pakietu Microsoft 365 / platformy Moodle'; $string['ucp_options'] = 'Opcje'; + +// phpcs:enable moodle.Files.LangFilesOrdering.IncorrectOrder +// phpcs:enable moodle.Files.LangFilesOrdering.UnexpectedComment diff --git a/lang/pt_br/local_o365.php b/lang/pt_br/local_o365.php index 9bf145cac..6ca999212 100644 --- a/lang/pt_br/local_o365.php +++ b/lang/pt_br/local_o365.php @@ -24,6 +24,9 @@ * @copyright (C) 2014 onwards Microsoft, Inc. (http://microsoft.com/) */ +// phpcs:disable moodle.Files.LangFilesOrdering.IncorrectOrder +// phpcs:disable moodle.Files.LangFilesOrdering.UnexpectedComment + $string['pluginname'] = 'Integração ao Microsoft 365'; $string['acp_title'] = 'Painel de controle de administração do Microsoft 365'; $string['acp_healthcheck'] = 'Verificação de integridade'; @@ -141,3 +144,6 @@ $string['ucp_syncdir_both'] = 'Atualizar tanto o Outlook quanto o Moodle'; $string['ucp_title'] = 'Painel de controle do Microsoft 365/Moodle'; $string['ucp_options'] = 'Opções'; + +// phpcs:enable moodle.Files.LangFilesOrdering.IncorrectOrder +// phpcs:enable moodle.Files.LangFilesOrdering.UnexpectedComment diff --git a/lib.php b/lib.php index d7d634d2c..565c3dec6 100644 --- a/lib.php +++ b/lib.php @@ -30,50 +30,76 @@ /** * TEAMS_MOODLE_APP_EXTERNAL_ID - app ID used to create Teams Moodle app. */ +/** @var string default teams Moodle app external ID. */ const TEAMS_MOODLE_APP_EXTERNAL_ID = '2e43119b-fcfe-44f8-b3e5-996ffcb7fb95'; // Teams/group course reset site settings. +/** @var int course reset site action Do nothing. */ const COURSE_SYNC_RESET_SITE_SETTING_DO_NOTHING = '1'; +/** @var int course reset site action allow configuration per course. */ const COURSE_SYNC_RESET_SITE_SETTING_PER_COURSE = '2'; +/** @var int course reset site action disconnect and create new. */ const COURSE_SYNC_RESET_SITE_SETTING_DISCONNECT_AND_CREATE_NEW = '3'; +/** @var int course reset site action disconnect only. */ const COURSE_SYNC_RESET_SITE_SETTING_DISCONNECT_ONLY = '4'; // Course reset course settings. +/** @var int course reset action do nothing. */ const COURSE_SYNC_RESET_COURSE_SETTING_DO_NOTHING = '1'; +/** @var int course reset course action disconnect and create new. */ const COURSE_SYNC_RESET_COURSE_SETTING_DISCONNECT_AND_CREATE_NEW = '2'; +/** @var int course reset course action disconnect only. */ const COURSE_SYNC_RESET_COURSE_SETTING_DISCONNECT_ONLY = '3'; // Course sync options. +/** @var int course sync disabled. */ const MICROSOFT365_COURSE_SYNC_DISABLED = 0; +/** @var int course sync enabled. */ const MICROSOFT365_COURSE_SYNC_ENABLED = 1; // Configuration tabs. -const LOCAL_O365_TAB_SETUP = 0; // Setup settings. -const LOCAL_O365_TAB_SYNC = 1; // Sync settings. -const LOCAL_O365_TAB_ADVANCED = 2; // Admin tools + advanced settings. -const LOCAL_O365_TAB_SDS = 3; // School data sync. -const LOCAL_O365_TAB_TEAMS = 5; // Teams integration settings. -const LOCAL_O365_TAB_MOODLE_APP = 6; // Teams Moodle app. +/** @var int configuration tab "Setup settings". */ +const LOCAL_O365_TAB_SETUP = 0; +/** @var int configuration tab "Sync settings". */ +const LOCAL_O365_TAB_SYNC = 1; +/** @var int configuration tab "Admin tools + advanced settings.". */ +const LOCAL_O365_TAB_ADVANCED = 2; +/** @var int configuration tab "School data sync". */ +const LOCAL_O365_TAB_SDS = 3; +/** @var int configuration tab "Teams integration settings". */ +const LOCAL_O365_TAB_TEAMS = 5; +/** @var int configuration tab "Teams Moodle app". */ +const LOCAL_O365_TAB_MOODLE_APP = 6; // Group roles. +/** @var int group role owner */ const MICROSOFT365_GROUP_ROLE_OWNER = 'owner'; +/** @var int group role member */ const MICROSOFT365_GROUP_ROLE_MEMBER = 'member'; // Team lock status. +/** @var int team locking status unknown */ const TEAM_LOCKED_STATUS_UNKNOWN = 0; +/** @var int team locking status locked */ const TEAM_LOCKED = 1; +/** @var int team locking status unlocked */ const TEAM_UNLOCKED = 2; -// Education license. +/** @var array education license */ const EDUCATION_LICENSE_IDS = ['c33802dd-1b50-4b9a-8bb9-f13d2cdeadac', '500b6a2a-7a50-4f40-b5f9-160e5b8c2f48']; // SDS sync school disabled actions. +/** @var int SDS school disabled action keep connected */ const SDS_SCHOOL_DISABLED_ACTION_KEEP_CONNECTED = 1; +/** @var int SDS school disabled action disconnect */ const SDS_SCHOOL_DISABLED_ACTION_DISCONNECT = 2; // Course user sync directions. +/** @var int course user sync direction from Moodle to teams */ const COURSE_USER_SYNC_DIRECTION_MOODLE_TO_TEAMS = 1; +/** @var int course user sync direction from teams to Moodle */ const COURSE_USER_SYNC_DIRECTION_TEAMS_TO_MOODLE = 2; +/** @var int course user sync direction both */ const COURSE_USER_SYNC_DIRECTION_BOTH = 3; /** @@ -120,7 +146,7 @@ function local_o365_rmdir($path) { * * @return string[] */ -function local_o365_create_manifest_file() : array { +function local_o365_create_manifest_file(): array { global $CFG; // Task 1: prepare manifest folder. @@ -283,11 +309,12 @@ function local_o365_set_default_user_sync_suspension_feature_schedule() { */ function local_o365_get_duplicate_emails() { global $DB; - + $sql = 'SELECT LOWER(email) FROM {user} WHERE deleted = 0 and suspended = 0 GROUP BY LOWER(email) HAVING COUNT(*) > 1'; $records = $DB->get_records_sql($sql); + return array_keys($records); } diff --git a/sass/styles.scss b/sass/styles.scss deleted file mode 100644 index 41831ed7c..000000000 --- a/sass/styles.scss +++ /dev/null @@ -1,129 +0,0 @@ -.local_o365_statusmessage { - &.alert { - margin-bottom: 0.25rem; - } - img { - margin-right: 0.25rem; - } - span, a { - vertical-align: middle; - } -} - -#local_o365_admin-verifysetup { - button.refreshperms { - margin: 0 0 0.75rem; - } -} - -.local_o365_adminsetting_verifysetup_results { - section { - margin-bottom: 1rem; - h5 { - margin: 0 0 0.25rem; - } - } -} - -.local_o365_ucp_index { - .connectionstatus { - float: right; - width: 14rem; - padding: 0.5rem; - img { - float: left; - padding: 0.25rem; - } - small { - font-weight: bold; - font-size: 0.8rem; - } - img.smallicon { - width: 12px; - height: 12px; - } - } - .local_o365_features { - margin-right: 16rem; - > div { - margin-bottom: 1rem; - a, b { - background-position: 2px 0px; - background-size: 28px; - background-repeat: no-repeat; - background-color: transparent; - display: inline-block; - padding: 4px 4px 4px 40px; - } - } - .local_o365_feature_connection { - a, b { - background-image: url([[pix:local_o365|o365color]]); - } - } - .local_o365_feature_calendar a, .local_o365_feature_calendar b { - background-image: url([[pix:local_o365|outlookcolor]]); - } - .local_o365_feature_onenote a, .local_o365_feature_onenote b { - background-image: url([[pix:local_o365|onenotecolor]]); - } - } -} - -.local_o365_ucp_featurepage { - h3.local_o365_featureheader { - background-position: center left; - background-size: 28px; - background-repeat: no-repeat; - background-color: transparent; - padding: 4px 4px 4px 35px; - &.local_o365_feature_calendar { - background-image: url([[pix:local_o365|outlookcolor]]); - } - &.local_o365_feature_onenote { - background-image: url([[pix:local_o365|onenotecolor]]); - } - } - &.local_o365_feature_connection { - h3.local_o365_featureheader { - background-image: url([[pix:local_o365|o365color]]); - } - div.connectionstatus { - margin: 2rem 0; - } - div.local_o365_connectionoption { - margin: 0 0 1rem; - padding: 1rem; - h4 { - margin-top: 0; - } - } - } -} - -.local_o365_o365toollink { - margin-bottom: 1rem; -} - -.local_o365_matchqueuetoolbar { - margin: 0.75rem 0 0.5rem 0; -} - -table.local_o365_matchqueue { - width: 100%; - td, th { - padding: 0.25rem 0.5rem; - vertical-align: top; - &:first-child { - width: 1.5rem; - text-align: center; - } - } - -} - -/* Display spinner while course data is syncing. */ -.local_o365_spinner { - margin: 0 0 1em 1em; - display: none; -} diff --git a/settings.php b/settings.php index 93fd3840b..33ab9fd2f 100644 --- a/settings.php +++ b/settings.php @@ -297,7 +297,7 @@ get_string('settings_team_name_sync_desc', 'local_o365'), 0)); - // Cohort Sync section + // Cohort Sync section. $label = new lang_string('settings_secthead_cohortsync', 'local_o365'); $desc = new lang_string('settings_secthead_cohortsync_desc', 'local_o365'); $settings->add(new admin_setting_heading('local_o365_section_cohortsync', $label, $desc)); diff --git a/sso_end.php b/sso_end.php index b50f2765b..bce43ee6f 100644 --- a/sso_end.php +++ b/sso_end.php @@ -23,6 +23,7 @@ * @copyright (C) 2018 onwards Microsoft, Inc. (http://microsoft.com/) */ +// phpcs:ignore moodle.Files.RequireLogin.Missing -- This file is called from Microsoft Teams tab. require_once(__DIR__ . '/../../config.php'); echo ""; diff --git a/sso_login.php b/sso_login.php index 34614234f..04a306dde 100644 --- a/sso_login.php +++ b/sso_login.php @@ -23,6 +23,7 @@ * @copyright (C) 2018 onwards Microsoft, Inc. (http://microsoft.com/) */ +// phpcs:ignore moodle.Files.RequireLogin.Missing -- This file is called from Microsoft Teams tab. require_once(__DIR__ . '/../../config.php'); require_once($CFG->dirroot . '/local/o365/lib.php'); diff --git a/sso_start.php b/sso_start.php index 4bce93923..9affbf8e3 100644 --- a/sso_start.php +++ b/sso_start.php @@ -23,6 +23,7 @@ * @copyright (C) 2018 onwards Microsoft, Inc. (http://microsoft.com/) */ +// phpcs:ignore moodle.Files.RequireLogin.Missing -- This file is called from Microsoft Teams tab. require_once(__DIR__ . '/../../config.php'); echo ""; diff --git a/styles.css b/styles.css index b55feca12..be654a889 100644 --- a/styles.css +++ b/styles.css @@ -6,7 +6,8 @@ margin-right: 0.25rem; } -.local_o365_statusmessage span, .local_o365_statusmessage a { +.local_o365_statusmessage span, +.local_o365_statusmessage a { vertical-align: middle; } @@ -51,8 +52,9 @@ margin-bottom: 1rem; } -.local_o365_ucp_index .local_o365_features > div a, .local_o365_ucp_index .local_o365_features > div b { - background-position: 2px 0px; +.local_o365_ucp_index .local_o365_features > div a, +.local_o365_ucp_index .local_o365_features > div b { + background-position: 2px 0; background-size: 28px; background-repeat: no-repeat; background-color: transparent; @@ -60,15 +62,18 @@ padding: 4px 4px 4px 40px; } -.local_o365_ucp_index .local_o365_features .local_o365_feature_connection a, .local_o365_ucp_index .local_o365_features .local_o365_feature_connection b { +.local_o365_ucp_index .local_o365_features .local_o365_feature_connection a, +.local_o365_ucp_index .local_o365_features .local_o365_feature_connection b { background-image: url([[pix:local_o365|o365color]]); } -.local_o365_ucp_index .local_o365_features .local_o365_feature_calendar a, .local_o365_ucp_index .local_o365_features .local_o365_feature_calendar b { +.local_o365_ucp_index .local_o365_features .local_o365_feature_calendar a, +.local_o365_ucp_index .local_o365_features .local_o365_feature_calendar b { background-image: url([[pix:local_o365|outlookcolor]]); } -.local_o365_ucp_index .local_o365_features .local_o365_feature_onenote a, .local_o365_ucp_index .local_o365_features .local_o365_feature_onenote b { +.local_o365_ucp_index .local_o365_features .local_o365_feature_onenote a, +.local_o365_ucp_index .local_o365_features .local_o365_feature_onenote b { background-image: url([[pix:local_o365|onenotecolor]]); } @@ -117,12 +122,14 @@ table.local_o365_matchqueue { width: 100%; } -table.local_o365_matchqueue td, table.local_o365_matchqueue th { +table.local_o365_matchqueue td, +table.local_o365_matchqueue th { padding: 0.25rem 0.5rem; vertical-align: top; } -table.local_o365_matchqueue td:first-child, table.local_o365_matchqueue th:first-child { +table.local_o365_matchqueue td:first-child, +table.local_o365_matchqueue th:first-child { width: 1.5rem; text-align: center; } @@ -139,8 +146,8 @@ select#id_local_o365_teams_course select::-webkit-scrollbar { } select#id_local_o365_teams_course::-webkit-scrollbar-track { - box-shadow: inset 0 0 0px grey; - border-radius: 0px; + box-shadow: inset 0 0 0 grey; + border-radius: 0; } select#id_local_o365_teams_course::-webkit-scrollbar-thumb { @@ -172,8 +179,8 @@ select#id_local_o365_teams_course { } select#id_local_o365_teams_course:focus { - outline-offset: 0px !important; - outline: none !important; + outline-offset: 0; + outline: none; } select#id_local_o365_teams_course option { @@ -194,7 +201,7 @@ form#local_o365_course_list { /* Teams tab page. */ #id_local_o365_teams_tab_name { background-color: #f0f2f4; - border: 0px; + border: 0; padding: 8px 8px 8px 12px; width: 100%; margin-bottom: 20px; @@ -215,7 +222,7 @@ div.local_o365_manual_login { } button.local_o365_manual_login_button { - font-family: "Segoe UI", "Helvetica Neue", "Apple Color Emoji", "Segoe UI Emoji", Helvetica, Arial, sans-serif !important; + font-family: "Segoe UI", "Helvetica Neue", "Apple Color Emoji", "Segoe UI Emoji", Helvetica, Arial, sans-serif; display: block; width: 200px; background: #6264a7; @@ -228,9 +235,9 @@ button.local_o365_manual_login_button { min-width: 6rem; padding: 0.25rem; white-space: nowrap; - -webkit-box-shadow: unset !important; - box-shadow: unset !important; - color: #FFF; + -webkit-box-shadow: unset; + box-shadow: unset; + color: #fff; margin: 5px; } @@ -240,13 +247,11 @@ button.local_o365_manual_login_button:not(:disabled):not(.disabled):active { color: #201f1f; } -button.local_o365_manual_login_button:hover, button.local_o365_manual_login_button.enabled { +button.local_o365_manual_login_button:hover, +button.local_o365_manual_login_button.enabled { background: #464775; border-color: transparent; - color: #FFF; -} - -button.local_o365_manual_login_button:focus, button.local_o365_manual_login_button:focus:enabled { + color: #fff; } .local_o365_acp_option { @@ -255,11 +260,11 @@ button.local_o365_manual_login_button:focus, button.local_o365_manual_login_butt } .local_o365_settings_manifest_container { - margin: 40px 0px 20px 0px; + margin: 40px 0 20px 0; } .local_o365_settings_teams_banner_part_1 { - margin: 30px 40px 0px 40px; + margin: 30px 40px 0 40px; text-align: center; } @@ -283,7 +288,7 @@ button.local_o365_manual_login_button:focus, button.local_o365_manual_login_butt } .local_o365_settings_teams_h4_spacer { - margin: 20px 0px 30px 0px; + margin: 20px 0 30px 0; border-top: 1px solid #e9ecef; padding-top: 10px; } diff --git a/teams_tab.php b/teams_tab.php index ddf686038..fb9789943 100644 --- a/teams_tab.php +++ b/teams_tab.php @@ -23,6 +23,7 @@ * @copyright (C) 2018 onwards Microsoft, Inc. (http://microsoft.com/) */ +// phpcs:ignore moodle.Files.RequireLogin.Missing -- This file is called from Microsoft Teams tab. require_once(__DIR__ . '/../../config.php'); // Force theme. @@ -58,10 +59,10 @@ echo html_writer::start_div('local_o365_manual_login'); // Microsoft Entra ID login box. echo html_writer::tag('button', get_string('sso_login', 'local_o365'), - array('onclick' => 'login()', 'class' => 'local_o365_manual_login_button')); + ['onclick' => 'login()', 'class' => 'local_o365_manual_login_button']); // Manual login link. echo html_writer::tag('button', get_string('other_login', 'local_o365'), - array('onclick' => 'otherLogin()', 'class' => 'local_o365_manual_login_button')); + ['onclick' => 'otherLogin()', 'class' => 'local_o365_manual_login_button']); echo html_writer::end_div(); $SESSION->wantsurl = $coursepageurl; diff --git a/teams_tab_configuration.php b/teams_tab_configuration.php index cea7ae27d..3ac35e101 100644 --- a/teams_tab_configuration.php +++ b/teams_tab_configuration.php @@ -23,6 +23,7 @@ * @copyright (C) 2018 onwards Microsoft, Inc. (http://microsoft.com/) */ +// phpcs:ignore moodle.Files.RequireLogin.Missing -- This file is called from Microsoft Teams tab. require_once(__DIR__ . '/../../config.php'); $url = new moodle_url('/local/o365/teams_tab_configuration.php'); diff --git a/teams_tab_redirect.php b/teams_tab_redirect.php index 6a13e8005..35bd5404d 100644 --- a/teams_tab_redirect.php +++ b/teams_tab_redirect.php @@ -23,6 +23,7 @@ * @copyright (C) 2018 onwards Microsoft, Inc. (http://microsoft.com/) */ +// phpcs:ignore moodle.Files.RequireLogin.Missing -- This file is called from Microsoft Teams tab. require_once(__DIR__ . '/../../config.php'); unset($SESSION->theme); diff --git a/tests/coursesyncutils_test.php b/tests/coursesyncutils_test.php index 5aac422e0..b6a864b7c 100644 --- a/tests/coursesyncutils_test.php +++ b/tests/coursesyncutils_test.php @@ -24,108 +24,120 @@ * @copyright (C) 2014 onwards Microsoft, Inc. (http://microsoft.com/) */ +namespace local_o365; + +use externallib_advanced_testcase; +use local_o365\feature\coursesync\utils; + defined('MOODLE_INTERNAL') || die(); global $CFG; -require_once($CFG->dirroot.'/webservice/tests/helpers.php'); +require_once($CFG->dirroot . '/webservice/tests/helpers.php'); /** * Tests \local_o365\feature\coursesync\utils. * * @group local_o365 */ -class local_o365_coursesyncutils_testcase extends \externallib_advanced_testcase { +final class coursesyncutils_test extends externallib_advanced_testcase { /** * Perform setup before every test. This tells Moodle's phpunit to reset the database after every test. */ - protected function setUp() : void { + protected function setUp(): void { parent::setUp(); $this->resetAfterTest(true); } /** * Test is_enabled() method. + * + * @covers \local_o365\feature\coursesync\utils::is_enabled */ - public function test_is_enabled() { + public function test_is_enabled(): void { global $DB; $DB->delete_records('config_plugins', ['name' => 'coursesync', 'plugin' => 'local_o365']); - $this->assertFalse(\local_o365\feature\coursesync\utils::is_enabled()); + $this->assertFalse(utils::is_enabled()); set_config('coursesync', '', 'local_o365'); - $this->assertFalse(\local_o365\feature\coursesync\utils::is_enabled()); + $this->assertFalse(utils::is_enabled()); set_config('coursesync', 'onall', 'local_o365'); - $this->assertTrue(\local_o365\feature\coursesync\utils::is_enabled()); + $this->assertTrue(utils::is_enabled()); set_config('coursesync', 'off', 'local_o365'); - $this->assertFalse(\local_o365\feature\coursesync\utils::is_enabled()); + $this->assertFalse(utils::is_enabled()); set_config('coursesync', 'oncustom', 'local_o365'); - $this->assertTrue(\local_o365\feature\coursesync\utils::is_enabled()); + $this->assertTrue(utils::is_enabled()); set_config('coursesync', 'off', 'local_o365'); - $this->assertFalse(\local_o365\feature\coursesync\utils::is_enabled()); + $this->assertFalse(utils::is_enabled()); } /** * Test get_enabled_courses() method. + * + * @covers \local_o365\feature\coursesync\utils::get_enabled_courses */ - public function test_get_enabled_courses() { + public function test_get_enabled_courses(): void { global $DB; $DB->delete_records('config_plugins', ['name' => 'coursesync', 'plugin' => 'local_o365']); - $actual = \local_o365\feature\coursesync\utils::get_enabled_courses(); + $actual = utils::get_enabled_courses(); $this->assertIsArray($actual); $this->assertEmpty($actual); set_config('coursesync', 'off', 'local_o365'); set_config('coursesynccustom', json_encode([1 => 1]), 'local_o365'); - $actual = \local_o365\feature\coursesync\utils::get_enabled_courses(); + $actual = utils::get_enabled_courses(); $this->assertIsArray($actual); $this->assertEmpty($actual); set_config('coursesync', 'onall', 'local_o365'); set_config('coursesynccustom', json_encode([1 => 1]), 'local_o365'); - $actual = \local_o365\feature\coursesync\utils::get_enabled_courses(); + $actual = utils::get_enabled_courses(); $this->assertTrue($actual); set_config('coursesync', 'oncustom', 'local_o365'); set_config('coursesynccustom', json_encode([1 => 1]), 'local_o365'); - $actual = \local_o365\feature\coursesync\utils::get_enabled_courses(); + $actual = utils::get_enabled_courses(); $this->assertIsArray($actual); $this->assertEquals([1], $actual); } /** * Test course_is_group_enabled() method. + * + * @covers \local_o365\feature\coursesync\utils::is_course_sync_enabled */ - public function test_course_is_group_enabled() { + public function test_course_is_group_enabled(): void { global $DB; + $DB->delete_records('config_plugins', ['name' => 'coursesync', 'plugin' => 'local_o365']); $DB->delete_records('config_plugins', ['name' => 'coursesynccustom', 'plugin' => 'local_o365']); - $actual = \local_o365\feature\coursesync\utils::is_course_sync_enabled(3); + $actual = utils::is_course_sync_enabled(3); $this->assertFalse($actual); set_config('coursesync', 'off', 'local_o365'); set_config('coursesynccustom', json_encode([1 => 1, 3 => 1]), 'local_o365'); - $actual = \local_o365\feature\coursesync\utils::is_course_sync_enabled(3); + $actual = utils::is_course_sync_enabled(3); $this->assertFalse($actual); set_config('coursesync', 'onall', 'local_o365'); set_config('coursesynccustom', json_encode([2 => 1]), 'local_o365'); - $actual = \local_o365\feature\coursesync\utils::is_course_sync_enabled(3); + $actual = utils::is_course_sync_enabled(3); $this->assertTrue($actual); set_config('coursesync', 'oncustom', 'local_o365'); set_config('coursesynccustom', json_encode([2 => 1]), 'local_o365'); - $actual = \local_o365\feature\coursesync\utils::is_course_sync_enabled(3); + $actual = utils::is_course_sync_enabled(3); $this->assertFalse($actual); set_config('coursesync', 'oncustom', 'local_o365'); set_config('coursesynccustom', json_encode([2 => 1, 3 => 1]), 'local_o365'); - $actual = \local_o365\feature\coursesync\utils::is_course_sync_enabled(3); + $actual = utils::is_course_sync_enabled(3); $this->assertTrue($actual); } } diff --git a/tests/observers_test.php b/tests/observers_test.php index 9bd5e7200..fa345e29c 100644 --- a/tests/observers_test.php +++ b/tests/observers_test.php @@ -23,29 +23,31 @@ * @copyright (C) 2016 onwards Microsoft, Inc. (http://microsoft.com/) */ -defined('MOODLE_INTERNAL') || die(); +namespace local_o365; + +use advanced_testcase; /** * Tests event observers. * * @group local_o365 * @group office365 - * @codeCoverageIgnore */ -class local_o365_observers_testcase extends \advanced_testcase { +final class observers_test extends advanced_testcase { /** * Perform setup before every test. This tells Moodle's phpunit to reset the database after every test. */ - protected function setUp() : void { + protected function setUp(): void { parent::setUp(); $this->resetAfterTest(true); } /** * Test users disconnect method. + * + * @covers \local_o365\observers::handle_oidc_user_disconnected */ - public function test_user_disconnected() { - global $DB; + public function test_user_disconnected(): void { $user = $this->getDataGenerator()->create_user(['auth' => 'oidc']); $this->create_member_entities($user->id); $this->assertTrue($this->has_member_entities($user->id)); @@ -57,9 +59,10 @@ public function test_user_disconnected() { /** * Test users deleted method. + * + * @covers \local_o365\observers::handle_user_deleted */ - public function test_user_deleted() { - global $DB; + public function test_user_deleted(): void { $user = $this->getDataGenerator()->create_user(['auth' => 'oidc']); $this->create_member_entities($user->id); $this->assertTrue($this->has_member_entities($user->id)); @@ -74,7 +77,7 @@ public function test_user_deleted() { */ public function create_member_entities($userid) { global $DB; - $token = (object)[ + $token = (object) [ 'user_id' => $userid, 'scope' => 'scope', 'tokenresource' => 'resource', @@ -83,7 +86,7 @@ public function create_member_entities($userid) { 'refreshtoken' => time() + 100000, ]; $DB->insert_record('local_o365_token', $token); - $entraiduserdata = (object)[ + $entraiduserdata = (object) [ 'type' => 'user', 'subtype' => '', 'objectid' => '', @@ -94,7 +97,7 @@ public function create_member_entities($userid) { ]; $DB->insert_record('local_o365_objects', $entraiduserdata); $DB->insert_record('local_o365_connections', ['muserid' => $userid]); - $object = (object)[ + $object = (object) [ 'muserid' => $userid, 'assigned' => 1, 'photoid' => 'abc', @@ -114,6 +117,7 @@ public function has_member_entities($userid) { $result = $DB->count_records('local_o365_token', ['user_id' => $userid]); $result = $result || $DB->count_records('local_o365_objects', ['type' => 'user', 'moodleid' => $userid]); $result = $result || $DB->count_records('local_o365_connections', ['muserid' => $userid]); + return $result || $DB->count_records('local_o365_appassign', ['muserid' => $userid]); } } diff --git a/tests/privacy_provider_test.php b/tests/privacy_provider_test.php index bbf3914ed..d076e382a 100644 --- a/tests/privacy_provider_test.php +++ b/tests/privacy_provider_test.php @@ -23,9 +23,16 @@ * @copyright (C) 2019 Remote Learner.net Inc http://www.remote-learner.net */ -defined('MOODLE_INTERNAL') || die(); +namespace local_o365; -use \local_o365\privacy\provider; +use context_system; +use context_user; +use core_privacy\local\request\approved_contextlist; +use core_privacy\local\request\userlist; +use core_privacy\local\request\writer; +use core_privacy\tests\provider_testcase; +use local_o365\privacy\provider; +use stdClass; /** * Privacy test for the local_o365 @@ -35,19 +42,21 @@ * @group office365 * @group office365_privacy */ -class local_o365_privacy_testcase extends \core_privacy\tests\provider_testcase { +final class privacy_provider_test extends provider_testcase { /** * Tests set up. */ - protected function setUp() : void { + protected function setUp(): void { $this->resetAfterTest(); $this->setAdminUser(); } /** * Check that a user context is returned if there is any user data for this user. + * + * @covers \local_o365\privacy\provider::get_contexts_for_userid */ - public function test_get_contexts_for_userid() { + public function test_get_contexts_for_userid(): void { $user = $this->getDataGenerator()->create_user(); $this->assertEmpty(provider::get_contexts_for_userid($user->id)); @@ -59,14 +68,16 @@ public function test_get_contexts_for_userid() { $this->assertCount(1, $contextlist); // Check that a context is returned and is the expected context. - $usercontext = \context_user::instance($user->id); + $usercontext = context_user::instance($user->id); $this->assertEquals($usercontext->id, $contextlist->get_contextids()[0]); } /** * Test that only users with a user context are fetched. + * + * @covers \local_o365\privacy\provider::get_users_in_context */ - public function test_get_users_in_context() { + public function test_get_users_in_context(): void { $this->resetAfterTest(); $component = 'local_o365'; @@ -75,7 +86,7 @@ public function test_get_users_in_context() { $usercontext = context_user::instance($user->id); // The list of users should not return anything yet (related data still haven't been created). - $userlist = new \core_privacy\local\request\userlist($usercontext, $component); + $userlist = new userlist($usercontext, $component); provider::get_users_in_context($userlist); $this->assertCount(0, $userlist); @@ -90,49 +101,53 @@ public function test_get_users_in_context() { $this->assertEquals($expected, $actual); // The list of users for system context should not return any users. - $userlist = new \core_privacy\local\request\userlist(context_system::instance(), $component); + $userlist = new userlist(context_system::instance(), $component); provider::get_users_in_context($userlist); $this->assertCount(0, $userlist); } /** * Test that user data is exported correctly. + * + * @covers \local_o365\privacy\provider::export_user_data */ - public function test_export_user_data() { + public function test_export_user_data(): void { // Create a user record. $user = $this->getDataGenerator()->create_user(); // Create user records. $userrecords = self::create_userdata($user->id); - $usercontext = \context_user::instance($user->id); + $usercontext = context_user::instance($user->id); - $writer = \core_privacy\local\request\writer::with_context($usercontext); + $writer = writer::with_context($usercontext); $this->assertFalse($writer->has_any_data()); - $approvedlist = new core_privacy\local\request\approved_contextlist($user, 'local_o365', [$usercontext->id]); + $approvedlist = new approved_contextlist($user, 'local_o365', [$usercontext->id]); provider::export_user_data($approvedlist); foreach ($userrecords as $table => $record) { $data = $writer->get_data([ get_string('privacy:metadata:local_o365', 'local_o365'), - get_string('privacy:metadata:'.$table, 'local_o365') + get_string('privacy:metadata:' . $table, 'local_o365'), ]); foreach ($record as $k => $v) { - $this->assertEquals((string)$v, $data->$k); + $this->assertEquals((string) $v, $data->$k); } } } /** * Test deleting all user data for a specific context. + * + * @covers \local_o365\privacy\provider::delete_data_for_all_users_in_context */ - public function test_delete_data_for_all_users_in_context() { + public function test_delete_data_for_all_users_in_context(): void { global $DB; // Create user data. $user1 = $this->getDataGenerator()->create_user(); $user1records = self::create_userdata($user1->id); - $user1context = \context_user::instance($user1->id); + $user1context = context_user::instance($user1->id); $user2 = $this->getDataGenerator()->create_user(); $user2records = self::create_userdata($user2->id); @@ -162,14 +177,16 @@ public function test_delete_data_for_all_users_in_context() { /** * This should work identical to the above test. + * + * @covers \local_o365\privacy\provider::delete_data_for_all_users_in_context */ - public function test_delete_data_for_user() { + public function test_delete_data_for_user(): void { global $DB; // Create a user record. $user1 = $this->getDataGenerator()->create_user(); $user1records = self::create_userdata($user1->id); - $user1context = \context_user::instance($user1->id); + $user1context = context_user::instance($user1->id); $user2 = $this->getDataGenerator()->create_user(); $user2records = self::create_userdata($user2->id); @@ -180,7 +197,7 @@ public function test_delete_data_for_user() { } // Delete everything for the first user. - $approvedlist = new \core_privacy\local\request\approved_contextlist($user1, 'local_o365', [$user1context->id]); + $approvedlist = new approved_contextlist($user1, 'local_o365', [$user1context->id]); provider::delete_data_for_user($approvedlist); $this->assertCount(0, $DB->get_records('local_o365_calidmap', ['userid' => $user1->id])); @@ -200,8 +217,10 @@ public function test_delete_data_for_user() { /** * Test that data for users in approved userlist is deleted. + * + * @covers \local_o365\privacy\provider::delete_data_for_users */ - public function test_delete_data_for_users() { + public function test_delete_data_for_users(): void { $this->resetAfterTest(); $component = 'local_o365'; @@ -216,7 +235,7 @@ public function test_delete_data_for_users() { $usercontext2 = context_user::instance($user2->id); // The list of users for usercontext1 should return user1. - $userlist1 = new \core_privacy\local\request\userlist($usercontext1, $component); + $userlist1 = new userlist($usercontext1, $component); provider::get_users_in_context($userlist1); $this->assertCount(1, $userlist1); $expected = [$user1->id]; @@ -224,7 +243,7 @@ public function test_delete_data_for_users() { $this->assertEquals($expected, $actual); // The list of users for usercontext2 should return user2. - $userlist2 = new \core_privacy\local\request\userlist($usercontext2, $component); + $userlist2 = new userlist($usercontext2, $component); provider::get_users_in_context($userlist2); $this->assertCount(1, $userlist2); $expected = [$user2->id]; @@ -238,11 +257,11 @@ public function test_delete_data_for_users() { provider::delete_data_for_users($approvedlist); // Re-fetch users in usercontext1 - The user list should now be empty. - $userlist1 = new \core_privacy\local\request\userlist($usercontext1, $component); + $userlist1 = new userlist($usercontext1, $component); provider::get_users_in_context($userlist1); $this->assertCount(0, $userlist1); // Re-fetch users in usercontext2 - The user list should not be empty (user2). - $userlist2 = new \core_privacy\local\request\userlist($usercontext2, $component); + $userlist2 = new userlist($usercontext2, $component); provider::get_users_in_context($userlist2); $this->assertCount(1, $userlist2); @@ -253,7 +272,7 @@ public function test_delete_data_for_users() { // Delete user1 data using delete_data_for_user. provider::delete_data_for_users($approvedlist); // Re-fetch users in usercontext2 - The user list should not be empty (user2). - $userlist2 = new \core_privacy\local\request\userlist($usercontext2, $component); + $userlist2 = new userlist($usercontext2, $component); provider::get_users_in_context($userlist2); $this->assertCount(1, $userlist2); } @@ -275,6 +294,7 @@ private static function create_userdata(int $userid) { 'local_o365_matchqueue' => self::create_matchqueue($userid), 'local_o365_calsettings' => self::create_calsettings($userid), ]; + return $records; } @@ -292,6 +312,7 @@ private static function create_calidmap(int $userid): stdClass { $record->origin = 'moodle'; $record->userid = $userid; $record->id = $DB->insert_record('local_o365_calidmap', $record); + return $record; } @@ -312,6 +333,7 @@ private static function create_calsub(int $userid): stdClass { $record->syncbehav = "out"; $record->timecreated = 123456; $record->id = $DB->insert_record('local_o365_calsub', $record); + return $record; } @@ -325,9 +347,10 @@ private static function create_connections(int $userid): stdClass { global $DB; $record = new stdClass(); $record->muserid = $userid; - $record->entraidupn = "user".$userid."@example.com"; + $record->entraidupn = "user" . $userid . "@example.com"; $record->uselogin = 1; $record->id = $DB->insert_record('local_o365_connections', $record); + return $record; } @@ -347,6 +370,7 @@ private static function create_token(int $userid): stdClass { $record->expiry = 123456; $record->refreshtoken = 'refreshtoken1234567'; $record->id = $DB->insert_record('local_o365_token', $record); + return $record; } @@ -369,6 +393,7 @@ private static function create_objects(int $userid): stdClass { $record->timecreated = 123456; $record->timemodified = 123457; $record->id = $DB->insert_record('local_o365_objects', $record); + return $record; } @@ -386,6 +411,7 @@ private static function create_appassign(int $userid): stdClass { $record->photoid = 'photoid123'; $record->photoupdated = 123457; $record->id = $DB->insert_record('local_o365_appassign', $record); + return $record; } @@ -405,6 +431,7 @@ private static function create_matchqueue(int $userid): stdClass { $record->completed = 1; $record->errormessage = 'some error message'; $record->id = $DB->insert_record('local_o365_matchqueue', $record); + return $record; } @@ -421,6 +448,7 @@ private static function create_calsettings(int $userid): stdClass { $record->o365calid = 'calid1234'; $record->timecreated = 1234567; $record->id = $DB->insert_record('local_o365_calsettings', $record); + return $record; } diff --git a/tests/token_test.php b/tests/token_test.php index c0bf50a0c..b77d29a6a 100644 --- a/tests/token_test.php +++ b/tests/token_test.php @@ -23,28 +23,31 @@ * @copyright (C) 2014 onwards Microsoft, Inc. (http://microsoft.com/) */ -defined('MOODLE_INTERNAL') || die(); +namespace local_o365; + +use advanced_testcase; /** * Tests \local_o365\oauth2\token * * @group local_o365 * @group office365 - * @codeCoverageIgnore */ -class local_o365_oauth2_token_testcase extends \advanced_testcase { +final class token_test extends advanced_testcase { /** * Perform setup before every test. This tells Moodle's phpunit to reset the database after every test. */ - protected function setUp() : void { + protected function setUp(): void { parent::setUp(); $this->resetAfterTest(true); } /** * Test refresh method. + * + * @covers \local_o365\oauth2\token::refresh */ - public function test_refresh() { + public function test_refresh(): void { global $USER, $DB; $this->setAdminUser(); $now = time(); @@ -64,7 +67,7 @@ public function test_refresh() { 'clientid' => 'clientid', 'clientsecret' => 'clientsecret', 'authendpoint' => 'http://example.com/auth', - 'tokenendpoint' => 'http://example.com/token' + 'tokenendpoint' => 'http://example.com/token', ]; $tokenrec = (object)[ diff --git a/tests/usersync_test.php b/tests/usersync_test.php index 60780f997..f58a270c8 100644 --- a/tests/usersync_test.php +++ b/tests/usersync_test.php @@ -23,20 +23,25 @@ * @copyright (C) 2014 onwards Microsoft, Inc. (http://microsoft.com/) */ -defined('MOODLE_INTERNAL') || die(); +namespace local_o365; + +use advanced_testcase; +use local_o365\feature\usersync\main; +use local_o365\oauth2\token; +use local_o365\rest\unified; +use local_o365\tests\mockhttpclient; /** * Tests \local_o365\feature\usersync\main. * * @group local_o365 * @group office365 - * @codeCoverageIgnore */ -class local_o365_usersync_testcase extends \advanced_testcase { +final class usersync_test extends advanced_testcase { /** * Perform setup before every test. This tells Moodle's phpunit to reset the database after every test. */ - protected function setUp() : void { + protected function setUp(): void { parent::setUp(); $this->resetAfterTest(true); } @@ -44,30 +49,31 @@ protected function setUp() : void { /** * Get a mock token object to use when constructing the API client. * - * @return \local_o365\oauth2\token The mock token object. + * @return token The mock token object. */ protected function get_mock_clientdata() { - $oidcconfig = (object)[ + $oidcconfig = (object) [ 'clientid' => 'clientid', 'clientsecret' => 'clientsecret', 'authendpoint' => 'http://example.com/auth', - 'tokenendpoint' => 'http://example.com/token' + 'tokenendpoint' => 'http://example.com/token', ]; $clientdata = new \local_o365\oauth2\clientdata($oidcconfig->clientid, $oidcconfig->clientsecret, - $oidcconfig->authendpoint, $oidcconfig->tokenendpoint); + $oidcconfig->authendpoint, $oidcconfig->tokenendpoint); + return $clientdata; } /** * Get a mock token object to use when constructing the API client. * - * @return \local_o365\oauth2\token The mock token object. + * @return token The mock token object. */ protected function get_mock_token() { - $httpclient = new \local_o365\tests\mockhttpclient(); + $httpclient = new mockhttpclient(); - $tokenrec = (object)[ + $tokenrec = (object) [ 'token' => 'token', 'expiry' => time() + 1000, 'refreshtoken' => 'refreshtoken', @@ -77,8 +83,9 @@ protected function get_mock_token() { ]; $clientdata = $this->get_mock_clientdata(); - $token = new \local_o365\oauth2\token($tokenrec->token, $tokenrec->expiry, $tokenrec->refreshtoken, - $tokenrec->scope, $tokenrec->tokenresource, $tokenrec->user_id, $clientdata, $httpclient); + $token = new token($tokenrec->token, $tokenrec->expiry, $tokenrec->refreshtoken, + $tokenrec->scope, $tokenrec->tokenresource, $tokenrec->user_id, $clientdata, $httpclient); + return $token; } @@ -92,16 +99,16 @@ protected function get_entra_id_userinfo($i = 0) { return [ 'odata.type' => 'Microsoft.WindowsAzure.ActiveDirectory.User', 'objectType' => 'User', - 'objectId' => '00000000-0000-0000-0000-00000000000'.$i, - 'id' => '00000000-0000-0000-0000-00000000000'.$i, + 'objectId' => '00000000-0000-0000-0000-00000000000' . $i, + 'id' => '00000000-0000-0000-0000-00000000000' . $i, 'city' => 'Toronto', 'country' => ($i == 3) ? 'Canada' : 'CA', 'department' => 'Dev', 'givenName' => 'Test', - 'userPrincipalName' => 'testuser'.$i.'@example.onmicrosoft.com', - 'mail' => 'testuser'.$i.'@example.onmicrosoft.com', - 'surname' => 'User'.$i, + 'mail' => 'testuser' . $i . '@example.onmicrosoft.com', + 'surname' => 'User' . $i, 'preferredLanguage' => ($i == 3) ? 'sa-IN' : 'en-US', + 'userPrincipalName' => 'testuser' . $i . '@example.onmicrosoft.com', ]; } @@ -110,7 +117,7 @@ protected function get_entra_id_userinfo($i = 0) { * * @return array Array of test parameters. */ - public function dataprovider_create_user_from_entra_id_data() { + public static function dataprovider_create_user_from_entra_id_data(): array { global $CFG; $tests = []; @@ -124,9 +131,12 @@ public function dataprovider_create_user_from_entra_id_data() { 'country' => 'CA', 'department' => 'Dev', 'givenName' => 'Test', - 'userPrincipalName' => 'testuser1@example.onmicrosoft.com', 'mail' => 'testuser1@example.onmicrosoft.com', 'surname' => 'User1', + 'userPrincipalName' => 'testuser1@example.onmicrosoft.com', + 'useridentifier' => 'testuser1@example.onmicrosoft.com', + 'useridentifierlower' => 'testuser1@example.onmicrosoft.com', + 'upnsplit0' => 'testuser1', ], [ 'auth' => 'oidc', @@ -153,9 +163,12 @@ public function dataprovider_create_user_from_entra_id_data() { 'country' => 'CA', 'department' => 'Dev', 'givenName' => 'Test', - 'userPrincipalName' => 'testuser2@example.onmicrosoft.com', 'mail' => 'testuser2@example.onmicrosoft.com', 'surname' => 'User2', + 'userPrincipalName' => 'testuser2@example.onmicrosoft.com', + 'useridentifier' => 'testuser2@example.onmicrosoft.com', + 'useridentifierlower' => 'testuser2@example.onmicrosoft.com', + 'upnsplit0' => 'testuser2', ], [ 'auth' => 'oidc', @@ -181,9 +194,12 @@ public function dataprovider_create_user_from_entra_id_data() { 'id' => '00000000-0000-0000-0000-000000000003', 'department' => 'Dev', 'givenName' => 'Test', - 'userPrincipalName' => 'testuser3@example.onmicrosoft.com', 'mail' => 'testuser3@example.onmicrosoft.com', 'surname' => 'User3', + 'userPrincipalName' => 'testuser3@example.onmicrosoft.com', + 'useridentifier' => 'testuser3@example.onmicrosoft.com', + 'useridentifierlower' => 'testuser3@example.onmicrosoft.com', + 'upnsplit0' => 'testuser3', ], [ 'auth' => 'oidc', @@ -208,9 +224,12 @@ public function dataprovider_create_user_from_entra_id_data() { 'objectId' => '00000000-0000-0000-0000-000000000004', 'id' => '00000000-0000-0000-0000-000000000004', 'givenName' => 'Test', - 'userPrincipalName' => 'testuser4@example.onmicrosoft.com', 'mail' => 'testuser4@example.onmicrosoft.com', 'surname' => 'User4', + 'userPrincipalName' => 'testuser4@example.onmicrosoft.com', + 'useridentifier' => 'testuser4@example.onmicrosoft.com', + 'useridentifierlower' => 'testuser4@example.onmicrosoft.com', + 'upnsplit0' => 'testuser4', ], [ 'auth' => 'oidc', @@ -237,13 +256,15 @@ public function dataprovider_create_user_from_entra_id_data() { * @dataProvider dataprovider_create_user_from_entra_id_data * @param array $entraiddata The Microsoft Entra ID user data to create the user from. * @param array $expecteduser The expected user data to be created. + * @covers \local_o365\feature\usersync\main::create_user_from_entra_id_data */ - public function test_create_user_from_entra_id_data($entraiddata, $expecteduser) { + public function test_create_user_from_entra_id_data($entraiddata, $expecteduser): void { global $DB; - $httpclient = new \local_o365\tests\mockhttpclient(); + + $httpclient = new mockhttpclient(); $clientdata = $this->get_mock_clientdata(); - $apiclient = new \local_o365\feature\usersync\main($clientdata, $httpclient); - $apiclient->create_user_from_entra_id_data($entraiddata, []); + $usersync = new main($clientdata, $httpclient); + $usersync->create_user_from_entra_id_data($entraiddata, []); $userparams = ['auth' => 'oidc', 'username' => $entraiddata['mail'], 'firstname' => $entraiddata['givenName'], 'lastname' => $entraiddata['surname']]; @@ -257,36 +278,39 @@ public function test_create_user_from_entra_id_data($entraiddata, $expecteduser) /** * Test sync_users method when creating users. + * + * @covers \local_o365\feature\usersync\main::sync_users */ - public function test_sync_users_create() { + public function test_sync_users_create(): void { global $CFG, $DB; + set_config('usersync', 'create', 'local_o365'); for ($i = 1; $i <= 2; $i++) { $muser = [ 'auth' => 'oidc', 'deleted' => '0', 'mnethostid' => $CFG->mnet_localhost_id, - 'username' => 'testuser'.$i.'@example.onmicrosoft.com', + 'username' => 'testuser' . $i . '@example.onmicrosoft.com', 'firstname' => 'Test', - 'lastname' => 'User'.$i, - 'email' => 'testuser'.$i.'@example.onmicrosoft.com', - 'lang' => 'en' + 'lastname' => 'User' . $i, + 'email' => 'testuser' . $i . '@example.onmicrosoft.com', + 'lang' => 'en', ]; - $muser['id'] = $DB->insert_record('user', (object)$muser); + $muser['id'] = $DB->insert_record('user', (object) $muser); $token = [ - 'oidcuniqid' => '00000000-0000-0000-0000-00000000000'.$i, + 'oidcuniqid' => '00000000-0000-0000-0000-00000000000' . $i, 'authcode' => '000', - 'username' => 'testuser'.$i.'@example.onmicrosoft.com', + 'username' => 'testuser' . $i . '@example.onmicrosoft.com', 'userid' => $muser['id'], 'scope' => 'test', - 'tokenresource' => \local_o365\rest\unified::get_tokenresource(), + 'tokenresource' => unified::get_tokenresource(), 'token' => '000', 'expiry' => '9999999999', - 'refreshtoken' => 'fsdfsdf'.$i, - 'idtoken' => 'sdfsdfsdf'.$i, + 'refreshtoken' => 'fsdfsdf' . $i, + 'idtoken' => 'sdfsdfsdf' . $i, ]; - $DB->insert_record('auth_oidc_token', (object)$token); + $DB->insert_record('auth_oidc_token', (object) $token); } $response = [ @@ -297,11 +321,11 @@ public function test_sync_users_create() { ]; $response = json_encode($response); $clientdata = $this->get_mock_clientdata(); - $httpclient = new \local_o365\tests\mockhttpclient(); + $httpclient = new mockhttpclient(); $httpclient->set_response($response); - $apiclient = new \local_o365\rest\unified($this->get_mock_token(), $httpclient); - $usersync = new \local_o365\feature\usersync\main($clientdata, $httpclient); + $apiclient = new unified($this->get_mock_token(), $httpclient); + $usersync = new main($clientdata, $httpclient); $users = $apiclient->get_users(); $usersync->sync_users($users); @@ -310,6 +334,7 @@ public function test_sync_users_create() { $createduser = ['auth' => 'oidc', 'username' => 'testuser3@example.onmicrosoft.com']; $this->assertTrue($DB->record_exists('user', $createduser)); + $createduser = $DB->get_record('user', $createduser); $this->assertEquals('Test', $createduser->firstname); $this->assertEquals('User3', $createduser->lastname); diff --git a/tests/webservices_onenoteassignment_test.php b/tests/webservices_onenoteassignment_test.php index 95e0cc880..db0d5f88a 100644 --- a/tests/webservices_onenoteassignment_test.php +++ b/tests/webservices_onenoteassignment_test.php @@ -23,10 +23,16 @@ * @copyright (C) 2014 onwards Microsoft Open Technologies, Inc. (http://msopentech.com/) */ +namespace local_o365; + +use advanced_testcase; use core_external\external_function_parameters; use core_external\external_single_structure; - -defined('MOODLE_INTERNAL') || die(); +use lang_string; +use local_o365\webservices\create_onenoteassignment; +use local_o365\webservices\delete_onenoteassignment; +use local_o365\webservices\read_onenoteassignment; +use local_o365\webservices\update_onenoteassignment; /** * Tests \local_o365\webservices\utils @@ -34,27 +40,33 @@ * @group local_o365 * @group office365 */ -class local_o365_webservices_onenoteassignment_testcase extends \advanced_testcase { +final class webservices_onenoteassignment_test extends advanced_testcase { // Data structure elements of the array based on old Data Provider. + /** @var int */ const DBSTATE = 0; + /** @var int */ const PARAMS = 1; + /** @var int */ const EXPECTEDRETURN = 2; + /** @var int */ const EXPECTEDEXCEPTION = 3; /** * Perform setup before every test. This tells Moodle's phpunit to reset the database after every test. */ - protected function setUp() : void { + protected function setUp(): void { parent::setUp(); $this->resetAfterTest(true); } /** * Test assignment_create_parameters method. + * + * @covers \local_o365\webservices\create_onenoteassignment::assignment_create_parameters */ - public function test_assignment_create_parameters() { - $schema = \local_o365\webservices\create_onenoteassignment::assignment_create_parameters(); + public function test_assignment_create_parameters(): void { + $schema = create_onenoteassignment::assignment_create_parameters(); $this->assertTrue($schema instanceof external_function_parameters); $this->assertArrayHasKey('data', $schema->keys); } @@ -64,7 +76,7 @@ public function test_assignment_create_parameters() { * * @return array Array of test parameters. */ - public function dataprovider_create_assignment() { + public static function dataprovider_create_assignment(): array { return [ [ [ @@ -94,18 +106,19 @@ public function dataprovider_create_assignment() { * @dataProvider dataprovider_create_assignment * @param array $params Webservice parameters. * @param array $expectedreturn Expected return. + * @covers \local_o365\webservices\create_onenoteassignment::assignment_create */ - public function test_assignment_create($params, $expectedreturn) { + public function test_assignment_create($params, $expectedreturn): void { global $DB; $course = $this->getDataGenerator()->create_course(); if ($params['course'] === '[[courseid]]') { - $params['course'] = (int)$course->id; + $params['course'] = (int) $course->id; } $this->setAdminUser(); - $actualreturn = \local_o365\webservices\create_onenoteassignment::assignment_create($params); + $actualreturn = create_onenoteassignment::assignment_create($params); $this->assertNotEmpty($actualreturn); $this->assertArrayHasKey('data', $actualreturn); @@ -129,18 +142,22 @@ public function test_assignment_create($params, $expectedreturn) { /** * Test assignment_create_returns method. + * + * @covers \local_o365\webservices\create_onenoteassignment::assignment_create_returns */ - public function test_assignment_create_returns() { - $schema = \local_o365\webservices\create_onenoteassignment::assignment_create_returns(); + public function test_assignment_create_returns(): void { + $schema = create_onenoteassignment::assignment_create_returns(); $this->assertTrue($schema instanceof external_single_structure); $this->assertArrayHasKey('data', $schema->keys); } /** * Test assignment_read_parameters method. + * + * @covers \local_o365\webservices\read_onenoteassignment::assignment_read_parameters */ - public function test_assignment_read_parameters() { - $schema = \local_o365\webservices\read_onenoteassignment::assignment_read_parameters(); + public function test_assignment_read_parameters(): void { + $schema = read_onenoteassignment::assignment_read_parameters(); $this->assertTrue($schema instanceof external_function_parameters); $this->assertArrayHasKey('data', $schema->keys); } @@ -148,16 +165,16 @@ public function test_assignment_read_parameters() { /** * Returns a list of general data existence tests to run against any function that looks up assignment data. * - * @return [type] [description] + * @return array[] [type] [description] */ - public function get_general_assignment_data_tests() { + public static function get_general_assignment_data_tests() { global $DB; - $course = $this->getDataGenerator()->create_course(); - $assign = $this->getDataGenerator()->create_module('assign', array('course' => $course->id, - 'section' => 1, - 'name' => 'OneNote Assignment', - 'intro' => 'This is a test assignment')); + $course = static::getDataGenerator()->create_course(); + $assign = static::getDataGenerator()->create_module('assign', ['course' => $course->id, + 'section' => 1, + 'name' => 'OneNote Assignment', + 'intro' => 'This is a test assignment']); // Enable OneNote submission for this assignment. $pluginconfigparams = [ @@ -254,10 +271,10 @@ public function get_general_assignment_data_tests() { * * @return array Array of test parameters. */ - public function dataprovider_assignment_read() { + public static function dataprovider_assignment_read(): array { global $DB; - $generaltests = $this->get_general_assignment_data_tests(); + $generaltests = static::get_general_assignment_data_tests(); $return = []; foreach ($generaltests as $testkey => $parameters) { @@ -269,12 +286,12 @@ public function dataprovider_assignment_read() { 'data' => [ [ 'course' => $parameters['params']['course'], - 'coursemodule' => (string)$parameters['params']['coursemodule'], + 'coursemodule' => (string) $parameters['params']['coursemodule'], 'name' => 'OneNote Assignment', 'intro' => 'This is a test assignment', 'section' => $DB->get_field('course_sections', 'id', - array('course' => $parameters['params']['course'], - 'section' => 1)), + ['course' => $parameters['params']['course'], + 'section' => 1]), 'visible' => '1', ], ], @@ -296,10 +313,11 @@ public function dataprovider_assignment_read() { /** * Test \local_o365\webservices\read_onenoteassignment::assignment_read(). + * + * @dataProvider dataprovider_assignment_read + * @covers \local_o365\webservices\read_onenoteassignment::assignment_read */ - public function test_assignment_read() { - global $DB; - + public function test_assignment_read(): void { $dataarr = $this->dataprovider_assignment_read(); foreach ($dataarr as $data) { if (!empty($data[self::DBSTATE])) { @@ -318,7 +336,7 @@ public function test_assignment_read() { $this->setAdminUser(); - $actualreturn = \local_o365\webservices\read_onenoteassignment::assignment_read($data[self::PARAMS]); + $actualreturn = read_onenoteassignment::assignment_read($data[self::PARAMS]); $this->assertEquals($data[self::EXPECTEDRETURN], $actualreturn); } @@ -326,18 +344,22 @@ public function test_assignment_read() { /** * Test assignment_read_returns method. + * + * @covers \local_o365\webservices\read_onenoteassignment::assignment_read_returns */ - public function test_assignment_read_returns() { - $schema = \local_o365\webservices\read_onenoteassignment::assignment_read_returns(); + public function test_assignment_read_returns(): void { + $schema = read_onenoteassignment::assignment_read_returns(); $this->assertTrue($schema instanceof external_single_structure); $this->assertArrayHasKey('data', $schema->keys); } /** * Test assignment_update_parameters method. + * + * @covers \local_o365\webservices\update_onenoteassignment::assignment_update_parameters */ - public function test_assignment_update_parameters() { - $schema = \local_o365\webservices\update_onenoteassignment::assignment_update_parameters(); + public function test_assignment_update_parameters(): void { + $schema = update_onenoteassignment::assignment_update_parameters(); $this->assertTrue($schema instanceof external_function_parameters); $this->assertArrayHasKey('data', $schema->keys); } @@ -347,26 +369,24 @@ public function test_assignment_update_parameters() { * * @return array Array of test parameters. */ - public function dataprovider_assignment_update() { + public static function dataprovider_assignment_update(): array { global $DB; - $generaltests = $this->get_general_assignment_data_tests(); + $generaltests = static::get_general_assignment_data_tests(); $return = []; foreach ($generaltests as $testkey => $parameters) { if ($testkey === 'All data correct, assignment is a OneNote assignment') { - $data = array( - 'name' => 'New OneNote Assignment', - 'intro' => 'This is a test assignment', - 'newintro' => 'This is a new test assignment', - 'section' => $DB->get_field('course_sections', 'id', - array('course' => $parameters['params']['course'], - 'section' => 1)), - 'newsection' => $DB->get_field('course_sections', 'id', - array('course' => $parameters['params']['course'], - 'section' => 0)), - 'visible' => 1, - 'newvisible' => 0, - ); + $data = [ + 'name' => 'New OneNote Assignment', + 'intro' => 'This is a test assignment', + 'newintro' => 'This is a new test assignment', + 'section' => $DB->get_field('course_sections', 'id', + ['course' => $parameters['params']['course'], 'section' => 1]), + 'newsection' => $DB->get_field('course_sections', 'id', + ['course' => $parameters['params']['course'], 'section' => 0]), + 'visible' => 1, + 'newvisible' => 0, + ]; $return['Update name'] = [ $parameters['dbstate'], @@ -375,7 +395,7 @@ public function dataprovider_assignment_update() { 'data' => [ [ 'course' => $parameters['params']['course'], - 'coursemodule' => (string)$parameters['params']['coursemodule'], + 'coursemodule' => (string) $parameters['params']['coursemodule'], 'name' => $data['name'], 'intro' => $data['intro'], 'section' => $data['section'], @@ -393,7 +413,7 @@ public function dataprovider_assignment_update() { 'data' => [ [ 'course' => $parameters['params']['course'], - 'coursemodule' => (string)$parameters['params']['coursemodule'], + 'coursemodule' => (string) $parameters['params']['coursemodule'], 'name' => $data['name'], 'intro' => $data['newintro'], 'section' => $data['section'], @@ -411,7 +431,7 @@ public function dataprovider_assignment_update() { 'data' => [ [ 'course' => $parameters['params']['course'], - 'coursemodule' => (string)$parameters['params']['coursemodule'], + 'coursemodule' => (string) $parameters['params']['coursemodule'], 'name' => $data['name'], 'intro' => $data['newintro'], 'section' => $data['section'], @@ -429,7 +449,7 @@ public function dataprovider_assignment_update() { 'data' => [ [ 'course' => $parameters['params']['course'], - 'coursemodule' => (string)$parameters['params']['coursemodule'], + 'coursemodule' => (string) $parameters['params']['coursemodule'], 'name' => $data['name'], 'intro' => $data['newintro'], 'section' => $data['newsection'], @@ -447,7 +467,7 @@ public function dataprovider_assignment_update() { 'data' => [ [ 'course' => $parameters['params']['course'], - 'coursemodule' => (string)$parameters['params']['coursemodule'], + 'coursemodule' => (string) $parameters['params']['coursemodule'], 'name' => $data['name'], 'intro' => $data['newintro'], 'section' => $data['newsection'], @@ -465,8 +485,11 @@ public function dataprovider_assignment_update() { /** * Test \local_o365\webservices\update_onenoteassignment::assignment_update(). + * + * @dataProvider dataprovider_assignment_update + * @covers \local_o365\webservices\update_onenoteassignment::assignment_update */ - public function test_assignment_update() { + public function test_assignment_update(): void { $dataarr = $this->dataprovider_assignment_update(); foreach ($dataarr as $data) { if (!empty($data[self::DBSTATE])) { @@ -485,7 +508,7 @@ public function test_assignment_update() { $this->setAdminUser(); - $actualreturn = \local_o365\webservices\update_onenoteassignment::assignment_update($data[self::PARAMS]); + $actualreturn = update_onenoteassignment::assignment_update($data[self::PARAMS]); $this->assertEquals($data[self::EXPECTEDRETURN]['data'][0]['name'], $actualreturn['data'][0]['name']); $this->assertEquals($data[self::EXPECTEDRETURN]['data'][0]['intro'], $actualreturn['data'][0]['intro']); @@ -496,18 +519,22 @@ public function test_assignment_update() { /** * Test assignment_update_returns method. + * + * @covers \local_o365\webservices\update_onenoteassignment::assignment_update_returns */ - public function test_assignment_update_returns() { - $schema = \local_o365\webservices\update_onenoteassignment::assignment_update_returns(); + public function test_assignment_update_returns(): void { + $schema = update_onenoteassignment::assignment_update_returns(); $this->assertTrue($schema instanceof external_single_structure); $this->assertArrayHasKey('data', $schema->keys); } /** * Test assignment_delete_parameters method. + * + * @covers \local_o365\webservices\delete_onenoteassignment::assignment_delete_parameters */ - public function test_assignment_delete_parameters() { - $schema = \local_o365\webservices\delete_onenoteassignment::assignment_delete_parameters(); + public function test_assignment_delete_parameters(): void { + $schema = delete_onenoteassignment::assignment_delete_parameters(); $this->assertTrue($schema instanceof external_function_parameters); $this->assertArrayHasKey('data', $schema->keys); } @@ -517,8 +544,8 @@ public function test_assignment_delete_parameters() { * * @return array Array of test parameters. */ - public function dataprovider_assignment_delete() { - $generaltests = $this->get_general_assignment_data_tests(); + public static function dataprovider_assignment_delete(): array { + $generaltests = static::get_general_assignment_data_tests(); $return = []; foreach ($generaltests as $testkey => $parameters) { @@ -538,8 +565,10 @@ public function dataprovider_assignment_delete() { /** * Test \local_o365\webservices\delete_onenoteassignment::assignment_delete(). + * + * @covers \local_o365\webservices\delete_onenoteassignment::assignment_delete */ - public function test_assignment_delete() { + public function test_assignment_delete(): void { $dataarr = $this->dataprovider_assignment_delete(); foreach ($dataarr as $data) { if (!empty($data[self::DBSTATE])) { @@ -558,7 +587,7 @@ public function test_assignment_delete() { $this->setAdminUser(); - $actualreturn = \local_o365\webservices\delete_onenoteassignment::assignment_delete($data[self::PARAMS]); + $actualreturn = delete_onenoteassignment::assignment_delete($data[self::PARAMS]); $this->assertEquals($data[self::EXPECTEDRETURN], $actualreturn); } @@ -566,9 +595,11 @@ public function test_assignment_delete() { /** * Test assignment_delete_returns method. + * + * @covers \local_o365\webservices\delete_onenoteassignment::assignment_delete_returns */ - public function test_assignment_delete_returns() { - $schema = \local_o365\webservices\delete_onenoteassignment::assignment_delete_returns(); + public function test_assignment_delete_returns(): void { + $schema = delete_onenoteassignment::assignment_delete_returns(); $this->assertTrue($schema instanceof external_single_structure); $this->assertArrayHasKey('result', $schema->keys); } diff --git a/tests/webservices_utils_test.php b/tests/webservices_utils_test.php index d2169a3a7..cd7dc6e96 100644 --- a/tests/webservices_utils_test.php +++ b/tests/webservices_utils_test.php @@ -23,9 +23,12 @@ * @copyright (C) 2014 onwards Microsoft Open Technologies, Inc. (http://msopentech.com/) */ -use core_external\external_single_structure; +namespace local_o365; -defined('MOODLE_INTERNAL') || die(); +use advanced_testcase; +use core_external\external_single_structure; +use lang_string; +use local_o365\webservices\utils; /** * Tests \local_o365\webservices\utils @@ -33,12 +36,12 @@ * @group local_o365 * @group office365 */ -class local_o365_webservices_utils_testcase extends \advanced_testcase { +final class webservices_utils_test extends advanced_testcase { /** * Perform setup before every test. This tells Moodle's phpunit to reset the database after every test. */ - protected function setUp() : void { + protected function setUp(): void { parent::setUp(); $this->resetAfterTest(true); } @@ -85,7 +88,7 @@ public function create_assignment_info_testdata($createcourse, $modulerecords) { * * @return array Array of test parameters. */ - public function dataprovider_assignment_info() { + public static function dataprovider_assignment_info(): array { // Notes: // [[coursemoduleid]] is replaced with the id of the *last* course_module record inserted. // [[courseid]] is replaced with the generated course ID. @@ -269,12 +272,14 @@ public function dataprovider_assignment_info() { * @param int $coursemoduleid The course module id to pass to the test method. * @param int $courseid The course id to pass to the test method. * @param array $expectedreturn The expected return of the test method. + * + * @covers \local_o365\webservices\utils::get_assignment_info */ public function test_get_assignment_info($createcourse, $modulerecords, $expectedexception, $coursemoduleid, $courseid, - $expectedreturn) { + $expectedreturn): void { global $DB; - list($course, $modulerecord) = $this->create_assignment_info_testdata($createcourse, $modulerecords); + [$course, $modulerecord] = $this->create_assignment_info_testdata($createcourse, $modulerecords); if (!empty($expectedexception)) { if (isset($expectedexception[1])) { @@ -288,7 +293,7 @@ public function test_get_assignment_info($createcourse, $modulerecords, $expecte $courseid = ($courseid === '[[courseid]]') ? $course->id : $courseid; $coursemoduleid = ($coursemoduleid === '[[coursemoduleid]]') ? $modulerecord['id'] : $coursemoduleid; - $actualreturn = \local_o365\webservices\utils::get_assignment_info($coursemoduleid, $courseid); + $actualreturn = utils::get_assignment_info($coursemoduleid, $courseid); if ($expectedreturn[0] === '[[course]]') { $expectedreturn[0] = $DB->get_record('course', ['id' => $course->id]); @@ -311,8 +316,8 @@ public function test_get_assignment_info($createcourse, $modulerecords, $expecte * * @return array Array of test parameters. */ - public function dataprovider_verify_assignment() { - $assignmentinfotests = $this->dataprovider_assignment_info(); + public static function dataprovider_verify_assignment(): array { + $assignmentinfotests = static::dataprovider_assignment_info(); $testcases = []; foreach ($assignmentinfotests as $testkey => $testparams) { @@ -364,12 +369,14 @@ public function dataprovider_verify_assignment() { * @param array $expectedreturn The expected return of the test method. * @param bool $grantcapability Whether to grant the test user the capability to work with the assignment. * @param bool $addonenotesubmission Whether to add the OneNote submission record to this assignment. + * + * @covers \local_o365\webservices\utils::verify_assignment */ public function test_verify_assignment($createcourse, $modulerecords, $expectedexception, $coursemoduleid, $courseid, - $expectedreturn, $grantcapability, $addonenotesubmission) { + $expectedreturn, $grantcapability, $addonenotesubmission): void { global $DB; - list($course, $modulerecord) = $this->create_assignment_info_testdata($createcourse, $modulerecords); + [$course, $modulerecord] = $this->create_assignment_info_testdata($createcourse, $modulerecords); if (!empty($expectedexception)) { if (isset($expectedexception[1])) { @@ -400,7 +407,7 @@ public function test_verify_assignment($createcourse, $modulerecords, $expectede $DB->insert_record('assign_plugin_config', $pluginconfigparams); } - $actualreturn = \local_o365\webservices\utils::verify_assignment($coursemoduleid, $courseid); + $actualreturn = utils::verify_assignment($coursemoduleid, $courseid); if ($expectedreturn[0] === '[[course]]') { $expectedreturn[0] = $DB->get_record('course', ['id' => $course->id]); @@ -417,9 +424,11 @@ public function test_verify_assignment($createcourse, $modulerecords, $expectede /** * Test get_assignment_return_info_schema method. + * + * @covers \local_o365\webservices\utils::get_assignment_return_info_schema */ - public function test_get_assignment_return_info_schema() { - $schema = \local_o365\webservices\utils::get_assignment_return_info_schema(); + public function test_get_assignment_return_info_schema(): void { + $schema = utils::get_assignment_return_info_schema(); $this->assertTrue($schema instanceof external_single_structure); $this->assertArrayHasKey('data', $schema->keys); } @@ -429,8 +438,8 @@ public function test_get_assignment_return_info_schema() { * * @return array Array of test parameters. */ - public function dataprovider_get_assignment_return_info() { - $assignmentinfotests = $this->dataprovider_assignment_info(); + public static function dataprovider_get_assignment_return_info(): array { + $assignmentinfotests = static::dataprovider_assignment_info(); $testcases = []; foreach ($assignmentinfotests as $testkey => $testparams) { @@ -449,6 +458,7 @@ public function dataprovider_get_assignment_return_info() { ]; } } + return $testcases; } @@ -464,10 +474,12 @@ public function dataprovider_get_assignment_return_info() { * @param int $coursemoduleid The course module id to pass to the test method. * @param int $courseid The course id to pass to the test method. * @param array $expectedreturn The expected return of the test method. + * + * @covers \local_o365\webservices\utils::get_assignment_return_info */ public function test_get_assignment_return_info($createcourse, $modulerecords, $expectedexception, $coursemoduleid, $courseid, - $expectedreturn) { - list($course, $modulerecord) = $this->create_assignment_info_testdata($createcourse, $modulerecords); + $expectedreturn): void { + [$course, $modulerecord] = $this->create_assignment_info_testdata($createcourse, $modulerecords); if (!empty($expectedexception)) { if (isset($expectedexception[1])) { @@ -481,16 +493,16 @@ public function test_get_assignment_return_info($createcourse, $modulerecords, $ $courseid = ($courseid === '[[courseid]]') ? $course->id : $courseid; $coursemoduleid = ($coursemoduleid === '[[coursemoduleid]]') ? $modulerecord['id'] : $coursemoduleid; - $actualreturn = \local_o365\webservices\utils::get_assignment_return_info($coursemoduleid, $courseid); + $actualreturn = utils::get_assignment_return_info($coursemoduleid, $courseid); if ($expectedreturn['course'] === '[[courseid]]') { $expectedreturn['course'] = $course->id; } if ($expectedreturn['coursemodule'] === '[[coursemoduleid]]') { - $expectedreturn['coursemodule'] = (string)$modulerecord['id']; + $expectedreturn['coursemodule'] = (string) $modulerecord['id']; } if ($expectedreturn['instance'] === '[[assignid]]') { - $expectedreturn['instance'] = (string)$modulerecord['instance']; + $expectedreturn['instance'] = (string) $modulerecord['instance']; } $this->assertEquals($expectedreturn, $actualreturn);