Skip to content

Commit

Permalink
feat: Adds moodle_curl_lrs loader to close #238 (#242)
Browse files Browse the repository at this point in the history
  • Loading branch information
ryasmi authored Sep 3, 2018
1 parent 02bc2f0 commit 3da6e75
Show file tree
Hide file tree
Showing 9 changed files with 236 additions and 78 deletions.
1 change: 1 addition & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ charset = utf-8

[*.{php,json}]
indent_size = 4
trim_trailing_whitespace=true
2 changes: 1 addition & 1 deletion classes/log/store.php
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ public function process_events(array $events) {
'app_url' => $CFG->wwwroot,
],
'loader' => [
'loader' => 'lrs',
'loader' => 'moodle_curl_lrs',
'lrs_endpoint' => $this->get_config('endpoint', ''),
'lrs_username' => $this->get_config('username', ''),
'lrs_password' => $this->get_config('password', ''),
Expand Down
107 changes: 30 additions & 77 deletions src/loader/lrs.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,82 +19,35 @@

use src\loader\utils as utils;

function correct_endpoint($endpoint) {
$endswithstatements = substr($endpoint, -11) === "/statements";
if ($endswithstatements) {
return substr($endpoint, 0, -11);
}
return rtrim($endpoint, '/');
}

function send_http_statements(array $config, array $statements) {
$endpoint = $config['lrs_endpoint'];
$username = $config['lrs_username'];
$password = $config['lrs_password'];

$url = correct_endpoint($endpoint).'/statements';
$auth = base64_encode($username.':'.$password);
$postdata = json_encode($statements);

$request = curl_init();
curl_setopt($request, CURLOPT_URL, $url);
curl_setopt($request, CURLOPT_POSTFIELDS, $postdata);
curl_setopt($request, CURLOPT_RETURNTRANSFER, true);
curl_setopt($request, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($request, CURLOPT_HTTPHEADER, [
'Authorization: Basic '.$auth,
'X-Experience-API-Version: 1.0.0',
'Content-Type: application/json',
]);

$responsetext = curl_exec($request);
$responsecode = curl_getinfo($request, CURLINFO_RESPONSE_CODE);
curl_close($request);

if ($responsecode !== 200) {
throw new \Exception($responsetext);
}
}

function load_transormed_events_to_lrs(array $config, array $transformedevents) {
try {
$statements = array_reduce($transformedevents, function ($result, $transformedevent) {
$eventstatements = $transformedevent['statements'];
return array_merge($result, $eventstatements);
}, []);
send_http_statements($config, $statements);
$loadedevents = utils\construct_loaded_events($transformedevents, true);
return $loadedevents;
} catch (\Exception $e) {
$logerror = $config['log_error'];
$logerror("Failed load for event id #" . $eventobj->id . ": " . $e->getMessage());
$logerror($e->getTraceAsString());
$loadedevents = utils\construct_loaded_events($transformedevents, false);
return $loadedevents;
}
}

function get_event_batches(array $config, array $transformedevents) {
$maxbatchsize = $config['lrs_max_batch_size'];
if (!empty($maxbatchsize) && $maxbatchsize < count($transformedevents)) {
return array_chunk($transformedevents, $maxbatchsize);
}
return [$transformedevents];
}

function load(array $config, array $events) {
// Attempts to load events that were transformed successfully in batches.
$successfultransformevents = utils\filter_transformed_events($events, true);
$batches = get_event_batches($config, $successfultransformevents);
$loadedevents = array_reduce($batches, function ($result, $batch) use ($config) {
$loadedbatchevents = load_transormed_events_to_lrs($config, $batch);
return array_merge($result, $loadedbatchevents);
}, []);

// Flags events that weren't transformed successfully as events that didn't load.
$failedtransformevents = utils\filter_transformed_events($events, false);
$nonloadedevents = utils\construct_loaded_events($failedtransformevents, false);

// Returns loaded and non-loaded events to avoid re-processing.
return array_merge($loadedevents, $nonloadedevents);
$sendhttpstatements = function (array $config, array $statements) {
$endpoint = $config['lrs_endpoint'];
$username = $config['lrs_username'];
$password = $config['lrs_password'];
$proxyendpoint = $config['lrs_proxy_endpoint'];

$url = utils\correct_endpoint($endpoint).'/statements';
$auth = base64_encode($username.':'.$password);
$postdata = json_encode($statements);

$request = curl_init();
curl_setopt($request, CURLOPT_URL, $url);
curl_setopt($request, CURLOPT_POSTFIELDS, $postdata);
curl_setopt($request, CURLOPT_RETURNTRANSFER, true);
curl_setopt($request, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($request, CURLOPT_HTTPHEADER, [
'Authorization: Basic '.$auth,
'X-Experience-API-Version: 1.0.0',
'Content-Type: application/json',
]);

$responsetext = curl_exec($request);
$responsecode = curl_getinfo($request, CURLINFO_RESPONSE_CODE);
curl_close($request);

if ($responsecode !== 200) {
throw new \Exception($responsetext);
}
};
return utils\load_in_batches($config, $events, $sendhttpstatements);
}
54 changes: 54 additions & 0 deletions src/loader/moodle_curl_lrs.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?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 src\loader\moodle_curl_lrs;
defined('MOODLE_INTERNAL') || die();

global $CFG;
if (!isset($CFG)) {
$CFG = (object) [ 'libdir' => 'utils' ];
}
require_once($CFG->libdir . '/filelib.php');

use src\loader\utils as utils;

function load(array $config, array $events) {
$sendhttpstatements = function (array $config, array $statements) {
$endpoint = $config['lrs_endpoint'];
$username = $config['lrs_username'];
$password = $config['lrs_password'];
$proxyendpoint = $config['lrs_proxy_endpoint'];

$url = utils\correct_endpoint($endpoint).'/statements';
$auth = base64_encode($username.':'.$password);
$postdata = json_encode($statements);

$request = new \curl();
$responsetext = $request->post($url, $postdata, [
'CURLOPT_HTTPHEADER' => [
'Authorization: Basic '.$auth,
'X-Experience-API-Version: 1.0.0',
'Content-Type: application/json',
],
]);
$responsecode = $request->info['http_code'];

if ($responsecode !== 200) {
throw new \Exception($responsetext);
}
};
return utils\load_in_batches($config, $events, $sendhttpstatements);
}
27 changes: 27 additions & 0 deletions src/loader/utils/correct_endpoint.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?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 src\loader\utils;

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

function correct_endpoint($endpoint) {
$endswithstatements = substr($endpoint, -11) === "/statements";
if ($endswithstatements) {
return substr($endpoint, 0, -11);
}
return rtrim($endpoint, '/');
}
23 changes: 23 additions & 0 deletions src/loader/utils/filelib.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?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 src\loader\utils;

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

class curl {
// This is just a dummy file to avoid failures in CI.
}
27 changes: 27 additions & 0 deletions src/loader/utils/get_event_batches.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?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 src\loader\utils;

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

function get_event_batches(array $config, array $transformedevents) {
$maxbatchsize = $config['lrs_max_batch_size'];
if (!empty($maxbatchsize) && $maxbatchsize < count($transformedevents)) {
return array_chunk($transformedevents, $maxbatchsize);
}
return [$transformedevents];
}
37 changes: 37 additions & 0 deletions src/loader/utils/load_batch.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?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 src\loader\utils;

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

function load_batch(array $config, array $transformedevents, callable $loader) {
try {
$statements = array_reduce($transformedevents, function ($result, $transformedevent) {
$eventstatements = $transformedevent['statements'];
return array_merge($result, $eventstatements);
}, []);
$loader($config, $statements);
$loadedevents = construct_loaded_events($transformedevents, true);
return $loadedevents;
} catch (\Exception $e) {
$logerror = $config['log_error'];
$logerror("Failed load for event id #" . $eventobj->id . ": " . $e->getMessage());
$logerror($e->getTraceAsString());
$loadedevents = construct_loaded_events($transformedevents, false);
return $loadedevents;
}
}
36 changes: 36 additions & 0 deletions src/loader/utils/load_in_batches.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?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 src\loader\utils;

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

function load_in_batches(array $config, array $events, callable $loader) {
// Attempts to load events that were transformed successfully in batches.
$successfultransformevents = filter_transformed_events($events, true);
$batches = get_event_batches($config, $successfultransformevents);
$loadedevents = array_reduce($batches, function ($result, $batch) use ($config, $loader) {
$loadedbatchevents = load_batch($config, $batch, $loader);
return array_merge($result, $loadedbatchevents);
}, []);

// Flags events that weren't transformed successfully as events that didn't load.
$failedtransformevents = filter_transformed_events($events, false);
$nonloadedevents = construct_loaded_events($failedtransformevents, false);

// Returns loaded and non-loaded events to avoid re-processing.
return array_merge($loadedevents, $nonloadedevents);
}

0 comments on commit 3da6e75

Please sign in to comment.