Ir a la última revisión | Autoría | Comparar con el anterior | Ultima modificación | Ver Log |
<?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.valueFROM {scorm_scoes_value} vJOIN {scorm_attempt} a ON a.id = v.attemptidJOIN {scorm_element} e ON e.id = v.elementidWHERE 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',];}}