Skip to content

Commit

Permalink
Merge pull request #239 from ArloSoftware/ARLO-52
Browse files Browse the repository at this point in the history
Arlo 52
  • Loading branch information
ojnadjarm authored Jan 2, 2025
2 parents a3173d8 + ac6c9df commit 6b2bebb
Show file tree
Hide file tree
Showing 5 changed files with 201 additions and 82 deletions.
189 changes: 112 additions & 77 deletions classes/local/job/outcomes_job.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,24 +25,21 @@

namespace enrol_arlo\local\job;

use enrol_arlo\local\persistent\job_persistent;
use stdClass;

defined('MOODLE_INTERNAL') || die();

use core_user;
use enrol_arlo\api;
use enrol_arlo\local\external;
use enrol_arlo\local\learner_progress;
use enrol_arlo\manager;
use enrol_arlo\persistent;
use enrol_arlo\Arlo\AuthAPI\RequestUri;
use enrol_arlo\local\client;
use enrol_arlo\local\enum\arlo_type;
use enrol_arlo\local\administrator_notification;
use enrol_arlo\local\persistent\retry_log_persistent;
use enrol_arlo\local\persistent\registration_persistent;
use enrol_arlo\result;
use enrol_arlo\task\outcome_adhoc;
use Exception;
use GuzzleHttp\Exception\ClientException;
use GuzzleHttp\Psr7\Request;
use coding_exception;
use moodle_exception;

Expand Down Expand Up @@ -155,7 +152,6 @@ public function run() {
['enrolid' => $enrolmentinstance->id, 'updatesource' => 1],
'timelastrequest', 'ASC', 0, $limit
);
$course = get_course($enrolmentinstance->courseid);
} catch (Exception $exception) {
// Update scheduling information on persistent after successfull save.
$jobpersistent->set('timelastrequest', time());
Expand All @@ -171,80 +167,119 @@ public function run() {
$jobpersistent->save();
} else {
foreach ($registrations as $registrationpersistent) {
$user = core_user::get_user($registrationpersistent->get('userid'));
$apiretryerrorpt1 = get_string('apiretryerrorpt1', 'enrol_arlo');
$apiretryerrorpt2 = get_string('apiretryerrorpt2', 'enrol_arlo');
$recordcounter = $registrationpersistent->get('redirectcounter');
$maxrecordretries = $pluginconfig->get('retriesperrecord');
if ($recordcounter >= $maxrecordretries) {
// Display retry error to admin on job page
$this->trace->output("$apiretryerrorpt1 $user->id $apiretryerrorpt2");
} else {
try {
if (!$user) {
throw new moodle_exception('moodleaccountdoesnotexist');
}
$registrationid = $registrationpersistent->get('sourceid');
$sourceregistration = external::get_registration_resource($registrationid);
$learnerprogress = new learner_progress($course, $user);
$data = $learnerprogress->get_keyed_data_for_arlo();
if (!empty($data)) {
$this->trace->output(implode(',', $data));
external::patch_registration_resource($sourceregistration, $data);
// Check API status code. If it's a 3xx, increment the registration and global retry counter.
// Now we count the errors 4xx and 5xx globally, but we don't increase the registration retry counter.
$apistatus = $pluginconfig->get('apistatus');
if ($apistatus >= 300 && $apistatus <= 599) {
$pluginredirectcount = $pluginconfig->get('redirectcount') + 1;
$pluginconfig->set('redirectcount', $pluginredirectcount);
$pluginmaxredirects = $pluginconfig->get('maxretries');
if ($apistatus <= 399) {
$recordcounter++;
$registrationpersistent->set('redirectcounter', $recordcounter);
if (!empty($maxrecordretries) && $recordcounter >= $maxrecordretries) {
// Display retry error to admin on job page
$this->trace->output("$apiretryerrorpt1 $user->id $apiretryerrorpt2");
// Create and save a log of the failure
$retrylog = new retry_log_persistent();
$retrylog->set('timelogged', time());
$retrylog->set('userid', $user->id);
$retrylog->set('participantname', "$user->lastname, $user->firstname");
$retrylog->set('courseid', $course->id);
$retrylog->set('coursename', $course->fullname);
$retrylog->save();
}
}
// We have reached the maximum number of errors allowed. Disable communication.
if (!empty($pluginmaxredirects) && $pluginredirectcount >= $pluginmaxredirects) {
$pluginconfig->set('enablecommunication', 0);
}
} else {
if ($recordcounter > 0) {
$registrationpersistent->set('redirectcounter', 0);
}
$pluginconfig->set('redirectcount', 0);
}
$apistatus == 200 ? $registrationpersistent->set('updatesource', 0) : null;
$registrationpersistent->set('timelastrequest', time());
$registrationpersistent->save();
}
} catch (Exception $exception) {
debugging($exception->getMessage(), DEBUG_DEVELOPER);
$this->add_error($exception->getMessage());
$registrationpersistent->set('errormessage', $exception->getMessage());
} finally {
// Update scheduling information on persistent after successfull save.
$jobpersistent->set('timelastrequest', time());
$jobpersistent->save();
// DO NOT release lock here. This is a foreach loop!
}
}
$registrationinfo = new stdClass();
$registrationinfo->id = $registrationpersistent->get('id');
$registrationinfo->courseid = $enrolmentinstance->courseid;
$outcomeadhoctask = new outcome_adhoc();
$outcomeadhoctask->set_custom_data($registrationinfo);
\core\task\manager::queue_adhoc_task($outcomeadhoctask);
}
}
$lock->release();
return true;
} else {
throw new moodle_exception('locktimeout');
// Job may not have completed in time. Just return false.
$this->add_error('locktimeout');
return false;
}
}

