first commit

This commit is contained in:
CHIEFSOFT\ameye
2024-09-30 18:11:26 -04:00
commit e592ca6823
27270 changed files with 5002257 additions and 0 deletions
@@ -0,0 +1,56 @@
<?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/>.
/**
* Activity base class.
*
* @package mod_scorm
* @copyright 2017 onwards Ankit Agarwal <ankit.agrr@gmail.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_scorm\analytics\indicator;
defined('MOODLE_INTERNAL') || die();
/**
* Activity base class.
*
* @package mod_scorm
* @copyright 2017 onwards Ankit Agarwal <ankit.agrr@gmail.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
abstract class activity_base extends \core_analytics\local\indicator\community_of_inquiry_activity {
/**
* feedback_viewed_events
*
* @return string[]
*/
protected function feedback_viewed_events() {
// Any view after the data graded counts as feedback viewed.
return array('\mod_scorm\event\course_module_viewed');
}
/**
* Returns the name of the field that controls activity availability.
*
* @return null|string
*/
protected function get_timeclose_field() {
return 'timeclose';
}
}
@@ -0,0 +1,56 @@
<?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/>.
/**
* Cognitive depth indicator - scorm.
*
* @package mod_scorm
* @copyright 2017 David Monllao {@link http://www.davidmonllao.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_scorm\analytics\indicator;
defined('MOODLE_INTERNAL') || die();
/**
* Cognitive depth indicator - scorm.
*
* @package mod_scorm
* @copyright 2017 David Monllao {@link http://www.davidmonllao.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class cognitive_depth extends activity_base {
/**
* Returns the name.
*
* If there is a corresponding '_help' string this will be shown as well.
*
* @return \lang_string
*/
public static function get_name(): \lang_string {
return new \lang_string('indicator:cognitivedepth', 'mod_scorm');
}
public function get_indicator_type() {
return self::INDICATOR_COGNITIVE;
}
public function get_cognitive_depth_level(\cm_info $cm) {
return self::COGNITIVE_LEVEL_3;
}
}
@@ -0,0 +1,56 @@
<?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/>.
/**
* Social breadth indicator - scorm.
*
* @package mod_scorm
* @copyright 2017 David Monllao {@link http://www.davidmonllao.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_scorm\analytics\indicator;
defined('MOODLE_INTERNAL') || die();
/**
* Social breadth indicator - scorm.
*
* @package mod_scorm
* @copyright 2017 David Monllao {@link http://www.davidmonllao.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class social_breadth extends activity_base {
/**
* Returns the name.
*
* If there is a corresponding '_help' string this will be shown as well.
*
* @return \lang_string
*/
public static function get_name(): \lang_string {
return new \lang_string('indicator:socialbreadth', 'mod_scorm');
}
public function get_indicator_type() {
return self::INDICATOR_SOCIAL;
}
public function get_social_breadth_level(\cm_info $cm) {
return self::SOCIAL_LEVEL_2;
}
}
+77
View File
@@ -0,0 +1,77 @@
<?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/>.
declare(strict_types=1);
namespace mod_scorm\cache;
use cache_definition;
/**
* Cache data source for the scorm elements.
*
* @package mod_scorm
* @copyright 2023 Catalyst IT Ltd
* @author Dan Marsden <dan@danmarsden.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class elements implements \cache_data_source {
/** @var elements the singleton instance of this class. */
protected static $instance = null;
/**
* Returns an instance of the data source class that the cache can use for loading data using the other methods
* specified by this interface.
*
* @param cache_definition $definition
* @return object
*/
public static function get_instance_for_cache(cache_definition $definition): elements {
if (is_null(self::$instance)) {
self::$instance = new elements();
}
return self::$instance;
}
/**
* Loads the data for the key provided ready formatted for caching.
*
* @param string|int $key The key to load.
* @return string What ever data should be returned, or null if it can't be loaded.
* @throws \coding_exception
*/
public function load_for_cache($key): ?string {
global $DB;
$element = $DB->get_field('scorm_element', 'id', ['element' => $key]);
// Return null instead of false, because false will not be cached.
return $element ?: null;
}
/**
* Loads several keys for the cache.
*
* @param array $keys An array of keys each of which will be string|int.
* @return array An array of matching data items.
*/
public function load_many_for_cache(array $keys): array {
global $DB;
list ($elementsql, $params) = $DB->get_in_or_equal($keys);
$sql = "SELECT element, id
FROM {scorm_element}
WHERE element ".$elementsql;
return $DB->get_records_sql_menu($sql, $params);
}
}
@@ -0,0 +1,220 @@
<?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/>.
declare(strict_types=1);
namespace mod_scorm\completion;
defined('MOODLE_INTERNAL') || die();
use core_completion\activity_custom_completion;
require_once($CFG->dirroot.'/mod/scorm/locallib.php');
/**
* Activity custom completion subclass for the scorm activity.
*
* Contains the class for defining mod_scorm's custom completion rules
* and fetching a scorm instance's completion statuses for a user.
*
* @package mod_scorm
* @copyright Michael Hawkins <michaelh@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class custom_completion extends activity_custom_completion {
/**
* Fetches the completion state for a given completion rule.
*
* @param string $rule The completion rule.
* @return int The completion state.
*/
public function get_state(string $rule): int {
global $DB;
$this->validate_rule($rule);
// Base query used when fetching user's tracks data.
$basequery = "SELECT v.id, v.scoid, e.element, v.value
FROM {scorm_scoes_value} v
JOIN {scorm_attempt} a ON a.id = v.attemptid
JOIN {scorm_element} e ON e.id = v.elementid
WHERE a.scormid = ?
AND a.userid = ?";
switch ($rule) {
case 'completionstatusrequired':
$status = COMPLETION_INCOMPLETE;
$query = $basequery .
" AND e.element IN (
'cmi.core.lesson_status',
'cmi.completion_status',
'cmi.success_status'
)";
$tracks = $DB->get_records_sql($query, [$this->cm->instance, $this->userid]);
// Get available status list.
$statuses = array_flip(\scorm_status_options());
$requiredcompletionstatusid = $this->cm->customdata['customcompletionrules']['completionstatusrequired'] ?? 0;
$isanystatus = ($requiredcompletionstatusid == array_sum($statuses));
// Check at least one track meets the required completion status value(s).
foreach ($tracks as $track) {
if (array_key_exists($track->value, $statuses)
&& ($isanystatus || $statuses[$track->value] == $requiredcompletionstatusid)) {
$status = COMPLETION_COMPLETE;
break;
}
}
break;
case 'completionscorerequired':
$status = COMPLETION_INCOMPLETE;
$query = $basequery .
" AND e.element IN (
'cmi.core.score.raw',
'cmi.score.raw'
)";
$tracks = $DB->get_records_sql($query, [$this->cm->instance, $this->userid]);
$requiredscore = $this->cm->customdata['customcompletionrules']['completionscorerequired'];
// Check if any track meets or exceeds the minimum score required.
foreach ($tracks as $track) {
if (strlen($track->value) && (floatval($track->value) >= $requiredscore)) {
$status = COMPLETION_COMPLETE;
// No need to check any other tracks once condition is confirmed completed.
break;
}
}
break;
case 'completionstatusallscos':
// Assume complete unless we find a sco that is not complete.
$status = COMPLETION_COMPLETE;
$query = $basequery .
" AND e.element IN (
'cmi.core.lesson_status',
'cmi.completion_status',
'cmi.success_status'
)";
$tracks = $DB->get_records_sql($query, [$this->cm->instance, $this->userid]);
// Get available status list.
$statuses = array_flip(\scorm_status_options());
// Make a list of all sco IDs.
$scoids = [];
foreach ($tracks as $track) {
if (array_key_exists($track->value, $statuses)) {
$scoids[] = $track->scoid;
}
}
// Iterate over all scos and ensure each has a lesson_status.
$scos = $DB->get_records('scorm_scoes', ['scorm' => $this->cm->instance, 'scormtype' => 'sco']);
foreach ($scos as $sco) {
// If we find a sco without a lesson status, this condition is not completed.
if (!in_array($sco->id, $scoids)) {
$status = COMPLETION_INCOMPLETE;
}
}
break;
default:
$status = COMPLETION_INCOMPLETE;
break;
}
// If not yet meeting the requirement and no attempts remain to complete it, mark it as failed.
if ($status === COMPLETION_INCOMPLETE) {
$scorm = $DB->get_record('scorm', ['id' => $this->cm->instance]);
$attemptcount = scorm_get_attempt_count($this->userid, $scorm);
if ($scorm->maxattempt > 0 && $attemptcount >= $scorm->maxattempt) {
$status = COMPLETION_COMPLETE_FAIL;
}
}
return $status;
}
/**
* Fetch the list of custom completion rules that this module defines.
*
* @return array
*/
public static function get_defined_custom_rules(): array {
return [
'completionstatusrequired',
'completionscorerequired',
'completionstatusallscos',
];
}
/**
* Returns an associative array of the descriptions of custom completion rules.
*
* @return array
*/
public function get_custom_rule_descriptions(): array {
$scorerequired = $this->cm->customdata['customcompletionrules']['completionscorerequired'] ?? 0;
// Prepare completion status requirements string.
$statusstrings = \scorm_status_options();
$completionstatusid = $this->cm->customdata['customcompletionrules']['completionstatusrequired'] ?? 0;
if (array_key_exists($completionstatusid, $statusstrings)) {
// Single status required.
$statusrequired = $statusstrings[$completionstatusid];
} else {
// All statuses required.
$statusrequired = 'completedorpassed';
}
return [
'completionstatusrequired' => get_string("completiondetail:completionstatus{$statusrequired}", 'scorm'),
'completionscorerequired' => get_string('completiondetail:completionscore', 'scorm', $scorerequired),
'completionstatusallscos' => get_string('completiondetail:allscos', 'scorm'),
];
}
/**
* Returns an array of all completion rules, in the order they should be displayed to users.
*
* @return array
*/
public function get_sort_order(): array {
return [
'completionview',
'completionstatusallscos',
'completionstatusrequired',
'completionusegrade',
'completionpassgrade',
'completionscorerequired',
];
}
}
+70
View File
@@ -0,0 +1,70 @@
<?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/>.
/**
* Contains the class for fetching the important dates in mod_scorm for a given module instance and a user.
*
* @package mod_scorm
* @copyright 2021 Shamim Rezaie <shamim@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
declare(strict_types=1);
namespace mod_scorm;
use core\activity_dates;
/**
* Class for fetching the important dates in mod_scorm for a given module instance and a user.
*
* @copyright 2021 Shamim Rezaie <shamim@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class dates extends activity_dates {
/**
* Returns a list of important dates in mod_scorm
*
* @return array
*/
protected function get_dates(): array {
$timeopen = $this->cm->customdata['timeopen'] ?? null;
$timeclose = $this->cm->customdata['timeclose'] ?? null;
$now = time();
$dates = [];
if ($timeopen) {
$openlabelid = $timeopen > $now ? 'activitydate:opens' : 'activitydate:opened';
$dates[] = [
'dataid' => 'timeopen',
'label' => get_string($openlabelid, 'core_course'),
'timestamp' => (int) $timeopen,
];
}
if ($timeclose) {
$closelabelid = $timeclose > $now ? 'activitydate:closes' : 'activitydate:closed';
$dates[] = [
'dataid' => 'timeclose',
'label' => get_string($closelabelid, 'core_course'),
'timestamp' => (int) $timeclose,
];
}
return $dates;
}
}
@@ -0,0 +1,98 @@
<?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/>.
/**
* The mod_scorm attempt deleted event.
*
* @package mod_scorm
* @copyright 2013 onwards Ankit Agarwal
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_scorm\event;
defined('MOODLE_INTERNAL') || die();
/**
* The mod_scorm attempt deleted event class.
*
* @property-read array $other {
* Extra information about event properties.
*
* - int attemptid: Attempt id.
* }
*
* @package mod_scorm
* @since Moodle 2.7
* @copyright 2013 onwards Ankit Agarwal
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class attempt_deleted extends \core\event\base {
/**
* Init method.
*/
protected function init() {
$this->data['crud'] = 'd';
$this->data['edulevel'] = self::LEVEL_TEACHING;
}
/**
* Returns non-localised description of what happened.
*
* @return string
*/
public function get_description() {
return "The user with id '$this->userid' deleted the attempt with id '{$this->other['attemptid']}' " .
"for the scorm activity with course module id '$this->contextinstanceid'.";
}
/**
* Returns localised general event name.
*
* @return string
*/
public static function get_name() {
return get_string('eventattemptdeleted', 'mod_scorm');
}
/**
* Get URL related to the action
*
* @return \moodle_url
*/
public function get_url() {
return new \moodle_url('/mod/scorm/report.php', array('id' => $this->contextinstanceid));
}
/**
* Custom validation.
*
* @throws \coding_exception
* @return void
*/
protected function validate_data() {
parent::validate_data();
if (empty($this->other['attemptid'])) {
throw new \coding_exception('The \'attemptid\' must be set in other.');
}
}
public static function get_other_mapping() {
// Nothing to map.
return false;
}
}
@@ -0,0 +1,105 @@
<?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/>.
/**
* The mod_scorm generic CMI element submitted event.
*
* @package mod_scorm
* @copyright 2016 onwards Matteo Scaramuccia
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_scorm\event;
defined('MOODLE_INTERNAL') || die();
/**
* The mod_scorm generic CMI element submitted event class.
*
* @property-read array $other {
* Extra information about event properties.
*
* - int attemptid: Attempt id.
* - string cmielement: CMI element.
* - string cmivalue: CMI value.
* }
*
* @package mod_scorm
* @since Moodle 3.1
* @copyright 2016 onwards Matteo Scaramuccia
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
abstract class cmielement_submitted extends \core\event\base {
/**
* Init method.
*/
protected function init() {
$this->data['crud'] = 'u';
$this->data['edulevel'] = self::LEVEL_PARTICIPATING;
$this->data['objecttable'] = 'scorm_scoes_value';
}
/**
* Returns non-localised description of what happened.
*
* @return string
*/
public function get_description() {
return "The user with the id '$this->userid' submitted the element '{$this->other['cmielement']}' " .
"with the value of '{$this->other['cmivalue']}' " .
"for the attempt with the id '{$this->other['attemptid']}' " .
"for a scorm activity with the course module id '$this->contextinstanceid'.";
}
/**
* Get URL related to the action
*
* @return \moodle_url
*/
public function get_url() {
return new \moodle_url('/mod/scorm/report/userreport.php',
array('id' => $this->contextinstanceid, 'user' => $this->userid, 'attempt' => $this->other['attemptid']));
}
/**
* Custom validation.
*
* @throws \coding_exception
* @return void
*/
protected function validate_data() {
parent::validate_data();
if (empty($this->other['attemptid'])) {
throw new \coding_exception("The 'attemptid' must be set in other.");
}
if (empty($this->other['cmielement'])) {
throw new \coding_exception("The 'cmielement' must be set in other.");
}
// Trust that 'cmielement' represents a valid CMI datamodel element:
// just check that the given value starts with 'cmi.'.
if (strpos($this->other['cmielement'], 'cmi.', 0) !== 0) {
throw new \coding_exception(
"A valid 'cmielement' must start with 'cmi.' ({$this->other['cmielement']}).");
}
// Warning: 'cmivalue' could be also "0" e.g. when 'cmielement' represents a score.
if (!isset($this->other['cmivalue'])) {
throw new \coding_exception("The 'cmivalue' must be set in other.");
}
}
}
@@ -0,0 +1,38 @@
<?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/>.
/**
* The mod_scorm instance list viewed event.
*
* @package mod_scorm
* @copyright 2013 Ankit Agarwal
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_scorm\event;
defined('MOODLE_INTERNAL') || die();
/**
* The mod_scorm instance list viewed event class.
*
* @package mod_scorm
* @since Moodle 2.7
* @copyright 2013 Ankit Agarwal
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class course_module_instance_list_viewed extends \core\event\course_module_instance_list_viewed {
}
@@ -0,0 +1,51 @@
<?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/>.
/**
* The mod_scorm course module viewed event.
*
* @package mod_scorm
* @copyright 2013 onwards Ankit Agarwal
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_scorm\event;
defined('MOODLE_INTERNAL') || die();
/**
* The mod_scorm course module viewed event class.
*
* @package mod_scorm
* @since Moodle 2.7
* @copyright 2013 onwards Ankit Agarwal
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class course_module_viewed extends \core\event\course_module_viewed {
/**
* Init method.
*/
protected function init() {
$this->data['crud'] = 'r';
$this->data['edulevel'] = self::LEVEL_PARTICIPATING;
$this->data['objecttable'] = 'scorm';
}
public static function get_objectid_mapping() {
return array('db' => 'scorm', 'restore' => 'scorm');
}
}
@@ -0,0 +1,114 @@
<?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/>.
/**
* The mod_scorm interactions viewed event.
*
* @package mod_scorm
* @copyright 2013 onwards Ankit Agarwal
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_scorm\event;
defined('MOODLE_INTERNAL') || die();
/**
* The mod_scorm interactions viewed event class.
*
* @property-read array $other {
* Extra information about event properties.
*
* - int attemptid: Attempt id.
* - int instanceid: Instance id of the scorm activity.
* }
*
* @package mod_scorm
* @since Moodle 2.7
* @copyright 2013 onwards Ankit Agarwal
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class interactions_viewed extends \core\event\base {
/**
* Init method.
*/
protected function init() {
$this->data['crud'] = 'r';
$this->data['edulevel'] = self::LEVEL_TEACHING;
}
/**
* Returns non-localised description of what happened.
*
* @return string
*/
public function get_description() {
return "The user with id '$this->userid' viewed the interactions for the user with id '$this->relateduserid' " .
"for the scorm activity with course module id '$this->contextinstanceid'.";
}
/**
* Returns localised general event name.
*
* @return string
*/
public static function get_name() {
return get_string('eventinteractionsviewed', 'mod_scorm');
}
/**
* Get URL related to the action
*
* @return \moodle_url
*/
public function get_url() {
$params = array(
'id' => $this->contextinstanceid,
'user' => $this->relateduserid,
'attempt' => $this->other['attemptid']
);
return new \moodle_url('/mod/scorm/userreportinteractions.php', $params);
}
/**
* Custom validation.
*
* @throws \coding_exception
* @return void
*/
protected function validate_data() {
parent::validate_data();
if (!isset($this->relateduserid)) {
throw new \coding_exception('The \'relateduserid\' must be set.');
}
if (empty($this->other['attemptid'])) {
throw new \coding_exception('The \'attemptid\' must be set in other.');
}
if (empty($this->other['instanceid'])) {
throw new \coding_exception('The \'instanceid\' must be set in other.');
}
}
public static function get_other_mapping() {
$othermapped = array();
$othermapped['instanceid'] = array('db' => 'scorm', 'restore' => 'scorm');
return $othermapped;
}
}
+105
View File
@@ -0,0 +1,105 @@
<?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/>.
/**
* The mod_scorm report viewed event.
*
* @package mod_scorm
* @copyright 2013 onwards Ankit Agarwal
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_scorm\event;
defined('MOODLE_INTERNAL') || die();
/**
* The mod_scorm report viewed event class.
*
* @property-read array $other {
* Extra information about event properties.
*
* - int scormid: The ID of the scorm.
* - string mode: Mode of the report viewed.
* }
*
* @package mod_scorm
* @since Moodle 2.7
* @copyright 2013 onwards Ankit Agarwal
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class report_viewed extends \core\event\base {
/**
* Init method.
*/
protected function init() {
$this->data['crud'] = 'r';
$this->data['edulevel'] = self::LEVEL_TEACHING;
}
/**
* Returns non-localised description of what happened.
*
* @return string
*/
public function get_description() {
return "The user with id '$this->userid' viewed the scorm report '{$this->other['mode']}' for the scorm with " .
"course module id '$this->contextinstanceid'.";
}
/**
* Returns localised general event name.
*
* @return string
*/
public static function get_name() {
return get_string('eventreportviewed', 'mod_scorm');
}
/**
* Get URL related to the action
*
* @return \moodle_url
*/
public function get_url() {
return new \moodle_url('/mod/scorm/report.php', array('id' => $this->contextinstanceid, 'mode' => $this->other['mode']));
}
/**
* Custom validation.
*
* @throws \coding_exception
* @return void
*/
protected function validate_data() {
parent::validate_data();
if (empty($this->other['scormid'])) {
throw new \coding_exception('The \'scormid\' value must be set in other.');
}
if (empty($this->other['mode'])) {
throw new \coding_exception('The \'mode\' value must be set in other.');
}
}
public static function get_other_mapping() {
$othermapped = array();
$othermapped['scormid'] = array('db' => 'scorm', 'restore' => 'scorm');
return $othermapped;
}
}
+106
View File
@@ -0,0 +1,106 @@
<?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/>.
/**
* The mod_scorm sco launched event.
*
* @package mod_scorm
* @copyright 2013 onwards Ankit Agarwal
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_scorm\event;
defined('MOODLE_INTERNAL') || die();
/**
* The mod_scorm sco launched event class.
*
* @property-read array $other {
* Extra information about event properties.
*
* - string loadedcontent: A reference to the content loaded.
* - int instanceid: (optional) Instance id of the scorm activity.
* }
*
* @package mod_scorm
* @since Moodle 2.7
* @copyright 2013 onwards Ankit Agarwal
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class sco_launched extends \core\event\base {
/**
* Init method.
*/
protected function init() {
$this->data['crud'] = 'r';
$this->data['edulevel'] = self::LEVEL_PARTICIPATING;
$this->data['objecttable'] = 'scorm_scoes';
}
/**
* Returns non-localised description of what happened.
*
* @return string
*/
public function get_description() {
return "The user with id '$this->userid' launched the sco with id '$this->objectid' for the scorm with " .
"course module id '$this->contextinstanceid'.";
}
/**
* Returns localised general event name.
*
* @return string
*/
public static function get_name() {
return get_string('eventscolaunched', 'mod_scorm');
}
/**
* Get URL related to the action
*
* @return \moodle_url
*/
public function get_url() {
return new \moodle_url('/mod/scorm/player.php', array('cm' => $this->contextinstanceid, 'scoid' => $this->objectid));
}
/**
* Custom validation.
*
* @throws \coding_exception
* @return void
*/
protected function validate_data() {
parent::validate_data();
if (empty($this->other['loadedcontent'])) {
throw new \coding_exception('The \'loadedcontent\' value must be set in other.');
}
}
public static function get_objectid_mapping() {
return array('db' => 'scorm_scoes', 'restore' => 'scorm_sco');
}
public static function get_other_mapping() {
$othermapped = array();
$othermapped['instanceid'] = array('db' => 'scorm', 'restore' => 'scorm');
return $othermapped;
}
}
@@ -0,0 +1,71 @@
<?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/>.
/**
* The mod_scorm raw score submitted event.
*
* @package mod_scorm
* @copyright 2016 onwards Matteo Scaramuccia
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_scorm\event;
defined('MOODLE_INTERNAL') || die();
/**
* The mod_scorm raw score submitted event class.
*
* @property-read array $other {
* Extra information about event properties.
*
* - int attemptid: Attempt id.
* - string cmielement: CMI element representing a raw score.
* - string cmivalue: CMI value.
* }
*
* @package mod_scorm
* @since Moodle 3.1
* @copyright 2016 onwards Matteo Scaramuccia
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class scoreraw_submitted extends cmielement_submitted {
/**
* Returns localised general event name.
*
* @return string
*/
public static function get_name() {
return get_string('eventscorerawsubmitted', 'mod_scorm');
}
/**
* Custom validation.
*
* @throws \coding_exception
* @return void
*/
protected function validate_data() {
parent::validate_data();
if (!strstr($this->other['cmielement'], '.score.raw')) {
throw new \coding_exception(
"The 'cmielement' must represents a valid CMI raw score ({$this->other['cmielement']}).");
}
// Note: we trust that 'cmivalue' represents a valid SCORM CMI score value.
}
}
@@ -0,0 +1,76 @@
<?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/>.
/**
* The mod_scorm status submitted event.
*
* @package mod_scorm
* @copyright 2016 onwards Matteo Scaramuccia
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_scorm\event;
defined('MOODLE_INTERNAL') || die();
/**
* The mod_scorm status submitted event class.
*
* @property-read array $other {
* Extra information about event properties.
*
* - int attemptid: Attempt id.
* - string cmielement: CMI element representing a status.
* - string cmivalue: CMI value.
* }
*
* @package mod_scorm
* @since Moodle 3.1
* @copyright 2016 onwards Matteo Scaramuccia
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class status_submitted extends cmielement_submitted {
/**
* Returns localised general event name.
*
* @return string
*/
public static function get_name() {
return get_string('eventstatussubmitted', 'mod_scorm');
}
/**
* Custom validation.
*
* @throws \coding_exception
* @return void
*/
protected function validate_data() {
parent::validate_data();
if (!in_array($this->other['cmielement'],
array('cmi.completion_status', 'cmi.core.lesson_status', 'cmi.success_status'))) {
throw new \coding_exception(
"The 'cmielement' must represents a valid CMI status element ({$this->other['cmielement']}).");
}
if (!in_array($this->other['cmivalue'],
array('passed', 'completed', 'failed', 'incomplete', 'browsed', 'not attempted', 'unknown'))) {
throw new \coding_exception(
"The 'cmivalue' must represents a valid CMI status value ({$this->other['cmivalue']}).");
}
}
}
+118
View File
@@ -0,0 +1,118 @@
<?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/>.
/**
* The mod_scorm tracks viewed event.
*
* @package mod_scorm
* @copyright 2013 onwards Ankit Agarwal
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_scorm\event;
defined('MOODLE_INTERNAL') || die();
/**
* The mod_scorm tracks viewed event class.
*
* @property-read array $other {
* Extra information about event properties.
*
* - int attemptid: Attempt id.
* - int instanceid: Instance id of the scorm activity.
* - int scoid: Sco Id for which the trackes are viewed.
* }
*
* @package mod_scorm
* @since Moodle 2.7
* @copyright 2013 onwards Ankit Agarwal
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class tracks_viewed extends \core\event\base {
/**
* Init method.
*/
protected function init() {
$this->data['crud'] = 'r';
$this->data['edulevel'] = self::LEVEL_TEACHING;
}
/**
* Returns non-localised description of what happened.
*
* @return string
*/
public function get_description() {
return "The user with id '$this->userid' viewed the tracks for the user with id '$this->relateduserid' " .
"for the scorm activity with course module id '$this->contextinstanceid'.";
}
/**
* Returns localised general event name.
*
* @return string
*/
public static function get_name() {
return get_string('eventtracksviewed', 'mod_scorm');
}
/**
* Get URL related to the action
*
* @return \moodle_url
*/
public function get_url() {
$params = array(
'id' => $this->contextinstanceid,
'user' => $this->relateduserid,
'attempt' => $this->other['attemptid'],
'scoid' => $this->other['scoid']
);
return new \moodle_url('/mod/scorm/userreporttracks.php', $params);
}
/**
* Custom validation.
*
* @throws \coding_exception
* @return void
*/
protected function validate_data() {
parent::validate_data();
if (!isset($this->relateduserid)) {
throw new \coding_exception('The \'relateduserid\' must be set.');
}
if (empty($this->other['attemptid'])) {
throw new \coding_exception('The \'attemptid\' value must be set in other.');
}
if (empty($this->other['instanceid'])) {
throw new \coding_exception('The \'instanceid\' value must be set in other.');
}
if (empty($this->other['scoid'])) {
throw new \coding_exception('The \'scoid\' value must be set in other.');
}
}
public static function get_other_mapping() {
$othermapped = array();
$othermapped['instanceid'] = array('db' => 'scorm', 'restore' => 'scorm');
$othermapped['scoid'] = array('db' => 'scorm_scoes', 'restore' => 'scorm_scoe');
return $othermapped;
}
}
@@ -0,0 +1,111 @@
<?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/>.
/**
* The mod_scorm tracks user report viewed event.
*
* @package mod_scorm
* @copyright 2013 onwards Ankit Agarwal
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_scorm\event;
defined('MOODLE_INTERNAL') || die();
/**
* The mod_scorm tracks user report viewed event class.
*
* @property-read array $other {
* Extra information about event properties.
*
* - int attemptid: Attempt id.
* - int instanceid: Instance id of the scorm activity.
* }
*
* @package mod_scorm
* @since Moodle 2.7
* @copyright 2013 onwards Ankit Agarwal
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class user_report_viewed extends \core\event\base {
/**
* Init method.
*/
protected function init() {
$this->data['crud'] = 'r';
$this->data['edulevel'] = self::LEVEL_TEACHING;
}
/**
* Returns non-localised description of what happened.
*
* @return string
*/
public function get_description() {
return "The user with id '$this->userid' viewed the scorm user report for the user with id '$this->relateduserid'.";
}
/**
* Returns localised general event name.
*
* @return string
*/
public static function get_name() {
return get_string('eventuserreportviewed', 'mod_scorm');
}
/**
* Get URL related to the action
*
* @return \moodle_url
*/
public function get_url() {
$params = array(
'id' => $this->contextinstanceid,
'user' => $this->relateduserid,
'attempt' => $this->other['attemptid']
);
return new \moodle_url('/mod/scorm/userreport.php', $params);
}
/**
* Custom validation.
*
* @throws \coding_exception
* @return void
*/
protected function validate_data() {
parent::validate_data();
if (!isset($this->relateduserid)) {
throw new \coding_exception('The \'relateduserid\' must be set.');
}
if (empty($this->other['attemptid'])) {
throw new \coding_exception('The \'attemptid\' value must be set in other.');
}
if (empty($this->other['instanceid'])) {
throw new \coding_exception('The \'instanceid\' value must be set in other.');
}
}
public static function get_other_mapping() {
$othermapped = array();
$othermapped['instanceid'] = array('db' => 'scorm', 'restore' => 'scorm');
return $othermapped;
}
}
+986
View File
@@ -0,0 +1,986 @@
<?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/>.
/**
* SCORM module external API
*
* @package mod_scorm
* @category external
* @copyright 2015 Juan Leyva <juan@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @since Moodle 3.0
*/
use core_course\external\helper_for_get_mods_by_courses;
use core_external\external_api;
use core_external\external_function_parameters;
use core_external\external_multiple_structure;
use core_external\external_single_structure;
use core_external\external_value;
use core_external\external_warnings;
use core_external\util;
defined('MOODLE_INTERNAL') || die;
require_once($CFG->dirroot . '/mod/scorm/lib.php');
require_once($CFG->dirroot . '/mod/scorm/locallib.php');
/**
* SCORM module external functions
*
* @package mod_scorm
* @category external
* @copyright 2015 Juan Leyva <juan@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @since Moodle 3.0
*/
class mod_scorm_external extends external_api {
/**
* Returns description of method parameters
*
* @return external_function_parameters
* @since Moodle 3.0
*/
public static function view_scorm_parameters() {
return new external_function_parameters(
array(
'scormid' => new external_value(PARAM_INT, 'scorm instance id')
)
);
}
/**
* Trigger the course module viewed event.
*
* @param int $scormid the scorm instance id
* @return array of warnings and status result
* @since Moodle 3.0
* @throws moodle_exception
*/
public static function view_scorm($scormid) {
global $DB, $CFG;
require_once($CFG->dirroot . '/mod/scorm/lib.php');
$params = self::validate_parameters(self::view_scorm_parameters(),
array(
'scormid' => $scormid
));
$warnings = array();
// Request and permission validation.
$scorm = $DB->get_record('scorm', array('id' => $params['scormid']), '*', MUST_EXIST);
list($course, $cm) = get_course_and_cm_from_instance($scorm, 'scorm');
$context = context_module::instance($cm->id);
self::validate_context($context);
// Call the scorm/lib API.
scorm_view($scorm, $course, $cm, $context);
$result = array();
$result['status'] = true;
$result['warnings'] = $warnings;
return $result;
}
/**
* Returns description of method result value
*
* @return \core_external\external_description
* @since Moodle 3.0
*/
public static function view_scorm_returns() {
return new external_single_structure(
array(
'status' => new external_value(PARAM_BOOL, 'status: true if success'),
'warnings' => new external_warnings()
)
);
}
/**
* Describes the parameters for get_scorm_attempt_count.
*
* @return external_function_parameters
* @since Moodle 3.0
*/
public static function get_scorm_attempt_count_parameters() {
return new external_function_parameters(
array(
'scormid' => new external_value(PARAM_INT, 'SCORM instance id'),
'userid' => new external_value(PARAM_INT, 'User id'),
'ignoremissingcompletion' => new external_value(PARAM_BOOL,
'Ignores attempts that haven\'t reported a grade/completion',
VALUE_DEFAULT, false),
)
);
}
/**
* Return the number of attempts done by a user in the given SCORM.
*
* @param int $scormid the scorm id
* @param int $userid the user id
* @param bool $ignoremissingcompletion ignores attempts that haven't reported a grade/completion
* @return array of warnings and the attempts count
* @since Moodle 3.0
*/
public static function get_scorm_attempt_count($scormid, $userid, $ignoremissingcompletion = false) {
global $USER, $DB;
$params = self::validate_parameters(self::get_scorm_attempt_count_parameters(),
array('scormid' => $scormid, 'userid' => $userid,
'ignoremissingcompletion' => $ignoremissingcompletion));
$attempts = array();
$warnings = array();
$scorm = $DB->get_record('scorm', array('id' => $params['scormid']), '*', MUST_EXIST);
$cm = get_coursemodule_from_instance('scorm', $scorm->id);
$context = context_module::instance($cm->id);
self::validate_context($context);
$user = core_user::get_user($params['userid'], '*', MUST_EXIST);
core_user::require_active_user($user);
// Extra checks so only users with permissions can view other users attempts.
if ($USER->id != $user->id) {
require_capability('mod/scorm:viewreport', $context);
}
// If the SCORM is not open this function will throw exceptions.
scorm_require_available($scorm);
$attemptscount = scorm_get_attempt_count($user->id, $scorm, false, $params['ignoremissingcompletion']);
$result = array();
$result['attemptscount'] = $attemptscount;
$result['warnings'] = $warnings;
return $result;
}
/**
* Describes the get_scorm_attempt_count return value.
*
* @return external_single_structure
* @since Moodle 3.0
*/
public static function get_scorm_attempt_count_returns() {
return new external_single_structure(
array(
'attemptscount' => new external_value(PARAM_INT, 'Attempts count'),
'warnings' => new external_warnings(),
)
);
}
/**
* Describes the parameters for get_scorm_scoes.
*
* @return external_function_parameters
* @since Moodle 3.0
*/
public static function get_scorm_scoes_parameters() {
return new external_function_parameters(
array(
'scormid' => new external_value(PARAM_INT, 'scorm instance id'),
'organization' => new external_value(PARAM_RAW, 'organization id', VALUE_DEFAULT, '')
)
);
}
/**
* Returns a list containing all the scoes data related to the given scorm id
*
* @param int $scormid the scorm id
* @param string $organization the organization id
* @return array warnings and the scoes data
* @since Moodle 3.0
*/
public static function get_scorm_scoes($scormid, $organization = '') {
global $DB;
$params = self::validate_parameters(self::get_scorm_scoes_parameters(),
array('scormid' => $scormid, 'organization' => $organization));
$scoes = array();
$warnings = array();
$scorm = $DB->get_record('scorm', array('id' => $params['scormid']), '*', MUST_EXIST);
$cm = get_coursemodule_from_instance('scorm', $scorm->id);
$context = context_module::instance($cm->id);
self::validate_context($context);
// Check settings / permissions to view the SCORM.
scorm_require_available($scorm, true, $context);
if (!$scoes = scorm_get_scoes($scorm->id, $params['organization'])) {
// Function scorm_get_scoes return false, not an empty array.
$scoes = array();
} else {
$scoreturnstructure = self::get_scorm_scoes_returns();
foreach ($scoes as $sco) {
$extradata = array();
foreach ($sco as $element => $value) {
// Check if the element is extra data (not a basic SCO element).
if (!isset($scoreturnstructure->keys['scoes']->content->keys[$element])) {
$extradata[] = array(
'element' => $element,
'value' => $value
);
}
}
$sco->extradata = $extradata;
}
}
$result = array();
$result['scoes'] = $scoes;
$result['warnings'] = $warnings;
return $result;
}
/**
* Describes the get_scorm_scoes return value.
*
* @return external_single_structure
* @since Moodle 3.0
*/
public static function get_scorm_scoes_returns() {
return new external_single_structure(
array(
'scoes' => new external_multiple_structure(
new external_single_structure(
array(
'id' => new external_value(PARAM_INT, 'sco id'),
'scorm' => new external_value(PARAM_INT, 'scorm id'),
'manifest' => new external_value(PARAM_NOTAGS, 'manifest id'),
'organization' => new external_value(PARAM_NOTAGS, 'organization id'),
'parent' => new external_value(PARAM_NOTAGS, 'parent'),
'identifier' => new external_value(PARAM_NOTAGS, 'identifier'),
'launch' => new external_value(PARAM_NOTAGS, 'launch file'),
'scormtype' => new external_value(PARAM_ALPHA, 'scorm type (asset, sco)'),
'title' => new external_value(PARAM_NOTAGS, 'sco title'),
'sortorder' => new external_value(PARAM_INT, 'sort order'),
'extradata' => new external_multiple_structure(
new external_single_structure(
array(
'element' => new external_value(PARAM_RAW, 'element name'),
'value' => new external_value(PARAM_RAW, 'element value')
)
), 'Additional SCO data', VALUE_OPTIONAL
)
), 'SCORM SCO data'
)
),
'warnings' => new external_warnings(),
)
);
}
/**
* Describes the parameters for get_scorm_user_data.
*
* @return external_function_parameters
* @since Moodle 3.0
*/
public static function get_scorm_user_data_parameters() {
return new external_function_parameters(
array(
'scormid' => new external_value(PARAM_INT, 'scorm instance id'),
'attempt' => new external_value(PARAM_INT, 'attempt number')
)
);
}
/**
* Retrieves user tracking and SCO data and default SCORM values
*
* @param int $scormid the scorm id
* @param int $attempt the attempt number
* @return array warnings and the scoes data
* @throws moodle_exception
* @since Moodle 3.0
*/
public static function get_scorm_user_data($scormid, $attempt) {
global $CFG, $DB;
$params = self::validate_parameters(self::get_scorm_user_data_parameters(),
array('scormid' => $scormid, 'attempt' => $attempt));
$data = array();
$warnings = array();
$scorm = $DB->get_record('scorm', array('id' => $params['scormid']), '*', MUST_EXIST);
$cm = get_coursemodule_from_instance('scorm', $scorm->id);
$context = context_module::instance($cm->id);
self::validate_context($context);
scorm_require_available($scorm, true, $context);
$scorm->version = strtolower(clean_param($scorm->version, PARAM_SAFEDIR));
if (!file_exists($CFG->dirroot.'/mod/scorm/datamodels/'.$scorm->version.'lib.php')) {
$scorm->version = 'scorm_12';
}
require_once($CFG->dirroot.'/mod/scorm/datamodels/'.$scorm->version.'lib.php');
if ($scoes = scorm_get_scoes($scorm->id)) {
$def = new stdClass();
$user = new stdClass();
foreach ($scoes as $sco) {
$def->{$sco->id} = new stdClass();
$user->{$sco->id} = new stdClass();
// We force mode normal, this can be override by the client at any time.
$def->{$sco->id} = get_scorm_default($user->{$sco->id}, $scorm, $sco->id, $params['attempt'], 'normal');
$userdata = array();
$defaultdata = array();
foreach ((array) $user->{$sco->id} as $key => $val) {
$userdata[] = array(
'element' => $key,
'value' => $val
);
}
foreach ($def->{$sco->id} as $key => $val) {
$defaultdata[] = array(
'element' => $key,
'value' => $val
);
}
$data[] = array(
'scoid' => $sco->id,
'userdata' => $userdata,
'defaultdata' => $defaultdata,
);
}
}
$result = array();
$result['data'] = $data;
$result['warnings'] = $warnings;
return $result;
}
/**
* Describes the get_scorm_user_data return value.
*
* @return external_single_structure
* @since Moodle 3.0
*/
public static function get_scorm_user_data_returns() {
return new external_single_structure(
array(
'data' => new external_multiple_structure(
new external_single_structure(
array(
'scoid' => new external_value(PARAM_INT, 'sco id'),
'userdata' => new external_multiple_structure(
new external_single_structure(
array(
'element' => new external_value(PARAM_RAW, 'element name'),
'value' => new external_value(PARAM_RAW, 'element value')
)
)
),
'defaultdata' => new external_multiple_structure(
new external_single_structure(
array(
'element' => new external_value(PARAM_RAW, 'element name'),
'value' => new external_value(PARAM_RAW, 'element value')
)
)
),
), 'SCO data'
)
),
'warnings' => new external_warnings(),
)
);
}
/**
* Describes the parameters for insert_scorm_tracks.
*
* @return external_function_parameters
* @since Moodle 3.0
*/
public static function insert_scorm_tracks_parameters() {
return new external_function_parameters(
array(
'scoid' => new external_value(PARAM_INT, 'SCO id'),
'attempt' => new external_value(PARAM_INT, 'attempt number'),
'tracks' => new external_multiple_structure(
new external_single_structure(
array(
'element' => new external_value(PARAM_RAW, 'element name'),
'value' => new external_value(PARAM_RAW, 'element value')
)
)
),
)
);
}
/**
* Saves a SCORM tracking record.
* It will overwrite any existing tracking data for this attempt.
* Validation should be performed before running the function to ensure the user will not lose any existing attempt data.
*
* @param int $scoid the SCO id
* @param string $attempt the attempt number
* @param array $tracks the track records to be stored
* @return array warnings and the scoes data
* @throws moodle_exception
* @since Moodle 3.0
*/
public static function insert_scorm_tracks($scoid, $attempt, $tracks) {
global $USER, $DB;
$params = self::validate_parameters(self::insert_scorm_tracks_parameters(),
array('scoid' => $scoid, 'attempt' => $attempt, 'tracks' => $tracks));
$trackids = array();
$warnings = array();
$sco = scorm_get_sco($params['scoid'], SCO_ONLY);
if (!$sco) {
throw new moodle_exception('cannotfindsco', 'scorm');
}
$scorm = $DB->get_record('scorm', array('id' => $sco->scorm), '*', MUST_EXIST);
$cm = get_coursemodule_from_instance('scorm', $scorm->id);
$context = context_module::instance($cm->id);
self::validate_context($context);
// Check settings / permissions to view the SCORM.
require_capability('mod/scorm:savetrack', $context);
// Check settings / permissions to view the SCORM.
scorm_require_available($scorm);
$attemptobject = scorm_get_attempt($USER->id, $scorm->id, $params['attempt']);
foreach ($params['tracks'] as $track) {
$element = $track['element'];
$value = $track['value'];
$trackid = scorm_insert_track($USER->id, $scorm->id, $sco->id, $attemptobject, $element, $value,
$scorm->forcecompleted);
if ($trackid) {
$trackids[] = $trackid;
} else {
$warnings[] = array(
'item' => 'scorm',
'itemid' => $scorm->id,
'warningcode' => 1,
'message' => 'Element: ' . $element . ' was not saved'
);
}
}
$result = array();
$result['trackids'] = $trackids;
$result['warnings'] = $warnings;
return $result;
}
/**
* Describes the insert_scorm_tracks return value.
*
* @return external_single_structure
* @since Moodle 3.0
*/
public static function insert_scorm_tracks_returns() {
return new external_single_structure(
array(
'trackids' => new external_multiple_structure(new external_value(PARAM_INT, 'track id')),
'warnings' => new external_warnings(),
)
);
}
/**
* Describes the parameters for get_scorm_sco_tracks.
*
* @return external_function_parameters
* @since Moodle 3.0
*/
public static function get_scorm_sco_tracks_parameters() {
return new external_function_parameters(
array(
'scoid' => new external_value(PARAM_INT, 'sco id'),
'userid' => new external_value(PARAM_INT, 'user id'),
'attempt' => new external_value(PARAM_INT, 'attempt number (0 for last attempt)', VALUE_DEFAULT, 0)
)
);
}
/**
* Retrieves SCO tracking data for the given user id and attempt number
*
* @param int $scoid the sco id
* @param int $userid the user id
* @param int $attempt the attempt number
* @return array warnings and the scoes data
* @since Moodle 3.0
*/
public static function get_scorm_sco_tracks($scoid, $userid, $attempt = 0) {
global $USER, $DB;
$params = self::validate_parameters(self::get_scorm_sco_tracks_parameters(),
array('scoid' => $scoid, 'userid' => $userid, 'attempt' => $attempt));
$tracks = array();
$warnings = array();
$sco = scorm_get_sco($params['scoid'], SCO_ONLY);
if (!$sco) {
throw new moodle_exception('cannotfindsco', 'scorm');
}
$scorm = $DB->get_record('scorm', array('id' => $sco->scorm), '*', MUST_EXIST);
$cm = get_coursemodule_from_instance('scorm', $scorm->id);
$context = context_module::instance($cm->id);
self::validate_context($context);
$user = core_user::get_user($params['userid'], '*', MUST_EXIST);
core_user::require_active_user($user);
// Extra checks so only users with permissions can view other users attempts.
if ($USER->id != $user->id) {
require_capability('mod/scorm:viewreport', $context);
}
scorm_require_available($scorm, true, $context);
if (empty($params['attempt'])) {
$params['attempt'] = scorm_get_last_attempt($scorm->id, $user->id);
}
$attempted = false;
if ($scormtracks = scorm_get_tracks($sco->id, $params['userid'], $params['attempt'])) {
// Check if attempted.
if ($scormtracks->status != '') {
$attempted = true;
foreach ($scormtracks as $element => $value) {
$tracks[] = array(
'element' => $element,
'value' => $value,
);
}
}
}
if (!$attempted) {
$warnings[] = array(
'item' => 'attempt',
'itemid' => $params['attempt'],
'warningcode' => 'notattempted',
'message' => get_string('notattempted', 'scorm')
);
}
$result = array();
$result['data']['attempt'] = $params['attempt'];
$result['data']['tracks'] = $tracks;
$result['warnings'] = $warnings;
return $result;
}
/**
* Describes the get_scorm_sco_tracks return value.
*
* @return external_single_structure
* @since Moodle 3.0
*/
public static function get_scorm_sco_tracks_returns() {
return new external_single_structure(
array(
'data' => new external_single_structure(
array(
'attempt' => new external_value(PARAM_INT, 'Attempt number'),
'tracks' => new external_multiple_structure(
new external_single_structure(
array(
'element' => new external_value(PARAM_RAW, 'Element name'),
'value' => new external_value(PARAM_RAW, 'Element value')
), 'Tracks data'
)
),
), 'SCO data'
),
'warnings' => new external_warnings(),
)
);
}
/**
* Describes the parameters for get_scorms_by_courses.
*
* @return external_function_parameters
* @since Moodle 3.0
*/
public static function get_scorms_by_courses_parameters() {
return new external_function_parameters (
array(
'courseids' => new external_multiple_structure(
new external_value(PARAM_INT, 'course id'), 'Array of course ids', VALUE_DEFAULT, array()
),
)
);
}
/**
* Returns a list of scorms in a provided list of courses,
* if no list is provided all scorms that the user can view will be returned.
*
* @param array $courseids the course ids
* @return array the scorm details
* @since Moodle 3.0
*/
public static function get_scorms_by_courses($courseids = array()) {
global $CFG;
$returnedscorms = array();
$warnings = array();
$params = self::validate_parameters(self::get_scorms_by_courses_parameters(), array('courseids' => $courseids));
$courses = array();
if (empty($params['courseids'])) {
$courses = enrol_get_my_courses();
$params['courseids'] = array_keys($courses);
}
// Ensure there are courseids to loop through.
if (!empty($params['courseids'])) {
list($courses, $warnings) = util::validate_courses($params['courseids'], $courses);
// Get the scorms in this course, this function checks users visibility permissions.
// We can avoid then additional validate_context calls.
$scorms = get_all_instances_in_courses("scorm", $courses);
$fs = get_file_storage();
foreach ($scorms as $scorm) {
$context = context_module::instance($scorm->coursemodule);
// Entry to return.
$module = helper_for_get_mods_by_courses::standard_coursemodule_element_values($scorm, 'mod_scorm');
// Check if the SCORM open and return warnings if so.
list($open, $openwarnings) = scorm_get_availability_status($scorm, true, $context);
if (!$open) {
foreach ($openwarnings as $warningkey => $warningdata) {
$warnings[] = array(
'item' => 'scorm',
'itemid' => $scorm->id,
'warningcode' => $warningkey,
'message' => get_string($warningkey, 'scorm', $warningdata)
);
}
} else {
$module['packagesize'] = 0;
// SCORM size.
if ($scorm->scormtype === SCORM_TYPE_LOCAL or $scorm->scormtype === SCORM_TYPE_LOCALSYNC) {
if ($packagefile = $fs->get_file($context->id, 'mod_scorm', 'package', 0, '/', $scorm->reference)) {
$module['packagesize'] = $packagefile->get_filesize();
// Download URL.
$module['packageurl'] = moodle_url::make_webservice_pluginfile_url(
$context->id, 'mod_scorm', 'package', 0, '/', $scorm->reference)->out(false);
}
}
$module['protectpackagedownloads'] = get_config('scorm', 'protectpackagedownloads');
$viewablefields = array('version', 'maxgrade', 'grademethod', 'whatgrade', 'maxattempt', 'forcecompleted',
'forcenewattempt', 'lastattemptlock', 'displayattemptstatus', 'displaycoursestructure',
'sha1hash', 'md5hash', 'revision', 'launch', 'skipview', 'hidebrowse', 'hidetoc', 'nav',
'navpositionleft', 'navpositiontop', 'auto', 'popup', 'width', 'height', 'timeopen',
'timeclose', 'scormtype', 'reference');
// Check additional permissions for returning optional private settings.
if (has_capability('moodle/course:manageactivities', $context)) {
$additionalfields = array('updatefreq', 'options', 'completionstatusrequired', 'completionscorerequired',
'completionstatusallscos', 'autocommit', 'timemodified');
$viewablefields = array_merge($viewablefields, $additionalfields);
}
foreach ($viewablefields as $field) {
$module[$field] = $scorm->{$field};
}
}
$returnedscorms[] = $module;
}
}
$settings = [
[
'name' => 'scormstandard',
'value' => get_config('scorm', 'scormstandard'),
]
];
$result = [
'scorms' => $returnedscorms,
'options' => $settings,
'warnings' => $warnings
];
return $result;
}
/**
* Describes the get_scorms_by_courses return value.
*
* @return external_single_structure
* @since Moodle 3.0
*/
public static function get_scorms_by_courses_returns() {
return new external_single_structure(
array(
'scorms' => new external_multiple_structure(
new external_single_structure(array_merge(
helper_for_get_mods_by_courses::standard_coursemodule_elements_returns(),
[
'packagesize' => new external_value(PARAM_INT, 'SCORM zip package size', VALUE_OPTIONAL),
'packageurl' => new external_value(PARAM_URL, 'SCORM zip package URL', VALUE_OPTIONAL),
'version' => new external_value(PARAM_NOTAGS, 'SCORM version (SCORM_12, SCORM_13, SCORM_AICC)',
VALUE_OPTIONAL),
'maxgrade' => new external_value(PARAM_INT, 'Max grade', VALUE_OPTIONAL),
'grademethod' => new external_value(PARAM_INT, 'Grade method', VALUE_OPTIONAL),
'whatgrade' => new external_value(PARAM_INT, 'What grade', VALUE_OPTIONAL),
'maxattempt' => new external_value(PARAM_INT, 'Maximum number of attemtps', VALUE_OPTIONAL),
'forcecompleted' => new external_value(PARAM_BOOL, 'Status current attempt is forced to "completed"',
VALUE_OPTIONAL),
'forcenewattempt' => new external_value(PARAM_INT, 'Controls re-entry behaviour',
VALUE_OPTIONAL),
'lastattemptlock' => new external_value(PARAM_BOOL, 'Prevents to launch new attempts once finished',
VALUE_OPTIONAL),
'displayattemptstatus' => new external_value(PARAM_INT, 'How to display attempt status',
VALUE_OPTIONAL),
'displaycoursestructure' => new external_value(PARAM_BOOL, 'Display contents structure',
VALUE_OPTIONAL),
'sha1hash' => new external_value(PARAM_NOTAGS, 'Package content or ext path hash', VALUE_OPTIONAL),
'md5hash' => new external_value(PARAM_NOTAGS, 'MD5 Hash of package file', VALUE_OPTIONAL),
'revision' => new external_value(PARAM_INT, 'Revison number', VALUE_OPTIONAL),
'launch' => new external_value(PARAM_INT, 'First content to launch', VALUE_OPTIONAL),
'skipview' => new external_value(PARAM_INT, 'How to skip the content structure page', VALUE_OPTIONAL),
'hidebrowse' => new external_value(PARAM_BOOL, 'Disable preview mode?', VALUE_OPTIONAL),
'hidetoc' => new external_value(PARAM_INT, 'How to display the SCORM structure in player',
VALUE_OPTIONAL),
'nav' => new external_value(PARAM_INT, 'Show navigation buttons', VALUE_OPTIONAL),
'navpositionleft' => new external_value(PARAM_INT, 'Navigation position left', VALUE_OPTIONAL),
'navpositiontop' => new external_value(PARAM_INT, 'Navigation position top', VALUE_OPTIONAL),
'auto' => new external_value(PARAM_BOOL, 'Auto continue?', VALUE_OPTIONAL),
'popup' => new external_value(PARAM_INT, 'Display in current or new window', VALUE_OPTIONAL),
'width' => new external_value(PARAM_INT, 'Frame width', VALUE_OPTIONAL),
'height' => new external_value(PARAM_INT, 'Frame height', VALUE_OPTIONAL),
'timeopen' => new external_value(PARAM_INT, 'Available from', VALUE_OPTIONAL),
'timeclose' => new external_value(PARAM_INT, 'Available to', VALUE_OPTIONAL),
'scormtype' => new external_value(PARAM_ALPHA, 'SCORM type', VALUE_OPTIONAL),
'reference' => new external_value(PARAM_NOTAGS, 'Reference to the package', VALUE_OPTIONAL),
'protectpackagedownloads' => new external_value(PARAM_BOOL, 'Protect package downloads?',
VALUE_OPTIONAL),
'updatefreq' => new external_value(PARAM_INT, 'Auto-update frequency for remote packages',
VALUE_OPTIONAL),
'options' => new external_value(PARAM_RAW, 'Additional options', VALUE_OPTIONAL),
'completionstatusrequired' => new external_value(PARAM_INT, 'Status passed/completed required?',
VALUE_OPTIONAL),
'completionscorerequired' => new external_value(PARAM_INT, 'Minimum score required', VALUE_OPTIONAL),
'completionstatusallscos' => new external_value(PARAM_INT, 'Require all scos to return completion status', VALUE_OPTIONAL),
'autocommit' => new external_value(PARAM_BOOL, 'Save track data automatically?', VALUE_OPTIONAL),
'timemodified' => new external_value(PARAM_INT, 'Time of last modification', VALUE_OPTIONAL),
]
), 'SCORM')
),
'options' => new external_multiple_structure(
new external_single_structure(
[
'name' => new external_value(PARAM_RAW, 'Options name'),
'value' => new external_value(PARAM_RAW, 'Option value')
]
), 'Global SCORM options', VALUE_OPTIONAL
),
'warnings' => new external_warnings(),
)
);
}
/**
* Returns description of method parameters
*
* @return external_function_parameters
* @since Moodle 3.1
*/
public static function launch_sco_parameters() {
return new external_function_parameters(
array(
'scormid' => new external_value(PARAM_INT, 'SCORM instance id'),
'scoid' => new external_value(PARAM_INT, 'SCO id (empty for launching the first SCO)', VALUE_DEFAULT, 0)
)
);
}
/**
* Trigger the course module viewed event.
*
* @param int $scormid the SCORM instance id
* @param int $scoid the SCO id
* @return array of warnings and status result
* @since Moodle 3.1
* @throws moodle_exception
*/
public static function launch_sco($scormid, $scoid = 0) {
global $DB, $CFG;
require_once($CFG->libdir . '/completionlib.php');
$params = self::validate_parameters(self::launch_sco_parameters(),
array(
'scormid' => $scormid,
'scoid' => $scoid
));
$warnings = array();
// Request and permission validation.
$scorm = $DB->get_record('scorm', array('id' => $params['scormid']), '*', MUST_EXIST);
list($course, $cm) = get_course_and_cm_from_instance($scorm, 'scorm');
$context = context_module::instance($cm->id);
self::validate_context($context);
// If the SCORM is not open this function will throw exceptions.
scorm_require_available($scorm);
if (!empty($params['scoid']) and !($sco = scorm_get_sco($params['scoid'], SCO_ONLY))) {
throw new moodle_exception('cannotfindsco', 'scorm');
}
// Mark module viewed.
$completion = new completion_info($course);
$completion->set_module_viewed($cm);
list($sco, $scolaunchurl) = scorm_get_sco_and_launch_url($scorm, $params['scoid'], $context);
// Trigger the SCO launched event.
scorm_launch_sco($scorm, $sco, $cm, $context, $scolaunchurl);
$result = array();
$result['status'] = true;
$result['warnings'] = $warnings;
return $result;
}
/**
* Returns description of method result value
*
* @return \core_external\external_description
* @since Moodle 3.1
*/
public static function launch_sco_returns() {
return new external_single_structure(
array(
'status' => new external_value(PARAM_BOOL, 'status: true if success'),
'warnings' => new external_warnings()
)
);
}
/**
* Describes the parameters for get_scorm_access_information.
*
* @return external_external_function_parameters
* @since Moodle 3.7
*/
public static function get_scorm_access_information_parameters() {
return new external_function_parameters (
array(
'scormid' => new external_value(PARAM_INT, 'scorm instance id.')
)
);
}
/**
* Return access information for a given scorm.
*
* @param int $scormid scorm instance id
* @return array of warnings and the access information
* @since Moodle 3.7
* @throws moodle_exception
*/
public static function get_scorm_access_information($scormid) {
global $DB;
$params = self::validate_parameters(self::get_scorm_access_information_parameters(), array('scormid' => $scormid));
// Request and permission validation.
$scorm = $DB->get_record('scorm', array('id' => $params['scormid']), '*', MUST_EXIST);
list($course, $cm) = get_course_and_cm_from_instance($scorm, 'scorm');
$context = context_module::instance($cm->id);
self::validate_context($context);
$result = array();
// Return all the available capabilities.
$capabilities = load_capability_def('mod_scorm');
foreach ($capabilities as $capname => $capdata) {
// Get fields like cansubmit so it is consistent with the access_information function implemented in other modules.
$field = 'can' . str_replace('mod/scorm:', '', $capname);
$result[$field] = has_capability($capname, $context);
}
$result['warnings'] = array();
return $result;
}
/**
* Describes the get_scorm_access_information return value.
*
* @return external_single_structure
* @since Moodle 3.7
*/
public static function get_scorm_access_information_returns() {
$structure = array(
'warnings' => new external_warnings()
);
$capabilities = load_capability_def('mod_scorm');
foreach ($capabilities as $capname => $capdata) {
// Get fields like cansubmit so it is consistent with the access_information function implemented in other modules.
$field = 'can' . str_replace('mod/scorm:', '', $capname);
$structure[$field] = new external_value(PARAM_BOOL, 'Whether the user has the capability ' . $capname . ' allowed.',
VALUE_OPTIONAL);
}
return new external_single_structure($structure);
}
}
+122
View File
@@ -0,0 +1,122 @@
<?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 mod_scorm\output;
use renderable;
use renderer_base;
use templatable;
use moodle_url;
use url_select;
/**
* Render HTML elements for tertiary nav for scorm.
*
* @package mod_scorm
* @copyright 2021 Sujith Haridasan <sujith@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class actionbar implements renderable, templatable {
/** @var int */
private $id;
/** @var string */
private $download;
/** @var int */
private $attemptsmode;
/**
* actionbar constructor.
*
* @param int $id The course module id.
* @param bool $download Show download button or not.
* @param int $attemptsmode attempts mode for scorm.
*/
public function __construct(int $id, bool $download = false, int $attemptsmode = 0) {
$this->id = $id;
$this->download = $download;
$this->attemptsmode = $attemptsmode;
}
/**
* Provide data for the template
*
* @param renderer_base $output renderer_base object.
* @return array data for the template
*/
public function export_for_template(renderer_base $output): array {
global $PAGE;
$basicreportlink = new moodle_url('/mod/scorm/report.php', ['id' => $this->id, 'mode' => 'basic']);
$graphreportlink = new moodle_url('/mod/scorm/report.php', ['id' => $this->id, 'mode' => 'graphs']);
$interactionreportlink = new moodle_url('/mod/scorm/report.php', ['id' => $this->id, 'mode' => 'interactions']);
$objectivesreportlink = new moodle_url('/mod/scorm/report.php', ['id' => $this->id, 'mode' => 'objectives']);
$reportmenu = [
$basicreportlink->out(false) => get_string('pluginname', 'scormreport_basic'),
$graphreportlink->out(false) => get_string('pluginname', 'scormreport_graphs'),
$interactionreportlink->out(false) => get_string('pluginname', 'scormreport_interactions'),
$objectivesreportlink->out(false) => get_string('pluginname', 'scormreport_objectives'),
];
$sesskey = sesskey();
if ($this->download) {
$mode = $PAGE->url->get_param('mode');
if ($mode === 'basic') {
$options = [
'id' => $this->id, 'mode' => $mode,
'attemptsmode' => $this->attemptsmode, 'sesskey' => $sesskey
];
} else if ($mode === 'interactions') {
$options = [
'id' => $this->id, 'mode' => $mode, 'qtext' => '0',
'resp' => '1', 'right' => '0', 'result' => '0',
'attemptsmode' => $this->attemptsmode, 'sesskey' => $sesskey
];
} else if ($mode === 'objectives') {
$options = [
'id' => $this->id, 'mode' => $mode,
'attemptsmode' => $this->attemptsmode, 'objectivescore' => '0',
'sesskey' => $sesskey
];
}
$options['download'] = 'ODS';
$downloadodslink = new moodle_url($PAGE->url, $options);
$options['download'] = 'Excel';
$downloadexcellink = new moodle_url($PAGE->url, $options);
$options['download'] = 'CSV';
$downloadtextlink = new moodle_url($PAGE->url, $options);
}
$url = new moodle_url('/mod/scorm/report.php', $PAGE->url->remove_params('attemptsmode'));
$urlselect = new url_select($reportmenu, $url->out(false), null, 'selectscormreports');
$heading = $reportmenu[$url->out(false)] ?? null;
$data = [
'heading' => $heading,
'scormreports' => $urlselect->export_for_template($output),
'candownload' => $this->download,
'downloadods' => ($this->download) ? $downloadodslink->out(false) : '',
'downloadexcel' => ($this->download) ? $downloadexcellink->out(false) : '',
'downloadtext' => ($this->download) ? $downloadtextlink->out(false) : ''
];
return $data;
}
}
@@ -0,0 +1,102 @@
<?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 mod_scorm\output;
use renderable;
use renderer_base;
use templatable;
use moodle_url;
use url_select;
/**
* Render HTML elements for reports page on tertiary nav.
*
* @package mod_scorm
* @copyright 2021 Sujith Haridasan <sujith@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class userreportsactionbar implements renderable, templatable {
/** @var int */
private $id;
/** @var int */
private $userid;
/** @var int */
private $attempt;
/** @var string */
private $reporttype;
/** @var string */
private $mode;
/** @var int */
private $scoid;
/**
* userreportsactionbar constructor
*
* @param int $id Course module id.
* @param int $userid User id.
* @param int $attempt Number of attempts.
* @param string $reporttype The report type can be either learning/interact.
* @param string $mode The mode view to set the back button.
* @param int|null $scoid The scorm id.
*/
public function __construct(int $id, int $userid, int $attempt, string $reporttype, string $mode, ?int $scoid = null) {
$this->id = $id;
$this->userid = $userid;
$this->attempt = $attempt;
$this->reporttype = $reporttype;
$this->mode = $mode;
$this->scoid = $scoid;
}
/**
* Provide data for the template
*
* @param renderer_base $output renderer_base object.
* @return array data for the template.
*/
public function export_for_template(renderer_base $output): array {
$data = [
'backurl' => (new moodle_url('/mod/scorm/report.php', ['id' => $this->id, 'mode' => $this->mode]))->out(false)
];
if (!$this->scoid) {
$learnobjects = new moodle_url('/mod/scorm/report/userreport.php',
['id' => $this->id, 'user' => $this->userid, 'attempt' => $this->attempt, 'mode' => $this->mode]);
$interactions = new moodle_url('/mod/scorm/report/userreportinteractions.php',
['id' => $this->id, 'user' => $this->userid, 'attempt' => $this->attempt, 'mode' => $this->mode]);
$reportmenu[$learnobjects->out(false)] = get_string('scoes', 'scorm');
$reportmenu[$interactions->out(false)] = get_string('interactions', 'scorm');
if ($this->reporttype === 'learning') {
$userreporturl = $learnobjects->out(false);
} else {
$userreporturl = $interactions->out(false);
}
$urlselect = new url_select($reportmenu, $userreporturl, [], 'userscormreport');
$data ['userreport'] = $urlselect->export_for_template($output);
$data ['heading'] = $reportmenu[$userreporturl] ?? null;
}
return $data;
}
}
@@ -0,0 +1,35 @@
<?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/>.
/**
* Subplugin info class.
*
* @package mod_scorm
* @copyright 2013 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_scorm\plugininfo;
use core\plugininfo\base;
defined('MOODLE_INTERNAL') || die();
class scormreport extends base {
public function is_uninstall_allowed() {
return true;
}
}
+380
View File
@@ -0,0 +1,380 @@
<?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 mod_scorm\privacy;
defined('MOODLE_INTERNAL') || die();
global $CFG;
require_once("{$CFG->dirroot}/mod/scorm/locallib.php");
use core_privacy\local\metadata\collection;
use core_privacy\local\request\approved_contextlist;
use core_privacy\local\request\approved_userlist;
use core_privacy\local\request\contextlist;
use core_privacy\local\request\helper;
use core_privacy\local\request\transform;
use core_privacy\local\request\userlist;
use core_privacy\local\request\writer;
/**
* Privacy class for requesting user data.
*
* @package mod_scorm
* @copyright 2018 Sara Arjona <sara@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class provider implements
\core_privacy\local\metadata\provider,
\core_privacy\local\request\core_userlist_provider,
\core_privacy\local\request\plugin\provider {
/**
* Return the fields which contain personal data.
*
* @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 {
$collection->add_database_table('scorm_attempt', [
'userid' => 'privacy:metadata:userid',
'attempt' => 'privacy:metadata:attempt',
], 'privacy:metadata:scorm_attempt');
$collection->add_database_table('scorm_aicc_session', [
'userid' => 'privacy:metadata:userid',
'scormmode' => 'privacy:metadata:aicc_session:scormmode',
'scormstatus' => 'privacy:metadata:aicc_session:scormstatus',
'attempt' => 'privacy:metadata:attempt',
'lessonstatus' => 'privacy:metadata:aicc_session:lessonstatus',
'sessiontime' => 'privacy:metadata:aicc_session:sessiontime',
'timecreated' => 'privacy:metadata:aicc_session:timecreated',
'timemodified' => 'privacy:metadata:timemodified',
], 'privacy:metadata:scorm_aicc_session');
$collection->add_external_location_link('aicc', [
'data' => 'privacy:metadata:aicc:data'
], 'privacy:metadata:aicc:externalpurpose');
return $collection;
}
/**
* Get the list of contexts that contain user information for the specified user.
*
* @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 {
$sql = "SELECT ctx.id
FROM {%s} ss
JOIN {modules} m
ON m.name = 'scorm'
JOIN {course_modules} cm
ON cm.instance = ss.scormid
AND cm.module = m.id
JOIN {context} ctx
ON ctx.instanceid = cm.id
AND ctx.contextlevel = :modlevel
WHERE ss.userid = :userid";
$params = ['modlevel' => CONTEXT_MODULE, 'userid' => $userid];
$contextlist = new contextlist();
$contextlist->add_from_sql(sprintf($sql, 'scorm_attempt'), $params);
$contextlist->add_from_sql(sprintf($sql, 'scorm_aicc_session'), $params);
return $contextlist;
}
/**
* Get the list of users who have data within a context.
*
* @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(userlist $userlist) {
$context = $userlist->get_context();
if (!is_a($context, \context_module::class)) {
return;
}
$sql = "SELECT ss.userid
FROM {%s} ss
JOIN {modules} m
ON m.name = 'scorm'
JOIN {course_modules} cm
ON cm.instance = ss.scormid
AND cm.module = m.id
JOIN {context} ctx
ON ctx.instanceid = cm.id
AND ctx.contextlevel = :modlevel
WHERE ctx.id = :contextid";
$params = ['modlevel' => CONTEXT_MODULE, 'contextid' => $context->id];
$userlist->add_from_sql('userid', sprintf($sql, 'scorm_attempt'), $params);
$userlist->add_from_sql('userid', sprintf($sql, 'scorm_aicc_session'), $params);
}
/**
* Export all user data for the specified user, in the specified contexts.
*
* @param approved_contextlist $contextlist The approved contexts to export information for.
*/
public static function export_user_data(approved_contextlist $contextlist) {
global $DB;
// Remove contexts different from COURSE_MODULE.
$contexts = array_reduce($contextlist->get_contexts(), function($carry, $context) {
if ($context->contextlevel == CONTEXT_MODULE) {
$carry[] = $context->id;
}
return $carry;
}, []);
if (empty($contexts)) {
return;
}
$user = $contextlist->get_user();
$userid = $user->id;
// Get SCORM data.
foreach ($contexts as $contextid) {
$context = \context::instance_by_id($contextid);
$data = helper::get_context_data($context, $user);
writer::with_context($context)->export_data([], $data);
helper::export_context_files($context, $user);
}
// Get scoes_track data.
list($insql, $inparams) = $DB->get_in_or_equal($contexts, SQL_PARAMS_NAMED);
$sql = "SELECT v.id,
a.attempt,
e.element,
v.value,
v.timemodified,
ctx.id as contextid
FROM {scorm_attempt} a
JOIN {scorm_scoes_value} v ON a.id = v.attemptid
JOIN {scorm_element} e on e.id = v.elementid
JOIN {course_modules} cm
ON cm.instance = a.scormid
JOIN {context} ctx
ON ctx.instanceid = cm.id
WHERE ctx.id $insql
AND a.userid = :userid";
$params = array_merge($inparams, ['userid' => $userid]);
$alldata = [];
$scoestracks = $DB->get_recordset_sql($sql, $params);
foreach ($scoestracks as $track) {
$alldata[$track->contextid][$track->attempt][] = (object)[
'element' => $track->element,
'value' => $track->value,
'timemodified' => transform::datetime($track->timemodified),
];
}
$scoestracks->close();
// The scoes_track data is organised in: {Course name}/{SCORM activity name}/{My attempts}/{Attempt X}/data.json
// where X is the attempt number.
array_walk($alldata, function($attemptsdata, $contextid) {
$context = \context::instance_by_id($contextid);
array_walk($attemptsdata, function($data, $attempt) use ($context) {
$subcontext = [
get_string('myattempts', 'scorm'),
get_string('attempt', 'scorm'). " $attempt"
];
writer::with_context($context)->export_data(
$subcontext,
(object)['scoestrack' => $data]
);
});
});
// Get aicc_session data.
$sql = "SELECT ss.id,
ss.scormmode,
ss.scormstatus,
ss.attempt,
ss.lessonstatus,
ss.sessiontime,
ss.timecreated,
ss.timemodified,
ctx.id as contextid
FROM {scorm_aicc_session} ss
JOIN {course_modules} cm
ON cm.instance = ss.scormid
JOIN {context} ctx
ON ctx.instanceid = cm.id
WHERE ctx.id $insql
AND ss.userid = :userid";
$params = array_merge($inparams, ['userid' => $userid]);
$alldata = [];
$aiccsessions = $DB->get_recordset_sql($sql, $params);
foreach ($aiccsessions as $aiccsession) {
$alldata[$aiccsession->contextid][] = (object)[
'scormmode' => $aiccsession->scormmode,
'scormstatus' => $aiccsession->scormstatus,
'lessonstatus' => $aiccsession->lessonstatus,
'attempt' => $aiccsession->attempt,
'sessiontime' => $aiccsession->sessiontime,
'timecreated' => transform::datetime($aiccsession->timecreated),
'timemodified' => transform::datetime($aiccsession->timemodified),
];
}
$aiccsessions->close();
// The aicc_session data is organised in: {Course name}/{SCORM activity name}/{My AICC sessions}/data.json
// In this case, the attempt hasn't been included in the json file because it can be null.
array_walk($alldata, function($data, $contextid) {
$context = \context::instance_by_id($contextid);
$subcontext = [
get_string('myaiccsessions', 'scorm')
];
writer::with_context($context)->export_data(
$subcontext,
(object)['sessions' => $data]
);
});
}
/**
* Delete all user data which matches the specified context.
*
* @param context $context A user context.
*/
public static function delete_data_for_all_users_in_context(\context $context) {
// This should not happen, but just in case.
if ($context->contextlevel != CONTEXT_MODULE) {
return;
}
// Prepare SQL to gather all IDs to delete.
$sql = "SELECT ss.id
FROM {%s} ss
JOIN {modules} m
ON m.name = 'scorm'
JOIN {course_modules} cm
ON cm.instance = ss.scormid
AND cm.module = m.id
WHERE cm.id = :cmid";
$params = ['cmid' => $context->instanceid];
static::delete_data('scorm_aicc_session', $sql, $params);
$coursemodule = get_coursemodule_from_id('scorm', $context->instanceid);
scorm_delete_tracks($coursemodule->instance);
}
/**
* Delete all user data for the specified user, in the specified contexts.
*
* @param approved_contextlist $contextlist The approved contexts and user information to delete information for.
*/
public static function delete_data_for_user(approved_contextlist $contextlist) {
global $DB;
// Remove contexts different from COURSE_MODULE.
$contextids = array_reduce($contextlist->get_contexts(), function($carry, $context) {
if ($context->contextlevel == CONTEXT_MODULE) {
$carry[] = $context->id;
}
return $carry;
}, []);
if (empty($contextids)) {
return;
}
$userid = $contextlist->get_user()->id;
// Prepare SQL to gather all completed IDs.
list($insql, $inparams) = $DB->get_in_or_equal($contextids, SQL_PARAMS_NAMED);
$sql = "SELECT ss.id
FROM {%s} ss
JOIN {modules} m
ON m.name = 'scorm'
JOIN {course_modules} cm
ON cm.instance = ss.scormid
AND cm.module = m.id
JOIN {context} ctx
ON ctx.instanceid = cm.id
WHERE ss.userid = :userid
AND ctx.id $insql";
$params = array_merge($inparams, ['userid' => $userid]);
static::delete_data('scorm_aicc_session', $sql, $params);
foreach ($contextlist->get_contexts() as $context) {
if ($context->contextlevel == CONTEXT_MODULE) {
$coursemodule = get_coursemodule_from_id('scorm', $context->instanceid);
scorm_delete_tracks($coursemodule->instance, null, $userid);
}
}
}
/**
* Delete multiple users within a single context.
*
* @param approved_userlist $userlist The approved context and user information to delete information for.
*/
public static function delete_data_for_users(approved_userlist $userlist) {
global $DB;
$context = $userlist->get_context();
if (!is_a($context, \context_module::class)) {
return;
}
// Prepare SQL to gather all completed IDs.
$userids = $userlist->get_userids();
list($insql, $inparams) = $DB->get_in_or_equal($userids, SQL_PARAMS_NAMED);
$sql = "SELECT ss.id
FROM {%s} ss
JOIN {modules} m
ON m.name = 'scorm'
JOIN {course_modules} cm
ON cm.instance = ss.scormid
AND cm.module = m.id
JOIN {context} ctx
ON ctx.instanceid = cm.id
WHERE ctx.id = :contextid
AND ss.userid $insql";
$params = array_merge($inparams, ['contextid' => $context->id]);
static::delete_data('scorm_aicc_session', $sql, $params);
$coursemodule = get_coursemodule_from_id('scorm', $context->instanceid);
foreach ($userlist->get_userids() as $userid) {
scorm_delete_tracks($coursemodule->instance, null, $userid);
}
}
/**
* Delete data from $tablename with the IDs returned by $sql query.
*
* @param string $tablename Table name where executing the SQL query.
* @param string $sql SQL query for getting the IDs of the scoestrack entries to delete.
* @param array $params SQL params for the query.
*/
protected static function delete_data(string $tablename, string $sql, array $params) {
global $DB;
$scoestracksids = $DB->get_fieldset_sql(sprintf($sql, $tablename), $params);
if (!empty($scoestracksids)) {
list($insql, $inparams) = $DB->get_in_or_equal($scoestracksids, SQL_PARAMS_NAMED);
$DB->delete_records_select($tablename, "id $insql", $inparams);
}
}
}
+113
View File
@@ -0,0 +1,113 @@
<?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/>.
/**
* @package mod_scorm
* @author Ankit Kumar Agarwal
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_scorm;
/*******************************************************************/
// Default class for Scorm plugins
//
// Doesn't do anything on it's own -- it needs to be extended.
// This class displays scorm reports. Because it is called from
// within /mod/scorm/report.php you can assume that the page header
// and footer are taken care of.
//
// This file can refer to itself as report.php to pass variables
// to itself - all these will also be globally available.
/*******************************************************************/
defined('MOODLE_INTERNAL') || die();
class report {
/**
* displays the full report
* @param stdClass $scorm full SCORM object
* @param stdClass $cm - full course_module object
* @param stdClass $course - full course object
* @param string $download - type of download being requested
*/
public function display($scorm, $cm, $course, $download) {
// This function just displays the report.
return true;
}
/**
* allows the plugin to control who can see this plugin.
* @return boolean
*/
public function canview($contextmodule) {
return true;
}
/**
* Generates a checkbox that can be added to header tables to select/deselect all quiz attempts.
*
* @return string
*/
protected function generate_master_checkbox(): string {
global $OUTPUT;
// Build the select/deselect all control.
$selectalltext = get_string('selectall', 'scorm');
$deselectalltext = get_string('selectnone', 'scorm');
$mastercheckbox = new \core\output\checkbox_toggleall('scorm-attempts', true, [
'name' => 'scorm-selectall-attempts',
'value' => 1,
'label' => $selectalltext,
'labelclasses' => 'accesshide',
'selectall' => $selectalltext,
'deselectall' => $deselectalltext,
]);
return $OUTPUT->render($mastercheckbox);
}
/**
* Generates a checkbox for a row in the attempts table.
*
* @param string $name The checkbox's name attribute.
* @param string $value The checkbox's value.
* @return string
*/
protected function generate_row_checkbox(string $name, string $value): string {
global $OUTPUT;
$checkbox = new \core\output\checkbox_toggleall('scorm-attempts', false, [
'name' => $name,
'value' => $value,
]);
return $OUTPUT->render($checkbox);
}
/**
* Generates an action button that deletes the selected attempts.
*/
protected function generate_delete_selected_button(): string {
$deleteselectedparams = array(
'type' => 'submit',
'value' => get_string('deleteselected', 'scorm'),
'class' => 'btn btn-secondary',
'data-action' => 'toggle',
'data-togglegroup' => 'scorm-attempts',
'data-toggle' => 'action',
'disabled' => true
);
return \html_writer::empty_tag('input', $deleteselectedparams);
}
}
+55
View File
@@ -0,0 +1,55 @@
<?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/>.
/**
* Search area for mod_scorm activities.
*
* @package mod_scorm
* @copyright 2015 David Monllao {@link http://www.davidmonllao.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_scorm\search;
defined('MOODLE_INTERNAL') || die();
/**
* Search area for mod_scorm activities.
*
* @package mod_scorm
* @copyright 2015 David Monllao {@link http://www.davidmonllao.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class activity extends \core_search\base_activity {
/**
* Returns true if this area uses file indexing.
*
* @return bool
*/
public function uses_file_indexing() {
return true;
}
/**
* Return the fileareas that should be indexed.
*
* @return array
*/
public function get_search_fileareas() {
return ['intro', 'content'];
}
}
+53
View File
@@ -0,0 +1,53 @@
<?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/>.
/**
* A scheduled task for scorm cron.
*
* @package mod_scorm
* @copyright 2017 Abhishek kumar <ganitgenius@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_scorm\task;
defined('MOODLE_INTERNAL') || die();
/**
* A cron_task class to be used by Tasks API.
*
* @copyright 2017 Abhishek kumar <ganitgenius@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class cron_task extends \core\task\scheduled_task {
/**
* Get a descriptive name for this task (shown to admins).
*
* @return string
*/
public function get_name() {
return get_string('crontask', 'mod_scorm');
}
/**
* Run scorm cron.
*/
public function execute() {
global $CFG;
require_once($CFG->dirroot . '/mod/scorm/lib.php');
scorm_cron_scheduled_task();
}
}
+37
View File
@@ -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 mod_scorm\task;
/**
* Adhoc task for recalculating grades.
*
* @package mod_scorm
* @copyright 2022 Dan Marsden
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class update_grades extends \core\task\adhoc_task {
/**
* Execute task.
*/
public function execute() {
global $CFG, $DB;
require_once($CFG->dirroot.'/mod/scorm/locallib.php');
$data = $this->get_custom_data();
$scorm = $DB->get_record('scorm', ['id' => $data->scormid]);
scorm_update_grades($scorm, $data->userid);
}
}