MDL-68379 core_xapi: adding result, attachments and context to statement

This commit is contained in:
Ferran Recio 2020-04-08 07:06:01 +02:00
parent 75ba339cdb
commit 72a2335151
10 changed files with 917 additions and 85 deletions

View file

@ -28,6 +28,9 @@ use core_xapi\local\statement\item;
use core_xapi\local\statement\item_actor;
use core_xapi\local\statement\item_object;
use core_xapi\local\statement\item_verb;
use core_xapi\local\statement\item_result;
use core_xapi\local\statement\item_attachment;
use core_xapi\local\statement\item_context;
use core_xapi\xapi_exception;
use JsonSerializable;
use stdClass;
@ -42,39 +45,39 @@ defined('MOODLE_INTERNAL') || die();
*/
class statement implements JsonSerializable {
/** @var actor The statement actor. */
/** @var item_actor The statement actor. */
protected $actor = null;
/** @var verb The statement verb. */
/** @var item_verb The statement verb. */
protected $verb = null;
/** @var object The statement object. */
/** @var item_object The statement object. */
protected $object = null;
/** @var result The statement result. */
/** @var item_result The statement result. */
protected $result = null;
/** @var context The statement context. */
/** @var item_context The statement context. */
protected $context = null;
/** @var timestamp The statement timestamp. */
/** @var string The statement timestamp. */
protected $timestamp = null;
/** @var stored The statement stored. */
/** @var string The statement stored. */
protected $stored = null;
/** @var authority The statement authority. */
protected $authority = null;
/** @var version The statement version. */
/** @var string The statement version. */
protected $version = null;
/** @var attachments The statement attachments. */
/** @var item_attachment[] The statement attachments. */
protected $attachments = null;
/** @var additionalfields list of additional fields. */
private static $additionalsfields = [
'context', 'result', 'timestamp', 'stored', 'authority', 'version', 'attachments'
'timestamp', 'stored', 'version'
];
/**
@ -97,11 +100,32 @@ class statement implements JsonSerializable {
$result->set_verb(item_verb::create_from_data($data->verb));
$result->set_object(item_object::create_from_data($data->object));
if (isset($data->result)) {
$result->set_result(item_result::create_from_data($data->result));
}
if (!empty($data->attachments)) {
if (!is_array($data->attachments)) {
throw new xapi_exception("Attachments must be an array");
}
foreach ($data->attachments as $attachment) {
$result->add_attachment(item_attachment::create_from_data($attachment));
}
}
if (isset($data->context)) {
$result->set_context(item_context::create_from_data($data->context));
}
if (isset($data->authority)) {
$result->set_authority(item_actor::create_from_data($data->authority));
}
// Store other generic xAPI statement fields.
foreach (self::$additionalsfields as $additional) {
if (isset($data->$additional)) {
$method = 'set_'.$additional;
$result->$method(item::create_from_data($data->$additional));
$result->$method($data->$additional);
}
}
return $result;
@ -118,6 +142,18 @@ class statement implements JsonSerializable {
'verb' => $this->verb,
'object' => $this->object,
];
if (!empty($this->result)) {
$result->result = $this->result;
}
if (!empty($this->context)) {
$result->context = $this->context;
}
if (!empty($this->authority)) {
$result->authority = $this->authority;
}
if (!empty($this->attachments)) {
$result->attachments = $this->attachments;
}
foreach (self::$additionalsfields as $additional) {
if (!empty($this->$additional)) {
$result->$additional = $this->$additional;
@ -179,36 +215,36 @@ class statement implements JsonSerializable {
/**
* Set the statement context.
*
* @param item $context context item element
* @param item_context $context context item element
*/
public function set_context(item $context): void {
public function set_context(item_context $context): void {
$this->context = $context;
}
/**
* Set the statement result.
*
* @param item $result result item element
* @param item_result $result result item element
*/
public function set_result(item $result): void {
public function set_result(item_result $result): void {
$this->result = $result;
}
/**
* Set the statement timestamp.
*
* @param item $timestamp timestamp item element
* @param string $timestamp timestamp element
*/
public function set_timestamp(item $timestamp): void {
public function set_timestamp(string $timestamp): void {
$this->timestamp = $timestamp;
}
/**
* Set the statement stored.
*
* @param item $stored stored item element
* @param string $stored stored element
*/
public function set_stored(item $stored): void {
public function set_stored(string $stored): void {
$this->stored = $stored;
}
@ -217,26 +253,29 @@ class statement implements JsonSerializable {
*
* @param item $authority authority item element
*/
public function set_authority(item $authority): void {
public function set_authority(item_actor $authority): void {
$this->authority = $authority;
}
/**
* Set the statement version.
*
* @param item $version version item element
* @param string $version version element
*/
public function set_version(item $version): void {
public function set_version(string $version): void {
$this->version = $version;
}
/**
* Set the statement attachments.
* Adds and attachment to the statement.
*
* @param item $attachments attachments item element
*/
public function set_attachments(item $attachments): void {
$this->attachments = $attachments;
public function add_attachment(item_attachment $attachment): void {
if ($this->attachments === null) {
$this->attachments = [];
}
$this->attachments[] = $attachment;
}
/**
@ -341,7 +380,7 @@ class statement implements JsonSerializable {
*
* @return item|null
*/
public function get_context(): ?item {
public function get_context(): ?item_context {
return $this->context;
}
@ -350,25 +389,25 @@ class statement implements JsonSerializable {
*
* @return item|null
*/
public function get_result(): ?item {
public function get_result(): ?item_result {
return $this->result;
}
/**
* Return the statement timestamp if it is defined.
*
* @return item|null
* @return string|null
*/
public function get_timestamp(): ?item {
public function get_timestamp(): ?string {
return $this->timestamp;
}
/**
* Return the statement stored if it is defined.
*
* @return item|null
* @return string|null
*/
public function get_stored(): ?item {
public function get_stored(): ?string {
return $this->stored;
}
@ -377,25 +416,25 @@ class statement implements JsonSerializable {
*
* @return item|null
*/
public function get_authority(): ?item {
public function get_authority(): ?item_actor {
return $this->authority;
}
/**
* Return the statement version if it is defined.
*
* @return item|null
* @return string|null
*/
public function get_version(): ?item {
public function get_version(): ?string {
return $this->version;
}
/**
* Return the statement attachments if it is defined.
*
* @return item|null
* @return item_attachment[]|null
*/
public function get_attachments(): ?item {
public function get_attachments(): ?array {
return $this->attachments;
}
}

View file

@ -0,0 +1,73 @@
<?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/>.
/**
* Statement attachment for xAPI structure checking and usage.
*
* @package core_xapi
* @copyright 2020 Ferran Recio
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_xapi\local\statement;
use core_xapi\xapi_exception;
use core_xapi\iri;
use stdClass;
/**
* Abstract xAPI attachment class.
*
* @copyright 2020 Ferran Recio
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class item_attachment extends item {
/**
* Function to create an item from part of the xAPI statement.
*
* @param stdClass $data the original xAPI element
* @return item item_attachment xAPI generated
*/
public static function create_from_data(stdClass $data): item {
if (empty($data->usageType)) {
throw new xapi_exception("missing attachment usageType");
}
if (!iri::check($data->usageType)) {
throw new xapi_exception("attachment usageType $data->usageType is not a valid IRI");
}
if (empty($data->display)) {
throw new xapi_exception("missing attachment display");
}
if (empty($data->contentType)) {
throw new xapi_exception("missing attachment contentType");
}
if (empty($data->length)) {
throw new xapi_exception("missing attachment length");
}
if (!is_numeric($data->length)) {
throw new xapi_exception("invalid attachment length format");
}
if (empty($data->sha2)) {
throw new xapi_exception("missing attachment sha2");
}
// More required property checks will appear here in the future.
return new self($data);
}
}

View file

@ -0,0 +1,49 @@
<?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/>.
/**
* Statement context for xAPI structure checking and usage.
*
* @package core_xapi
* @copyright 2020 Ferran Recio
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_xapi\local\statement;
use stdClass;
/**
* Abstract xAPI context class.
*
* @copyright 2020 Ferran Recio
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class item_context extends item {
/**
* Function to create an item from part of the xAPI statement.
*
* @param stdClass $data the original xAPI element
* @return item item_context xAPI generated
*/
public static function create_from_data(stdClass $data): item {
// Required property checks will appear here in the future.
return new self($data);
}
}

View file

@ -0,0 +1,107 @@
<?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/>.
/**
* Statement result for xAPI structure checking and usage.
*
* @package core_xapi
* @copyright 2020 Ferran Recio
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_xapi\local\statement;
use core_xapi\xapi_exception;
use DateInterval;
use Exception;
use stdClass;
/**
* Abstract xAPI result class.
*
* @copyright 2020 Ferran Recio
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class item_result extends item {
/** @var int The second of duration if present. */
protected $duration;
/** @var item_score the result score if present. */
protected $score;
/**
* Function to create a result from part of the xAPI statement.
*
* @param stdClass $data the original xAPI element
* @param int $duration duration in seconds
* @param item_score $score the provided score
*/
protected function __construct(stdClass $data, int $duration = null, item_score $score = null) {
parent::__construct($data);
$this->duration = $duration;
$this->score = $score;
}
/**
* Function to create an item from part of the xAPI statement.
*
* @param stdClass $data the original xAPI element
* @return item item_result xAPI generated
*/
public static function create_from_data(stdClass $data): item {
$duration = null;
if (!empty($data->duration)) {
try {
// Duration uses ISO 8601 format which is ALMOST compatible with PHP DateInterval.
// Because we are mesuring human time we get rid of milliseconds, which are not
// compatible with DateInterval (More info: https://bugs.php.net/bug.php?id=53831),
// all other fractions like "P1.5Y" will throw an exception.
$value = preg_replace('/[.,][0-9]*S/', 'S', $data->duration);
$interval = new DateInterval($value);
$duration = date_create('@0')->add($interval)->getTimestamp();
} catch (Exception $e) {
throw new xapi_exception('Invalid duration format.');
}
}
$score = null;
if (!empty($data->score)) {
$score = item_score::create_from_data($data->score);
}
return new self($data, $duration, $score);
}
/**
* Returns the duration in seconds (if present).
*
* @return int|null duration in seconds
*/
public function get_duration(): ?int {
return $this->duration;
}
/**
* Returns the score.
*
* @return item_score|null the score item
*/
public function get_score(): ?item_score {
return $this->score;
}
}

View file

@ -0,0 +1,49 @@
<?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/>.
/**
* Statement score for xAPI structure checking and usage.
*
* @package core_xapi
* @copyright 2020 Ferran Recio
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_xapi\local\statement;
use stdClass;
/**
* Abstract xAPI score class.
*
* @copyright 2020 Ferran Recio
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class item_score extends item {
/**
* Function to create an item from part of the xAPI statement.
*
* @param stdClass $data the original xAPI element
* @return item item_score xAPI generated
*/
public static function create_from_data(stdClass $data): item {
// Required property checks will appear here in the future.
return new self($data);
}
}