MDL-41434 SCORM: add new sortorder field to allow better ordering of scos
authorDan Marsden <dan@danmarsden.com>
Tue, 27 Aug 2013 00:55:10 +0000 (12:55 +1200)
committerDan Marsden <dan@danmarsden.com>
Sun, 15 Sep 2013 22:11:16 +0000 (10:11 +1200)
15 files changed:
mod/scorm/backup/moodle2/backup_scorm_stepslib.php
mod/scorm/datamodels/aicclib.php
mod/scorm/datamodels/scormlib.php
mod/scorm/db/install.xml
mod/scorm/db/subplugins.php [changed mode: 0644->0755]
mod/scorm/db/upgrade.php
mod/scorm/lib.php
mod/scorm/loadSCO.php
mod/scorm/locallib.php
mod/scorm/report/basic/report.php
mod/scorm/report/graphs/report.php
mod/scorm/report/interactions/report.php
mod/scorm/report/objectives/report.php
mod/scorm/report/userreport.php
mod/scorm/version.php

index 6c81396..11712d0 100644 (file)
@@ -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');
index c33fd3f..4675494 100644 (file)
@@ -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';
index 6fa4f5d..91ef6d8 100644 (file)
@@ -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;
index 794bbe8..d69f1ea 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8" ?>
-<XMLDB PATH="mod/scorm/db" VERSION="20120326" COMMENT="XMLDB file for Moodle mod/scorm"
+<XMLDB PATH="mod/scorm/db" VERSION="20130826" COMMENT="XMLDB file for Moodle mod/scorm"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:noNamespaceSchemaLocation="../../../lib/xmldb/xmldb.xsd"
 >
@@ -61,6 +61,7 @@
         <FIELD NAME="launch" TYPE="text" NOTNULL="true" SEQUENCE="false"/>
         <FIELD NAME="scormtype" TYPE="char" LENGTH="5" NOTNULL="true" SEQUENCE="false"/>
         <FIELD NAME="title" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false"/>
+        <FIELD NAME="sortorder" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="order of scoes"/>
       </FIELDS>
       <KEYS>
         <KEY NAME="primary" TYPE="primary" FIELDS="id"/>
old mode 100644 (file)
new mode 100755 (executable)
index d6c1cff..870a988 100644 (file)
@@ -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;
 }
 
index 8f487a2..c09508a 100644 (file)
@@ -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 .= "<ul id='0' class='$liststyle'>";
                 $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;
index 65611e6..8b39f3e 100644 (file)
@@ -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);
 }
index 8287314..edb7362 100644 (file)
@@ -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 == '/') {
index c4bb765..5c55e9c 100644 (file)
@@ -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;
index d9d532b..58e426f 100644 (file)
@@ -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',
index 2550a9f..8a2881c 100644 (file)
@@ -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;
index d5a2000..3593961 100644 (file)
@@ -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;
index d4a2ff4..f1e3ee1 100644 (file)
@@ -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(
index 9f2d6c1..56084ad 100644 (file)
@@ -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;