Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

MDL-43541 SCORM: set first launchable sco correctly.

  • Loading branch information...
commit 9f3a4cbbcfd0688ec61485d36e5c26234c689dd5 1 parent 27ebbdd
@danmarsden danmarsden authored
View
29 mod/scorm/datamodels/aicclib.php
@@ -14,6 +14,14 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
+/**
+ * functions used by AICC packages.
+ *
+ * @package mod_scorm
+ * @copyright 1999 onwards Roberto Pinna
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
function scorm_add_time($a, $b) {
$aes = explode(':', $a);
$bes = explode(':', $b);
@@ -106,8 +114,14 @@ function scorm_forge_cols_regexp($columns, $remodule='(".*")?,') {
return $regexp;
}
+/**
+ * Sets up AICC packages
+ * Called whenever package changes
+ * @param object $scorm instance - fields are updated and changes saved into database
-function scorm_parse_aicc($scorm) {
+ * @return bool
+ */
+function scorm_parse_aicc(&$scorm) {
global $DB;
if ($scorm->scormtype == SCORM_TYPE_AICCURL) {
@@ -359,9 +373,18 @@ function scorm_parse_aicc($scorm) {
}
}
- $scorm->version = 'AICC';
+ // Find first launchable object.
+ $sqlselect = 'scorm = ? AND '.$DB->sql_isnotempty('scorm_scoes', 'launch', false, true);
+ // We use get_records here as we need to pass a limit in the query that works cross db.
+ $scoes = $DB->get_records_select('scorm_scoes', $sqlselect, array($scorm->id), 'sortorder', 'id', 0, 1);
+ if (!empty($scoes)) {
+ $sco = reset($scoes); // We only care about the first record - the above query only returns one.
+ $scorm->launch = $sco->id;
+ } else {
+ $scorm->launch = $launch;
+ }
- $scorm->launch = $launch;
+ $scorm->version = 'AICC';
return true;
}
View
59 mod/scorm/datamodels/scormlib.php
@@ -14,6 +14,14 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
+/**
+ * functions used by SCORM 1.2/2004 packages.
+ *
+ * @package mod_scorm
+ * @copyright 1999 onwards Roberto Pinna
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
function scorm_get_resources($blocks) {
$resources = array();
foreach ($blocks as $block) {
@@ -503,7 +511,14 @@ function scorm_get_manifest($blocks, $scoes) {
return $scoes;
}
-function scorm_parse_scorm($scorm, $manifest) {
+/**
+ * Sets up SCORM 1.2/2004 packages using the manifest file.
+ * Called whenever SCORM changes
+ * @param object $scorm instance - fields are updated and changes saved into database
+ * @param stored_file|string $manifest - path to manifest file or stored_file.
+ * @return bool
+ */
+function scorm_parse_scorm(&$scorm, $manifest) {
global $CFG, $DB;
// load manifest into string
@@ -514,7 +529,8 @@ function scorm_parse_scorm($scorm, $manifest) {
$xmltext = download_file_content($manifest);
}
- $launch = 0;
+ $defaultorgid = 0;
+ $firstinorg = 0;
$pattern = '/&(?!\w{2,6};)/';
$replacement = '&amp;';
@@ -525,6 +541,7 @@ function scorm_parse_scorm($scorm, $manifest) {
$scoes = new stdClass();
$scoes->version = '';
$scoes = scorm_get_manifest($manifests, $scoes);
+ $newscoes = array();
$sortorder = 0;
if (count($scoes->elements) > 0) {
$olditems = $DB->get_records('scorm_scoes', array('scorm'=>$scorm->id));
@@ -547,6 +564,10 @@ function scorm_parse_scorm($scorm, $manifest) {
}
}
+ if (!empty($defaultorgid) && empty($firstinorg) && $newitem->parent == $scoes->defaultorg) {
+ $firstinorg = $sortorder;
+ }
+
if (!empty($olditems) && ($olditemid = scorm_array_search('identifier', $newitem->identifier, $olditems))) {
$newitem->id = $olditemid;
// Update the Sco sortorder but keep id so that user tracks are kept against the same ids.
@@ -567,6 +588,7 @@ function scorm_parse_scorm($scorm, $manifest) {
// Insert the new SCO, and retain the link between the old and new for later adjustment
$id = $DB->insert_record('scorm_scoes', $newitem);
}
+ $newscoes[$id] = $newitem; // Save this sco in memory so we can use it later.
if ($optionaldatas = scorm_optionals_data($item, $standarddatas)) {
$data = new stdClass();
@@ -651,8 +673,8 @@ function scorm_parse_scorm($scorm, $manifest) {
}
}
}
- if (($launch == 0) && ((empty($scoes->defaultorg)) || ($scoes->defaultorg == $identifier))) {
- $launch = $id;
+ if (empty($defaultorgid) && ((empty($scoes->defaultorg)) || ($scoes->defaultorg == $identifier))) {
+ $defaultorgid = $id;
}
}
}
@@ -673,11 +695,34 @@ function scorm_parse_scorm($scorm, $manifest) {
if (empty($scoes->version)) {
$scoes->version = 'SCORM_1.2';
}
- $DB->set_field('scorm', 'version', $scoes->version, array('id'=>$scorm->id));
+ $DB->set_field('scorm', 'version', $scoes->version, array('id' => $scorm->id));
$scorm->version = $scoes->version;
}
-
- $scorm->launch = $launch;
+ $scorm->launch = 0;
+ // Check launch sco is valid.
+ if (!empty($defaultorgid) && isset($newscoes[$defaultorgid]) && !empty($newscoes[$defaultorgid]->launch)) {
+ // Launch param is valid - do nothing.
+ $scorm->launch = $defaultorgid;
+ } else if (!empty($defaultorgid) && isset($newscoes[$defaultorgid]) && empty($newscoes[$defaultorgid]->launch)) {
+ // The launch is probably the default org so we need to find the first launchable item inside this org.
+ $sqlselect = 'scorm = ? AND sortorder > ? AND '.$DB->sql_isnotempty('scorm_scoes', 'launch', false, true);
+ // We use get_records here as we need to pass a limit in the query that works cross db.
+ $scoes = $DB->get_records_select('scorm_scoes', $sqlselect, array($scorm->id, $firstinorg), 'sortorder', 'id', 0, 1);
+ if (!empty($scoes)) {
+ $sco = reset($scoes); // We only care about the first record - the above query only returns one.
+ $scorm->launch = $sco->id;
+ }
+ }
+ if (empty($scorm->launch)) {
+ // No valid Launch is specified - find the first launchable sco instead.
+ $sqlselect = 'scorm = ? AND '.$DB->sql_isnotempty('scorm_scoes', 'launch', false, true);
+ // We use get_records here as we need to pass a limit in the query that works cross db.
+ $scoes = $DB->get_records_select('scorm_scoes', $sqlselect, array($scorm->id), 'sortorder', 'id', 0, 1);
+ if (!empty($scoes)) {
+ $sco = reset($scoes); // We only care about the first record - the above query only returns one.
+ $scorm->launch = $sco->id;
+ }
+ }
return true;
}
View
52 mod/scorm/db/upgrade.php
@@ -17,8 +17,7 @@
/**
* Upgrade script for the scorm module.
*
- * @package mod
- * @subpackage scorm
+ * @package mod_scorm
* @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
@@ -203,6 +202,55 @@ function xmldb_scorm_upgrade($oldversion) {
upgrade_mod_savepoint(true, 2013110501, 'scorm');
}
+ if ($oldversion < 2013110502) {
+ // Fix invalid $scorm->launch records that launch an org sco instead of a real sco.
+ $sql = "SELECT s.*, c.identifier
+ FROM {scorm} s
+ LEFT JOIN {scorm_scoes} c ON s.launch = c.id
+ WHERE ".$DB->sql_isempty('scorm_scoes', 'c.launch', false, true);
+ $scorms = $DB->get_recordset_sql($sql);
+ foreach ($scorms as $scorm) {
+ upgrade_set_timeout(60); // Increase execution time just in case. (60 sec is minimum but prob excessive here).
+ $originallaunch = $scorm->launch;
+ // Find the first sco using the current identifier as it's parent
+ // we use get records here as we need to pass a limit in the query that works cross db.
+ $firstsco = $DB->get_records('scorm_scoes',
+ array('scorm' => $scorm->id, 'parent' => $scorm->identifier), 'sortorder', '*', 0, 1);
+ if (!empty($firstsco)) {
+ $firstsco = reset($firstsco);
+ }
+ if (!empty($firstsco->launch)) {
+ // Usual behavior - this is a valid sco with a launch param so use it.
+ $scorm->launch = $firstsco->id;
+ } else {
+ // The firstsco found is not launchable - find the first launchable sco after this sco.
+ $sqlselect = 'scorm = ? AND sortorder > ? AND '.$DB->sql_isnotempty('scorm_scoes', 'launch', false, true);
+ // We use get_records here as we need to pass a limit in the query that works cross db.
+ $scoes = $DB->get_records_select('scorm_scoes', $sqlselect,
+ array($scorm->id, $firstsco->sortorder), 'sortorder', 'id', 0, 1);
+ if (!empty($scoes)) {
+ $sco = reset($scoes); // We only care about the first record - the above query only returns one.
+ $scorm->launch = $sco->id;
+ } else {
+ // This is an invalid package - it has a default org that doesn't contain a launchable sco.
+ // Check for any valid sco with a launch param.
+ $sqlselect = 'scorm = ? AND '.$DB->sql_isnotempty('scorm_scoes', 'launch', false, true);
+ // We use get_records here as we need to pass a limit in the query that works cross db.
+ $scoes = $DB->get_records_select('scorm_scoes', $sqlselect, array($scorm->id), 'sortorder', 'id', 0, 1);
+ if (!empty($scoes)) {
+ $sco = reset($scoes); // We only care about the first record - the above query only returns one.
+ $scorm->launch = $sco->id;
+ }
+ }
+ }
+ if ($originallaunch != $scorm->launch) {
+ $DB->update_record('scorm', $scorm);
+ }
+ }
+ $scorms->close();
+
+ upgrade_mod_savepoint(true, 2013110502, 'scorm');
+ }
return true;
}
View
10 mod/scorm/locallib.php
@@ -14,6 +14,14 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
+/**
+ * Library of internal classes and functions for module SCORM
+ *
+ * @package mod_scorm
+ * @copyright 1999 onwards Roberto Pinna
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
require_once("$CFG->dirroot/mod/scorm/lib.php");
require_once("$CFG->libdir/filelib.php");
@@ -897,7 +905,7 @@ function scorm_view_display ($user, $scorm, $action, $cm) {
}
?>
<br />
- <input type="hidden" name="scoid"/>
+ <input type="hidden" name="scoid" value="<?php echo $scorm->launch ?>" />
<input type="hidden" name="cm" value="<?php echo $cm->id ?>"/>
<input type="hidden" name="currentorg" value="<?php echo $orgidentifier ?>" />
<input type="submit" value="<?php print_string('enter', 'scorm') ?>" />
View
5 mod/scorm/version.php
@@ -17,15 +17,14 @@
/**
* scorm version information.
*
- * @package mod
- * @subpackage scorm
+ * @package mod_scorm
* @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
-$module->version = 2013110501; // The current module version (Date: YYYYMMDDXX)
+$module->version = 2013110502; // The current module version (Date: YYYYMMDDXX)
$module->requires = 2013110500; // Requires this Moodle version
$module->component = 'mod_scorm'; // Full name of the plugin (used for diagnostics)
$module->cron = 300;
Please sign in to comment.
Something went wrong with that request. Please try again.