/**
* Process a single outcome.
*
* @param stdClass $registrationinfo
* @param progress_trace $trace
* @throws \dml_exception
* @throws \moodle_exception
*/
public static function process_single_outcome($registrationinfo, $trace) {
global $DB;

$course = get_course($registrationinfo->courseid);
$registrationid = $registrationinfo->id;
$plugin = api::get_enrolment_plugin();
$pluginconfig = $plugin->get_plugin_config();
$registrationpersistent = new registration_persistent($registrationid);
$user = core_user::get_user($registrationpersistent->get('userid'));
$apiretryerrorpt1 = get_string('apiretryerrorpt1', 'enrol_arlo');
$apiretryerrorpt2 = get_string('apiretryerrorpt2', 'enrol_arlo');
$recordcounter = $registrationpersistent->get('redirectcounter');
$maxrecordretries = $pluginconfig->get('retriesperrecord');

if ($recordcounter >= $maxrecordretries) {
// Display retry error to admin on job page
$trace->output("$apiretryerrorpt1 $user->id $apiretryerrorpt2");
} else {
try {
if (!$user) {
throw new moodle_exception('moodleaccountdoesnotexist');
}
$registrationid = $registrationpersistent->get('sourceid');
$sourceregistration = external::get_registration_resource($registrationid);

$learnerprogress = new learner_progress($course, $user);
$data = $learnerprogress->get_keyed_data_for_arlo();

if (!empty($data)) {
$trace->output(implode(',', $data));
external::patch_registration_resource($sourceregistration, $data);
// Check API status code. If it's a 3xx, increment the registration and global retry counter.
// Now we count the errors 4xx and 5xx globally, but we don't increase the registration retry counter.
$apistatus = $pluginconfig->get('apistatus');
if ($apistatus >= 300 && $apistatus <= 599) {
$pluginredirectcount = $pluginconfig->get('redirectcount') + 1;
$pluginconfig->set('redirectcount', $pluginredirectcount);
$pluginmaxredirects = $pluginconfig->get('maxretries');
if ($apistatus <= 399) {
$recordcounter++;
$registrationpersistent->set('redirectcounter', $recordcounter);
if (!empty($maxrecordretries) && $recordcounter >= $maxrecordretries) {
// Display retry error to admin on job page
$trace->output("$apiretryerrorpt1 $user->id $apiretryerrorpt2");
// Create and save a log of the failure
$retrylog = new retry_log_persistent();
$retrylog->set('timelogged', time());
$retrylog->set('userid', $user->id);
$retrylog->set('participantname', "$user->lastname, $user->firstname");
$retrylog->set('courseid', $course->id);
$retrylog->set('coursename', $course->fullname);
$retrylog->save();
}
}
// We have reached the maximum number of errors allowed. Disable communication.
if (!empty($pluginmaxredirects) && $pluginredirectcount >= $pluginmaxredirects) {
$pluginconfig->set('enablecommunication', 0);
}
} else {
if ($recordcounter > 0) {
$registrationpersistent->set('redirectcounter', 0);
}
$pluginconfig->set('redirectcount', 0);
}
$apistatus == 200 ? $registrationpersistent->set('updatesource', 0) : null;
$registrationpersistent->set('timelastrequest', time());
$registrationpersistent->save();
}
} catch (Exception $exception) {
debugging($exception->getMessage(), DEBUG_DEVELOPER);
$registrationpersistent->set('errormessage', $exception->getMessage());
} finally {
$sql = "SELECT *
FROM {enrol_arlo_scheduledjob}
WHERE area = :area
AND type = :type
AND disabled <> :disabled";
$conditions = [
'area' => 'enrolment',
'type' => 'outcomes',
'disabled' => 1,
];
$job = $DB->get_record_sql($sql, $conditions);
// Update scheduling information on persistent after successfull save.
$jobpersistent = new job_persistent(0, $job);
$jobpersistent->set('timelastrequest', time());
$jobpersistent->save();
}
}
}
}
81 changes: 81 additions & 0 deletions classes/task/outcome_adhoc.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.

