From d28eedd5363b4f081f9e66d0c9014d84792a89d7 Mon Sep 17 00:00:00 2001 From: Juan Leyva Date: Thu, 22 Oct 2015 08:03:12 +0200 Subject: [PATCH] MDL-50837 mod_scorm: Fix availability checks --- mod/scorm/lib.php | 14 ++++++++-- mod/scorm/loadSCO.php | 11 ++------ mod/scorm/locallib.php | 60 +++++++++++++++++++++++++++++++++++++++++- mod/scorm/player.php | 24 +++++++---------- mod/scorm/view.php | 18 ++++++------- 5 files changed, 90 insertions(+), 37 deletions(-) diff --git a/mod/scorm/lib.php b/mod/scorm/lib.php index 5f3ffded74a..20cfe498838 100644 --- a/mod/scorm/lib.php +++ b/mod/scorm/lib.php @@ -930,7 +930,7 @@ function scorm_get_file_info($browser, $areas, $course, $cm, $context, $filearea * @return bool false if file not found, does not return if found - just send the file */ function scorm_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload, array $options=array()) { - global $CFG; + global $CFG, $DB; if ($context->contextlevel != CONTEXT_MODULE) { return false; @@ -938,8 +938,18 @@ function scorm_pluginfile($course, $cm, $context, $filearea, $args, $forcedownlo require_login($course, true, $cm); + $canmanageactivity = has_capability('moodle/course:manageactivities', $context); $lifetime = null; + // Check SCORM availability. + if (!$canmanageactivity) { + $scorm = $DB->get_record('scorm', array('id' => $cm->instance), 'id, timeopen, timeclose', MUST_EXIST); + list($available, $warnings) = scorm_get_availability_status($scorm); + if (!$available) { + return false; + } + } + if ($filearea === 'content') { $revision = (int)array_shift($args); // Prevents caching problems - ignored here. $relativepath = implode('/', $args); @@ -947,7 +957,7 @@ function scorm_pluginfile($course, $cm, $context, $filearea, $args, $forcedownlo // TODO: add any other access restrictions here if needed! } else if ($filearea === 'package') { - if (!has_capability('moodle/course:manageactivities', $context)) { + if (!$canmanageactivity) { return false; } $revision = (int)array_shift($args); // Prevents caching problems - ignored here. diff --git a/mod/scorm/loadSCO.php b/mod/scorm/loadSCO.php index 5e04d5eae54..3641f47cc66 100644 --- a/mod/scorm/loadSCO.php +++ b/mod/scorm/loadSCO.php @@ -60,15 +60,8 @@ if (!isloggedin()) { // Prevent login page from being shown in iframe. require_login($course, false, $cm, false); // Call require_login anyway to set up globals correctly. -// Check if scorm closed. -$timenow = time(); -if ($scorm->timeclose != 0) { - if ($scorm->timeopen > $timenow) { - print_error('notopenyet', 'scorm', null, userdate($scorm->timeopen)); - } else if ($timenow > $scorm->timeclose) { - print_error('expired', 'scorm', null, userdate($scorm->timeclose)); - } -} +// Check if SCORM is available. +scorm_require_available($scorm); $context = context_module::instance($cm->id); diff --git a/mod/scorm/locallib.php b/mod/scorm/locallib.php index 17e994a78c9..5f2e7979591 100644 --- a/mod/scorm/locallib.php +++ b/mod/scorm/locallib.php @@ -2022,4 +2022,62 @@ function scorm_check_launchable_sco($scorm, $scoid) { } // Returning 0 will cause default behaviour which will find the first launchable sco in the package. return 0; -} \ No newline at end of file +} + +/** + * Check if a SCORM is available for the current user. + * + * @param stdClass $scorm SCORM record + * @param boolean $checkviewreportcap Check the scorm:viewreport cap + * @param stdClass $context Module context, required if $checkviewreportcap is set to true + * @return array status (available or not and possible warnings) + */ +function scorm_get_availability_status($scorm, $checkviewreportcap = false, $context = null) { + $open = true; + $closed = false; + $warnings = array(); + + $timenow = time(); + if (!empty($scorm->timeopen) and $scorm->timeopen > $timenow) { + $open = false; + } + if (!empty($scorm->timeclose) and $timenow > $scorm->timeclose) { + $closed = true; + } + + if (!$open or $closed) { + if ($checkviewreportcap and !empty($context) and has_capability('mod/scorm:viewreport', $context)) { + return array(true, $warnings); + } + + if (!$open) { + $warnings['notopenyet'] = userdate($scorm->timeopen); + } + if ($closed) { + $warnings['expired'] = userdate($scorm->timeclose); + } + return array(false, $warnings); + } + + // Scorm is available. + return array(true, $warnings); +} + +/** + * Requires a SCORM package to be available for the current user. + * + * @param stdClass $scorm SCORM record + * @param boolean $checkviewreportcap Check the scorm:viewreport cap + * @param stdClass $context Module context, required if $checkviewreportcap is set to true + * @throws moodle_exception + */ +function scorm_require_available($scorm, $checkviewreportcap = false, $context = null) { + + list($available, $warnings) = scorm_get_availability_status($scorm, $checkviewreportcap, $context); + + if (!$available) { + $reason = current(array_keys($warnings)); + throw new moodle_exception($reason, 'scorm', '', $warnings[$reason]); + } + +} diff --git a/mod/scorm/player.php b/mod/scorm/player.php index c18edf62410..c242312aa36 100644 --- a/mod/scorm/player.php +++ b/mod/scorm/player.php @@ -116,22 +116,16 @@ if (!$cm->visible and !has_capability('moodle/course:viewhiddenactivities', cont die; } -// Check if scorm closed. -$timenow = time(); -if ($scorm->timeclose != 0) { - if ($scorm->timeopen > $timenow) { - echo $OUTPUT->header(); - echo $OUTPUT->box(get_string("notopenyet", "scorm", userdate($scorm->timeopen)), "generalbox boxaligncenter"); - echo $OUTPUT->footer(); - die; - } else if ($timenow > $scorm->timeclose) { - echo $OUTPUT->header(); - echo $OUTPUT->box(get_string("expired", "scorm", userdate($scorm->timeclose)), "generalbox boxaligncenter"); - echo $OUTPUT->footer(); - - die; - } +// Check if SCORM available. +list($available, $warnings) = scorm_get_availability_status($scorm); +if (!$available) { + $reason = current(array_keys($warnings)); + echo $OUTPUT->header(); + echo $OUTPUT->box(get_string($reason, "scorm", $warnings[$reason]), "generalbox boxaligncenter"); + echo $OUTPUT->footer(); + die; } + // TOC processing $scorm->version = strtolower(clean_param($scorm->version, PARAM_SAFEDIR)); // Just to be safe. if (!file_exists($CFG->dirroot.'/mod/scorm/datamodels/'.$scorm->version.'lib.php')) { diff --git a/mod/scorm/view.php b/mod/scorm/view.php index ef38570ab5a..b01db962fe6 100644 --- a/mod/scorm/view.php +++ b/mod/scorm/view.php @@ -164,19 +164,17 @@ if (empty($launch) && ($scorm->displayattemptstatus == SCORM_DISPLAY_ATTEMPTSTAT } echo $OUTPUT->box(format_module_intro('scorm', $scorm, $cm->id).$attemptstatus, 'generalbox boxaligncenter boxwidthwide', 'intro'); -$scormopen = true; -$timenow = time(); -if (!empty($scorm->timeopen) && $scorm->timeopen > $timenow) { - echo $OUTPUT->box(get_string("notopenyet", "scorm", userdate($scorm->timeopen)), "generalbox boxaligncenter"); - $scormopen = false; +// Check if SCORM available. +list($available, $warnings) = scorm_get_availability_status($scorm); +if (!$available) { + $reason = current(array_keys($warnings)); + echo $OUTPUT->box(get_string($reason, "scorm", $warnings[$reason]), "generalbox boxaligncenter"); } -if (!empty($scorm->timeclose) && $timenow > $scorm->timeclose) { - echo $OUTPUT->box(get_string("expired", "scorm", userdate($scorm->timeclose)), "generalbox boxaligncenter"); - $scormopen = false; -} -if ($scormopen && empty($launch)) { + +if ($available && empty($launch)) { scorm_view_display($USER, $scorm, 'view.php?id='.$cm->id, $cm); } + if (!empty($forcejs)) { echo $OUTPUT->box(get_string("forcejavascriptmessage", "scorm"), "generalbox boxaligncenter forcejavascriptmessage"); }