From b33e466550a6619601d612272d6f18f4c11e60f0 Mon Sep 17 00:00:00 2001 From: Dan Marsden Date: Tue, 27 Aug 2013 12:55:10 +1200 Subject: [PATCH] MDL-41434 SCORM: add new sortorder field to allow better ordering of scos --- .../backup/moodle2/backup_scorm_stepslib.php | 4 +-- mod/scorm/datamodels/aicclib.php | 25 ++++++------- mod/scorm/datamodels/scormlib.php | 36 ++++++++++++++----- mod/scorm/db/install.xml | 3 +- mod/scorm/db/subplugins.php | 0 mod/scorm/db/upgrade.php | 15 ++++++++ mod/scorm/lib.php | 4 +-- mod/scorm/loadSCO.php | 4 +-- mod/scorm/locallib.php | 13 ++++--- mod/scorm/report/basic/report.php | 2 +- mod/scorm/report/graphs/report.php | 2 +- mod/scorm/report/interactions/report.php | 2 +- mod/scorm/report/objectives/report.php | 2 +- mod/scorm/report/userreport.php | 2 +- mod/scorm/version.php | 2 +- 15 files changed, 75 insertions(+), 41 deletions(-) mode change 100644 => 100755 mod/scorm/db/subplugins.php diff --git a/mod/scorm/backup/moodle2/backup_scorm_stepslib.php b/mod/scorm/backup/moodle2/backup_scorm_stepslib.php index 6c81396ee1a..11712d028f1 100644 --- a/mod/scorm/backup/moodle2/backup_scorm_stepslib.php +++ b/mod/scorm/backup/moodle2/backup_scorm_stepslib.php @@ -51,7 +51,7 @@ class backup_scorm_activity_structure_step extends backup_activity_structure_ste $sco = new backup_nested_element('sco', array('id'), array( 'manifest', 'organization', 'parent', 'identifier', - 'launch', 'scormtype', 'title')); + 'launch', 'scormtype', 'title', 'sortorder')); $scodatas = new backup_nested_element('sco_datas'); @@ -128,7 +128,7 @@ class backup_scorm_activity_structure_step extends backup_activity_structure_ste $scorm->set_source_table('scorm', array('id' => backup::VAR_ACTIVITYID)); // Order is important for several SCORM calls (especially scorm_scoes) in the following calls to set_source_table - $sco->set_source_table('scorm_scoes', array('scorm' => backup::VAR_PARENTID), 'id ASC'); + $sco->set_source_table('scorm_scoes', array('scorm' => backup::VAR_PARENTID), 'sortorder, id'); $scodata->set_source_table('scorm_scoes_data', array('scoid' => backup::VAR_PARENTID), 'id ASC'); $seqrulecond->set_source_table('scorm_seq_ruleconds', array('scoid' => backup::VAR_PARENTID), 'id ASC'); $seqrulecondsdata->set_source_table('scorm_seq_rulecond', array('ruleconditionsid' => backup::VAR_PARENTID), 'id ASC'); diff --git a/mod/scorm/datamodels/aicclib.php b/mod/scorm/datamodels/aicclib.php index c33fd3f3796..46754946775 100644 --- a/mod/scorm/datamodels/aicclib.php +++ b/mod/scorm/datamodels/aicclib.php @@ -248,10 +248,11 @@ function scorm_parse_aicc($scorm) { } $oldscoes = $DB->get_records('scorm_scoes', array('scorm'=>$scorm->id)); - + $sortorder = 0; $launch = 0; if (isset($courses)) { foreach ($courses as $course) { + $sortorder++; $sco = new stdClass(); $sco->identifier = $course->id; $sco->scorm = $scorm->id; @@ -260,12 +261,13 @@ function scorm_parse_aicc($scorm) { $sco->parent = '/'; $sco->launch = ''; $sco->scormtype = ''; + $sco->sortorder = $sortorder; if ($ss = $DB->get_record('scorm_scoes', array('scorm'=>$scorm->id, 'identifier'=>$sco->identifier))) { $id = $ss->id; $sco->id = $id; - $DB->update_record('scorm_scoes',$sco); + $DB->update_record('scorm_scoes', $sco); unset($oldscoes[$id]); } else { $id = $DB->insert_record('scorm_scoes', $sco); @@ -421,17 +423,17 @@ function scorm_aicc_confirm_hacp_session($hacpsession) { */ function scorm_aicc_generate_simple_sco($scorm) { global $DB; - // find the old one - $scos = $DB->get_records('scorm_scoes', array('scorm'=>$scorm->id)); + // Find the oldest one. + $scos = $DB->get_records('scorm_scoes', array('scorm' => $scorm->id), 'id'); if (!empty($scos)) { $sco = array_shift($scos); } else { - $sco = new object(); + $sco = new stdClass(); } - // get rid of old ones - foreach($scos as $oldsco) { - $DB->delete_records('scorm_scoes', array('id'=>$oldsco->id)); - $DB->delete_records('scorm_scoes_track', array('scoid'=>$oldsco->id)); + // Get rid of old ones. + foreach ($scos as $oldsco) { + $DB->delete_records('scorm_scoes', array('id' => $oldsco->id)); + $DB->delete_records('scorm_scoes_track', array('scoid' => $oldsco->id)); } $sco->identifier = 'A1'; @@ -439,11 +441,10 @@ function scorm_aicc_generate_simple_sco($scorm) { $sco->organization = ''; $sco->title = $scorm->name; $sco->parent = '/'; - // add the HACP signal to the activity launcher + // Add the HACP signal to the activity launcher. if (preg_match('/\?/', $scorm->reference)) { $sco->launch = $scorm->reference.'&CMI=HACP'; - } - else { + } else { $sco->launch = $scorm->reference.'?CMI=HACP'; } $sco->scormtype = 'sco'; diff --git a/mod/scorm/datamodels/scormlib.php b/mod/scorm/datamodels/scormlib.php index 6fa4f5d5775..91ef6d88b2e 100644 --- a/mod/scorm/datamodels/scormlib.php +++ b/mod/scorm/datamodels/scormlib.php @@ -525,27 +525,47 @@ function scorm_parse_scorm($scorm, $manifest) { $scoes = new stdClass(); $scoes->version = ''; $scoes = scorm_get_manifest($manifests, $scoes); + $sortorder = 0; if (count($scoes->elements) > 0) { $olditems = $DB->get_records('scorm_scoes', array('scorm'=>$scorm->id)); foreach ($scoes->elements as $manifest => $organizations) { foreach ($organizations as $organization => $items) { foreach ($items as $identifier => $item) { + $sortorder++; // This new db mngt will support all SCORM future extensions $newitem = new stdClass(); $newitem->scorm = $scorm->id; $newitem->manifest = $manifest; $newitem->organization = $organization; + $newitem->sortorder = $sortorder; $standarddatas = array('parent', 'identifier', 'launch', 'scormtype', 'title'); foreach ($standarddatas as $standarddata) { if (isset($item->$standarddata)) { $newitem->$standarddata = $item->$standarddata; + } else { + $newitem->$standarddata = ''; } } - // Insert the new SCO, and retain the link between the old and new for later adjustment - $id = $DB->insert_record('scorm_scoes', $newitem); if (!empty($olditems) && ($olditemid = scorm_array_search('identifier', $newitem->identifier, $olditems))) { - $olditems[$olditemid]->newid = $id; + $newitem->id = $olditemid; + // Update the Sco sortorder but keep id so that user tracks are kept against the same ids. + $DB->update_record('scorm_scoes', $newitem); + $id = $olditemid; + // Remove all old data so we don't duplicate it. + $DB->delete_records('scorm_scoes_data', array('scoid'=>$olditemid)); + $DB->delete_records('scorm_seq_objective', array('scoid'=>$olditemid)); + $DB->delete_records('scorm_seq_mapinfo', array('scoid'=>$olditemid)); + $DB->delete_records('scorm_seq_ruleconds', array('scoid'=>$olditemid)); + $DB->delete_records('scorm_seq_rulecond', array('scoid'=>$olditemid)); + $DB->delete_records('scorm_seq_rolluprule', array('scoid'=>$olditemid)); + $DB->delete_records('scorm_seq_rolluprulecond', array('scoid'=>$olditemid)); + + // Now remove this SCO from the olditems object as we have dealt with it. + unset($olditems[$olditemid]); + } else { + // Insert the new SCO, and retain the link between the old and new for later adjustment + $id = $DB->insert_record('scorm_scoes', $newitem); } if ($optionaldatas = scorm_optionals_data($item, $standarddatas)) { @@ -641,9 +661,6 @@ function scorm_parse_scorm($scorm, $manifest) { foreach ($olditems as $olditem) { $DB->delete_records('scorm_scoes', array('id'=>$olditem->id)); $DB->delete_records('scorm_scoes_data', array('scoid'=>$olditem->id)); - if (isset($olditem->newid)) { - $DB->set_field('scorm_scoes_track', 'scoid', $olditem->newid, array('scoid' => $olditem->id)); - } $DB->delete_records('scorm_scoes_track', array('scoid'=>$olditem->id)); $DB->delete_records('scorm_seq_objective', array('scoid'=>$olditem->id)); $DB->delete_records('scorm_seq_mapinfo', array('scoid'=>$olditem->id)); @@ -701,7 +718,8 @@ function scorm_get_parent($sco) { function scorm_get_children($sco) { global $DB; - if ($children = $DB->get_records('scorm_scoes', array('scorm'=>$sco->scorm, 'parent'=>$sco->identifier))) {//originally this said parent instead of childrean + $children = $DB->get_records('scorm_scoes', array('scorm' => $sco->scorm, 'parent' => $sco->identifier), 'sortorder, id'); + if (!empty($children)) { return $children; } return null; @@ -710,7 +728,7 @@ function scorm_get_children($sco) { function scorm_get_available_children($sco) { global $DB; - $res = $DB->get_records('scorm_scoes', array('scorm' => $sco->scorm, 'parent' => $sco->identifier)); + $res = $DB->get_records('scorm_scoes', array('scorm' => $sco->scorm, 'parent' => $sco->identifier), 'sortorder, id'); if (!$res || $res == null) { return false; } else { @@ -738,7 +756,7 @@ function scorm_get_available_descendent($descend = array(), $sco) { function scorm_get_siblings($sco) { global $DB; - if ($siblings = $DB->get_records('scorm_scoes', array('scorm'=>$sco->scorm, 'parent'=>$sco->parent))) { + if ($siblings = $DB->get_records('scorm_scoes', array('scorm'=>$sco->scorm, 'parent'=>$sco->parent), 'sortorder, id')) { unset($siblings[$sco->id]); if (!empty($siblings)) { return $siblings; diff --git a/mod/scorm/db/install.xml b/mod/scorm/db/install.xml index 794bbe80912..d69f1ea6a00 100644 --- a/mod/scorm/db/install.xml +++ b/mod/scorm/db/install.xml @@ -1,5 +1,5 @@ - @@ -61,6 +61,7 @@ + diff --git a/mod/scorm/db/subplugins.php b/mod/scorm/db/subplugins.php old mode 100644 new mode 100755 diff --git a/mod/scorm/db/upgrade.php b/mod/scorm/db/upgrade.php index d6c1cff6afb..870a9886f12 100644 --- a/mod/scorm/db/upgrade.php +++ b/mod/scorm/db/upgrade.php @@ -114,6 +114,21 @@ function xmldb_scorm_upgrade($oldversion) { upgrade_mod_savepoint(true, 2013081302, 'scorm'); } + if ($oldversion < 2013081303) { + + // Define field sortorder to be added to scorm_scoes. + $table = new xmldb_table('scorm_scoes'); + $field = new xmldb_field('sortorder', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'title'); + + // Conditionally launch add field sortorder. + if (!$dbman->field_exists($table, $field)) { + $dbman->add_field($table, $field); + } + + // Scorm savepoint reached. + upgrade_mod_savepoint(true, 2013081303, 'scorm'); + } + return true; } diff --git a/mod/scorm/lib.php b/mod/scorm/lib.php index 8f487a26b0c..c09508a069b 100644 --- a/mod/scorm/lib.php +++ b/mod/scorm/lib.php @@ -388,7 +388,7 @@ function scorm_user_complete($course, $user, $mod, $scorm) { if ($orgs = $DB->get_records_select('scorm_scoes', 'scorm = ? AND '. $DB->sql_isempty('scorm_scoes', 'launch', false, true).' AND '. $DB->sql_isempty('scorm_scoes', 'organization', false, false), - array($scorm->id), 'id', 'id,identifier,title')) { + array($scorm->id), 'sortorder, id', 'id, identifier, title')) { if (count($orgs) <= 1) { unset($orgs); $orgs = array(); @@ -407,7 +407,7 @@ function scorm_user_complete($course, $user, $mod, $scorm) { } $report .= "
    "; $conditions['scorm'] = $scorm->id; - if ($scoes = $DB->get_records('scorm_scoes', $conditions, "id ASC")) { + if ($scoes = $DB->get_records('scorm_scoes', $conditions, "sortorder, id")) { // drop keys so that we can access array sequentially $scoes = array_values($scoes); $level=0; diff --git a/mod/scorm/loadSCO.php b/mod/scorm/loadSCO.php index 65611e6a12c..8b39f3e0fdf 100644 --- a/mod/scorm/loadSCO.php +++ b/mod/scorm/loadSCO.php @@ -83,7 +83,7 @@ if (!empty($scoid)) { 'scorm_scoes', 'scorm = ? AND '.$DB->sql_isnotempty('scorm_scoes', 'launch', false, true).' AND id > ?', array($scorm->id, $sco->id), - 'id ASC')) { + 'sortorder, id')) { $sco = current($scoes); } } @@ -97,7 +97,7 @@ if (!isset($sco)) { 'scorm_scoes', 'scorm = ? AND '.$DB->sql_isnotempty('scorm_scoes', 'launch', false, true), array($scorm->id), - 'id ASC' + 'sortorder, id' ); $sco = current($scoes); } diff --git a/mod/scorm/locallib.php b/mod/scorm/locallib.php index 8287314c9ca..edb73624090 100644 --- a/mod/scorm/locallib.php +++ b/mod/scorm/locallib.php @@ -367,13 +367,12 @@ function scorm_get_sco($id, $what=SCO_ALL) { function scorm_get_scoes($id, $organisation=false) { global $DB; - $organizationsql = ''; $queryarray = array('scorm'=>$id); if (!empty($organisation)) { $queryarray['organization'] = $organisation; } - if ($scoes = $DB->get_records('scorm_scoes', $queryarray, 'id ASC')) { - // drop keys so that it is a simple array as expected + if ($scoes = $DB->get_records('scorm_scoes', $queryarray, 'sortorder, id')) { + // Drop keys so that it is a simple array as expected. $scoes = array_values($scoes); foreach ($scoes as $sco) { if ($scodatas = $DB->get_records('scorm_scoes_data', array('scoid'=>$sco->id))) { @@ -627,7 +626,7 @@ function scorm_grade_user_attempt($scorm, $userid, $attempt=1) { $attemptscore->sum = 0; $attemptscore->lastmodify = 0; - if (!$scoes = $DB->get_records('scorm_scoes', array('scorm'=>$scorm->id))) { + if (!$scoes = $DB->get_records('scorm_scoes', array('scorm' => $scorm->id), 'sortorder, id')) { return null; } @@ -814,7 +813,7 @@ function scorm_view_display ($user, $scorm, $action, $cm) { if ($orgs = $DB->get_records_select_menu('scorm_scoes', 'scorm = ? AND '. $DB->sql_isempty('scorm_scoes', 'launch', false, true).' AND '. $DB->sql_isempty('scorm_scoes', 'organization', false, false), - array($scorm->id), 'id', 'id,title')) { + array($scorm->id), 'sortorder, id', 'id,title')) { if (count($orgs) > 1) { $select = new single_select(new moodle_url($action), 'organization', $orgs, $organization, null); $select->label = get_string('organizations', 'scorm'); @@ -900,7 +899,8 @@ function scorm_simple_play($scorm, $user, $context, $cmid) { if ($scorm->scormtype != SCORM_TYPE_LOCAL && $scorm->updatefreq == SCORM_UPDATE_EVERYTIME) { scorm_parse($scorm, false); } - $scoes = $DB->get_records_select('scorm_scoes', 'scorm = ? AND '.$DB->sql_isnotempty('scorm_scoes', 'launch', false, true), array($scorm->id), 'id', 'id'); + $scoes = $DB->get_records_select('scorm_scoes', 'scorm = ? AND '. + $DB->sql_isnotempty('scorm_scoes', 'launch', false, true), array($scorm->id), 'sortorder, id', 'id'); if ($scoes) { $orgidentifier = ''; @@ -1461,7 +1461,6 @@ function scorm_get_toc_get_parent_child(&$result) { $final = array(); $level = 0; $prevparent = '/'; - ksort($result); foreach ($result as $sco) { if ($sco->parent == '/') { diff --git a/mod/scorm/report/basic/report.php b/mod/scorm/report/basic/report.php index c4bb765b230..5c55e9c7032 100644 --- a/mod/scorm/report/basic/report.php +++ b/mod/scorm/report/basic/report.php @@ -137,7 +137,7 @@ class scorm_basic_report extends scorm_default_report { $headers[]= get_string('last', 'scorm'); $columns[]= 'score'; $headers[]= get_string('score', 'scorm'); - if ($detailedrep && $scoes = $DB->get_records('scorm_scoes', array("scorm"=>$scorm->id), 'id')) { + if ($detailedrep && $scoes = $DB->get_records('scorm_scoes', array("scorm"=>$scorm->id), 'sortorder, id')) { foreach ($scoes as $sco) { if ($sco->launch!='') { $columns[]= 'scograde'.$sco->id; diff --git a/mod/scorm/report/graphs/report.php b/mod/scorm/report/graphs/report.php index d9d532b103c..58e426f4c54 100644 --- a/mod/scorm/report/graphs/report.php +++ b/mod/scorm/report/graphs/report.php @@ -46,7 +46,7 @@ class scorm_graphs_report extends scorm_default_report { groups_print_activity_menu($cm, new moodle_url($PAGE->url)); } - if ($scoes = $DB->get_records('scorm_scoes', array("scorm"=>$scorm->id), 'id')) { + if ($scoes = $DB->get_records('scorm_scoes', array("scorm"=>$scorm->id), 'sortorder, id')) { foreach ($scoes as $sco) { if ($sco->launch != '') { $imageurl = new moodle_url('/mod/scorm/report/graphs/graph.php', diff --git a/mod/scorm/report/interactions/report.php b/mod/scorm/report/interactions/report.php index 2550a9f0bd4..8a2881c8d4e 100644 --- a/mod/scorm/report/interactions/report.php +++ b/mod/scorm/report/interactions/report.php @@ -148,7 +148,7 @@ class scorm_interactions_report extends scorm_default_report { $headers[] = get_string('last', 'scorm'); $columns[] = 'score'; $headers[] = get_string('score', 'scorm'); - $scoes = $DB->get_records('scorm_scoes', array("scorm"=>$scorm->id), 'id'); + $scoes = $DB->get_records('scorm_scoes', array("scorm" => $scorm->id), 'sortorder, id'); foreach ($scoes as $sco) { if ($sco->launch != '') { $columns[] = 'scograde'.$sco->id; diff --git a/mod/scorm/report/objectives/report.php b/mod/scorm/report/objectives/report.php index d5a2000367c..3593961015e 100644 --- a/mod/scorm/report/objectives/report.php +++ b/mod/scorm/report/objectives/report.php @@ -148,7 +148,7 @@ class scorm_objectives_report extends scorm_default_report { $headers[] = get_string('last', 'scorm'); $columns[] = 'score'; $headers[] = get_string('score', 'scorm'); - $scoes = $DB->get_records('scorm_scoes', array("scorm"=>$scorm->id), 'id'); + $scoes = $DB->get_records('scorm_scoes', array("scorm" => $scorm->id), 'sortorder, id'); foreach ($scoes as $sco) { if ($sco->launch != '') { $columns[] = 'scograde'.$sco->id; diff --git a/mod/scorm/report/userreport.php b/mod/scorm/report/userreport.php index d4a2ff4a462..f1e3ee144ae 100644 --- a/mod/scorm/report/userreport.php +++ b/mod/scorm/report/userreport.php @@ -72,7 +72,7 @@ require($CFG->dirroot . '/mod/scorm/report/userreporttabs.php'); $output = $PAGE->get_renderer('mod_scorm'); echo $output->view_user_heading($user, $course, $PAGE->url, $attempt, $attemptids); -if ($scoes = $DB->get_records_select('scorm_scoes', "scorm = ? ORDER BY id", array($scorm->id))) { +if ($scoes = $DB->get_records('scorm_scoes', array('scorm' => $scorm->id), 'sortorder, id')) { // Print general score data. $table = new html_table(); $table->head = array( diff --git a/mod/scorm/version.php b/mod/scorm/version.php index 9f2d6c1b63d..56084add8c6 100644 --- a/mod/scorm/version.php +++ b/mod/scorm/version.php @@ -25,7 +25,7 @@ defined('MOODLE_INTERNAL') || die(); -$module->version = 2013081302; // The current module version (Date: YYYYMMDDXX) +$module->version = 2013081303; // The current module version (Date: YYYYMMDDXX) $module->requires = 2013050100; // Requires this Moodle version $module->component = 'mod_scorm'; // Full name of the plugin (used for diagnostics) $module->cron = 300;