namespace enrol_arlo\task;

use core\task\adhoc_task;
use enrol_arlo\local\job\outcomes_job;
use null_progress_trace;
use text_progress_trace;

defined('MOODLE_INTERNAL') || die();

/**
* Processes Arlo Outcomes.
*
* @package enrol_arlo
* @author 2023 Oscar Nadjar <oscar.nadjar@moodle.com>
* @copyright Moodle US
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class outcome_adhoc extends adhoc_task {

/**
* Get schedule task human readable name.
*
* @return string
* @throws \coding_exception
*/
public function get_name() {
return get_string('outcomesadhoctask', 'enrol_arlo');
}

/**
* Execute the task.
*
* @throws \coding_exception
* @throws \dml_exception
* @throws \moodle_exception
*/
public function execute() {
global $CFG;

require_once($CFG->dirroot . '/enrol/arlo/lib.php');
if (!enrol_is_enabled('arlo')) {
return;
}
$trace = new null_progress_trace();
if ($CFG->debug == DEBUG_DEVELOPER) {
$trace = new text_progress_trace();
}
$registrationinfo = $this->get_custom_data();
outcomes_job::process_single_outcome($registrationinfo, $trace);

return true;
}

/**
* Queues this task to run ASAP.
*
* @param string $registrationid
*/
public static function queue_task(object $event) {
$task = new self();
$task->set_custom_data($event);
$task->set_next_run_time(time());
\core\task\manager::queue_adhoc_task($task);
}
}
2 changes: 1 addition & 1 deletion db/tasks.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
'classname' => 'enrol_arlo\task\outcomes',
'blocking' => 0,
'minute' => '*',
'hour' => '*',
'hour' => '*/1',
'day' => '*',
'dayofweek' => '*',
'month' => '*',
Expand Down
5 changes: 4 additions & 1 deletion lib.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@

defined('MOODLE_INTERNAL') || die();

require_once(__DIR__ . '/vendor/autoload.php');
if (!class_exists('GuzzleHttp\Client')) {
require_once(__DIR__ . '/vendor/autoload.php');
}

require_once($CFG->dirroot . '/group/lib.php');

use enrol_arlo\Arlo\AuthAPI\Enum\EventStatus;
Expand Down
6 changes: 3 additions & 3 deletions version.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@

$plugin = new stdClass();

$plugin->version = 2024081400;
$plugin->version = 2024090401;
$plugin->requires = 2022112800; // See http://docs.moodle.org/dev/Moodle_Version
$plugin->component = 'enrol_arlo'; // Full name of the plugin (used for diagnostics).
$plugin->release = '4.1.9'; // Human-friendly version name.
$plugin->release = '4.2.0'; // Human-friendly version name.
$plugin->maturity = MATURITY_STABLE; // This version's maturity level.
$plugin->dependencies = [];
$plugin->supported = [401, 404]; // Supported Moodle versions.

0 comments on commit 6b2bebb

Please sign in to comment.