Merge branch 'wip-MDL-32106-master' of git://github.com/marinaglancy/moodle
authorAparup Banerjee <aparup@moodle.com>
Tue, 27 Mar 2012 02:10:05 +0000 (10:10 +0800)
committerAparup Banerjee <aparup@moodle.com>
Tue, 27 Mar 2012 02:10:05 +0000 (10:10 +0800)
42 files changed:
admin/tool/xmldb/actions/edit_field/edit_field.js
admin/tool/xmldb/actions/edit_field_save/edit_field_save.class.php
admin/tool/xmldb/actions/edit_table_save/edit_table_save.class.php
admin/webservice/forms.php
config-dist.php
lang/en/backup.php
lib/ajax/ajaxcourse.js
lib/ajax/ajaxlib.php
lib/ajax/section_classes.js
lib/ddl/mysql_sql_generator.php
lib/ddl/simpletest/testddl.php
lib/ddl/sql_generator.php
lib/dml/mssql_native_moodle_database.php
lib/dml/oci_native_moodle_database.php
lib/dml/pgsql_native_moodle_database.php
lib/dml/sqlite3_pdo_moodle_database.php
lib/dml/sqlsrv_native_moodle_database.php
lib/filelib.php
lib/formslib.php
lib/messagelib.php
lib/minify/config.php
lib/moodlelib.php
lib/xmldb/xmldb_field.php
lib/xmldb/xmldb_table.php
message/lib.php
message/output/email/lang/en/message_email.php
message/output/email/lib.php [deleted file]
message/output/email/settings.php
message/output/jabber/lib.php [deleted file]
message/output/popup/lib.php [deleted file]
mod/assignment/type/upload/upload_form.php
mod/assignment/type/uploadsingle/upload_form.php
mod/choice/view.php
mod/lesson/locallib.php
mod/lesson/pagetypes/branchtable.php
mod/lesson/view.php
mod/scorm/db/install.xml
mod/scorm/lib.php
mod/scorm/styles.css
question/type/edit_question_form.php
theme/fusion/style/core.css
user/index.php

index 57dcfca..264c39d 100644 (file)
@@ -74,24 +74,24 @@ function transformForm(event) {
     // Based on type, disable some items
     switch (typeField.value) {
         case '1':  // XMLDB_TYPE_INTEGER
-            lengthTip.innerHTML = ' 1...20';
+            lengthTip.innerHTML = ' 1...20'; // Hardcoded xmldb_field::INTEGER_MAX_LENGTH, yes!
             lengthField.disabled = false;
             decimalsTip.innerHTML = '';
             decimalsField.disabled = true;
             decimalsField.value = '';
             break;
         case '2':  // XMLDB_TYPE_NUMBER
-            lengthTip.innerHTML = ' 1...20';
+            lengthTip.innerHTML = ' 1...20'; // Hardcoded xmldb_field::NUMBER_MAX_LENGTH, yes!
             lengthField.disabled = false;
             decimalsTip.innerHTML = ' 0...length or empty';
             break;
         case '3':  // XMLDB_TYPE_FLOAT
-            lengthTip.innerHTML = ' 1...20 or empty';
+            lengthTip.innerHTML = ' 1...20 or empty'; // Hardcoded xmldb_field::FLOAT_MAX_LENGTH, yes!
             lengthField.disabled = false;
             decimalsTip.innerHTML = ' 0...length or empty';
             break;
         case '4':  // XMLDB_TYPE_CHAR
-            lengthTip.innerHTML = ' 1...1333'; // Hardcoded, yes!
+            lengthTip.innerHTML = ' 1...1333'; // Hardcoded xmldb_field::CHAR_MAX_LENGTH, yes!
             lengthField.disabled = false;
             decimalsTip.innerHTML = '';
             decimalsField.disabled = true;
index 90b1433..3a60be0 100644 (file)
@@ -86,7 +86,7 @@ class edit_field_save extends XMLDBAction {
 
         $tableparam = strtolower(required_param('table', PARAM_PATH));
         $fieldparam = strtolower(required_param('field', PARAM_PATH));
-        $name = substr(trim(strtolower(optional_param('name', $fieldparam, PARAM_PATH))),0,30);
+        $name = substr(trim(strtolower(optional_param('name', $fieldparam, PARAM_PATH))),0,xmldb_field::NAME_MAX_LENGTH);
 
         $comment = required_param('comment', PARAM_CLEAN);
         $comment = trim($comment);
@@ -138,7 +138,7 @@ class edit_field_save extends XMLDBAction {
         // Integer checks
         if ($type == XMLDB_TYPE_INTEGER) {
             if (!(is_numeric($length) && !empty($length) && intval($length)==floatval($length) &&
-                  $length > 0 && $length <= 20)) {
+                  $length > 0 && $length <= xmldb_field::INTEGER_MAX_LENGTH)) {
                 $errors[] = $this->str['integerincorrectlength'];
             }
             if (!(empty($default) || (is_numeric($default) &&
@@ -150,7 +150,7 @@ class edit_field_save extends XMLDBAction {
         // Number checks
         if ($type == XMLDB_TYPE_NUMBER) {
             if (!(is_numeric($length) && !empty($length) && intval($length)==floatval($length) &&
-                  $length > 0 && $length <= 20)) {
+                  $length > 0 && $length <= xmldb_field::NUMBER_MAX_LENGTH)) {
                 $errors[] = $this->str['numberincorrectlength'];
             }
             if (!(empty($decimals) || (is_numeric($decimals) &&
@@ -171,7 +171,7 @@ class edit_field_save extends XMLDBAction {
                                      !empty($length) &&
                                      intval($length)==floatval($length) &&
                                      $length > 0 &&
-                                     $length <= 20))) {
+                                     $length <= xmldb_field::FLOAT_MAX_LENGTH))) {
                 $errors[] = $this->str['floatincorrectlength'];
             }
             if (!(empty($decimals) || (is_numeric($decimals) &&
index 7658fd0..3e5267d 100644 (file)
@@ -77,7 +77,7 @@ class edit_table_save extends XMLDBAction {
         $dirpath = $CFG->dirroot . $dirpath;
 
         $tableparam = strtolower(required_param('table', PARAM_PATH));
-        $name = substr(trim(strtolower(required_param('name', PARAM_PATH))),0,28);
+        $name = substr(trim(strtolower(required_param('name', PARAM_PATH))),0,xmldb_table::NAME_MAX_LENGTH);
         $comment = required_param('comment', PARAM_CLEAN);
         $comment = $comment;
 
index 5185b9b..96e53c6 100644 (file)
@@ -112,7 +112,7 @@ class external_service_form extends moodleform {
         $mform->setType('id', PARAM_INT);
 
         if (!empty($service->id)) {
-            $buttonlabel = get_string('editaservice', 'webservice');
+            $buttonlabel = get_string('savechanges');
         } else {
             $buttonlabel = get_string('addaservice', 'webservice');
         }
index e4fe58f..4919ed1 100644 (file)
@@ -353,6 +353,10 @@ $CFG->admin = 'admin';
 //     $CFG->tempdir = '/var/www/moodle/temp';
 //     $CFG->cachedir = '/var/www/moodle/cache';
 //
+// Some filesystems such as NFS may not support file locking operations.
+// Locking resolves race conditions and is strongly recommended for production servers.
+//     $CFG->preventfilelocking = false;
+//
 // If $CFG->langstringcache is enabled (which should always be in production
 // environment), Moodle keeps aggregated strings in its own internal format
 // optimised for performance. By default, this on-disk cache is created in
index a2cea18..0af62aa 100644 (file)
@@ -67,6 +67,7 @@ $string['backupstage16action'] = 'Continue';
 $string['backuptype'] = 'Type';
 $string['backuptypeactivity'] = 'Activity';
 $string['backuptypecourse'] = 'Course';
+$string['backuptypesection'] = 'Section';
 $string['backupversion'] = 'Backup version';
 $string['cannotfindassignablerole'] = 'The {$a} role in the backup file cannot be mapped to any of the roles that you are allowed to assign.';
 $string['choosefilefromcoursebackup'] = 'Course backup area';
index 3d6e208..f130e86 100644 (file)
@@ -182,7 +182,6 @@ main_class.prototype.mk_button = function(tag, imgSrc, text, attributes, imgAttr
 
     image.setAttribute('src', imgSrc);
     image.setAttribute('alt', text);
-    //image.setAttribute('title', '');
     container.appendChild(image);
 
     if (attributes != null) {
index 0d640e4..9148561 100644 (file)
@@ -158,6 +158,7 @@ class jsportal {
         }
         $output .= "    main.portal.icons['spacerimg']='".$OUTPUT->pix_url('spacer')."';\n";
         $output .= "    main.portal.icons['marker']='".$OUTPUT->pix_url('i/marker')."';\n";
+        $output .= "    main.portal.icons['marked']='".$OUTPUT->pix_url('i/marked')."';\n";
         $output .= "    main.portal.icons['ihide']='".$OUTPUT->pix_url('i/hide')."';\n";
         $output .= "    main.portal.icons['move_2d']='".$OUTPUT->pix_url('i/move_2d')."';\n";
         $output .= "    main.portal.icons['show']='".$OUTPUT->pix_url('t/show')."';\n";
index c787e3f..ab127f3 100644 (file)
@@ -92,7 +92,13 @@ section_class.prototype.init_buttons = function() {
     }
 
     if (main.getString('courseformat', this.sectionId) != "weeks" && this.sectionId > 0) {
-        var highlightbutton = main.mk_button('div', main.portal.icons['marker'], main.getString('marker', this.sectionId));
+        var highlightbutton = '';
+        //If current topic, then initalised as marked else marker
+        if (YAHOO.util.Dom.hasClass(this.getEl(),'current')) {
+            highlightbutton = main.mk_button('div', main.portal.icons['marked'], main.getString('marked', this.sectionId));
+        } else {
+            highlightbutton = main.mk_button('div', main.portal.icons['marker'], main.getString('marker', this.sectionId));
+        }
         YAHOO.util.Event.addListener(highlightbutton, 'click', this.mk_marker, this, true);
         commandContainer.appendChild(highlightbutton);
         this.highlightButton = highlightbutton;
@@ -331,7 +337,10 @@ section_class.prototype.toggle_hide = function(e,target,superficial) {
         YAHOO.util.Dom.removeClass(this.getEl(), 'hidden');
         this.viewButton.childNodes[0].src = this.viewButton.childNodes[0].src.replace(/show/i, 'hide');
         this.viewButton.childNodes[0].alt = this.viewButton.childNodes[0].alt.replace(strshow, strhide);
-        this.viewButton.childNodes[0].title = this.viewButton.childNodes[0].title.replace(strshow, strhide); //IE hack.
+        // mk_button set title only in ie, so check before setting it
+        if (this.viewButton.childNodes[0].title) {
+            this.viewButton.childNodes[0].title = this.viewButton.childNodes[0].title.replace(strshow, strhide); //IE hack.
+        }
         this.viewButton.title = this.viewButton.title.replace(strshow, strhide);
         this.hidden = false;
 
@@ -347,7 +356,9 @@ section_class.prototype.toggle_hide = function(e,target,superficial) {
         YAHOO.util.Dom.addClass(this.getEl(), 'hidden');
         this.viewButton.childNodes[0].src = this.viewButton.childNodes[0].src.replace(/hide/i, 'show');
         this.viewButton.childNodes[0].alt = this.viewButton.childNodes[0].alt.replace(strhide, strshow);
-        this.viewButton.childNodes[0].title = this.viewButton.childNodes[0].title.replace(strhide, strshow); //IE hack.
+        if (this.viewButton.childNodes[0].title) {
+            this.viewButton.childNodes[0].title = this.viewButton.childNodes[0].title.replace(strhide, strshow); //IE hack.
+        }
         this.viewButton.title = this.viewButton.title.replace(strhide, strshow);
         this.hidden = true;
 
@@ -363,11 +374,27 @@ section_class.prototype.toggle_hide = function(e,target,superficial) {
 
 
 section_class.prototype.toggle_highlight = function() {
+    var strmarker = main.portal.strings['marker'];
+    var strmarked = main.portal.strings['marked'];
+
     if (this.highlighted) {
         YAHOO.util.Dom.removeClass(this.getEl(), 'current');
+        this.highlightButton.childNodes[0].src = main.portal.icons['marker'];
+        this.highlightButton.childNodes[0].alt = strmarker;
+        // mk_button set title only in ie, so check before setting it
+        if (this.highlightButton.childNodes[0].title) {
+            this.highlightButton.childNodes[0].title = strmarker;   //for IE
+        }
+        this.highlightButton.title = strmarker;
         this.highlighted = false;
     } else {
         YAHOO.util.Dom.addClass(this.getEl(), 'current');
+        this.highlightButton.childNodes[0].src = main.portal.icons['marked'];
+        this.highlightButton.childNodes[0].alt = strmarked;
+        if (this.highlightButton.childNodes[0].title) {
+            this.highlightButton.childNodes[0].title = strmarked;   //for IE
+        }
+        this.highlightButton.title = strmarked;
         this.highlighted = true;
     }
 };
index 11e241a..ec1c204 100644 (file)
@@ -234,11 +234,12 @@ class mysql_sql_generator extends sql_generator {
         $xmldb_field_clone = clone($xmldb_field);
 
     /// Change the name of the field to perform the change
-        $xmldb_field_clone->setName($xmldb_field_clone->getName() . ' ' . $newname);
+        $xmldb_field_clone->setName($newname);
 
         $fieldsql = $this->getFieldSQL($xmldb_table, $xmldb_field_clone);
 
-        $sql = 'ALTER TABLE ' . $this->getTableName($xmldb_table) . ' CHANGE ' . $fieldsql;
+        $sql = 'ALTER TABLE ' . $this->getTableName($xmldb_table) . ' CHANGE ' .
+               $xmldb_field->getName() . ' ' . $fieldsql;
 
         return array($sql);
     }
index 5d452a0..56e4583 100644 (file)
@@ -15,6 +15,7 @@ require_once($CFG->libdir . '/adminlib.php');
 class ddl_test extends UnitTestCase {
     private $tables = array();
     private $records= array();
+    /** @var moodle_database */
     private $tdb;
     public  static $includecoverage = array('lib/ddl');
     public  static $excludecoverage = array('lib/ddl/simpletest');
@@ -310,6 +311,225 @@ class ddl_test extends UnitTestCase {
             $this->assertTrue($e instanceof ddl_exception);
         }
 
+        // long table name names - the largest allowed
+        $table = new xmldb_table('abcdef____0123456789_____xyz');
+        $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
+        $table->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '2');
+        $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
+        $table->setComment("This is a test'n drop table. You can drop it safely");
+
+        $this->tables[$table->getName()] = $table;
+
+        $dbman->create_table($table);
+        $this->assertTrue($dbman->table_exists($table));
+        $dbman->drop_table($table);
+
+        // table name is too long
+        $table = new xmldb_table('abcdef____0123456789_____xyz9');
+        $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
+        $table->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '2');
+        $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
+        $table->setComment("This is a test'n drop table. You can drop it safely");
+
+        $this->tables[$table->getName()] = $table;
+
+        try {
+            $dbman->create_table($table);
+            $this->fail('Exception expected');
+        } catch (Exception $e) {
+            $this->assertIdentical(get_class($e), 'coding_exception');
+        }
+
+        // invalid table name
+        $table = new xmldb_table('abCD');
+        $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
+        $table->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '2');
+        $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
+        $table->setComment("This is a test'n drop table. You can drop it safely");
+
+        $this->tables[$table->getName()] = $table;
+
+        try {
+            $dbman->create_table($table);
+            $this->fail('Exception expected');
+        } catch (Exception $e) {
+            $this->assertIdentical(get_class($e), 'coding_exception');
+        }
+
+
+        // weird column names - the largest allowed
+        $table = new xmldb_table('test_table3');
+        $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
+        $table->add_field('abcdef____0123456789_______xyz', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '2');
+        $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
+        $table->setComment("This is a test'n drop table. You can drop it safely");
+
+        $this->tables[$table->getName()] = $table;
+
+        $dbman->create_table($table);
+        $this->assertTrue($dbman->table_exists($table));
+        $dbman->drop_table($table);
+
+        // Too long field name - max 30
+        $table = new xmldb_table('test_table4');
+        $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
+        $table->add_field('abcdeabcdeabcdeabcdeabcdeabcdez', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '2');
+        $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
+        $table->setComment("This is a test'n drop table. You can drop it safely");
+
+        $this->tables[$table->getName()] = $table;
+
+        try {
+            $dbman->create_table($table);
+            $this->fail('Exception expected');
+        } catch (Exception $e) {
+            $this->assertIdentical(get_class($e), 'coding_exception');
+        }
+
+        // Invalid field name
+        $table = new xmldb_table('test_table4');
+        $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
+        $table->add_field('abCD', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '2');
+        $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
+        $table->setComment("This is a test'n drop table. You can drop it safely");
+
+        $this->tables[$table->getName()] = $table;
+
+        try {
+            $dbman->create_table($table);
+            $this->fail('Exception expected');
+        } catch (Exception $e) {
+            $this->assertIdentical(get_class($e), 'coding_exception');
+        }
+
+        // Invalid integer length
+        $table = new xmldb_table('test_table4');
+        $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
+        $table->add_field('course', XMLDB_TYPE_INTEGER, '21', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '2');
+        $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
+        $table->setComment("This is a test'n drop table. You can drop it safely");
+
+        $this->tables[$table->getName()] = $table;
+
+        try {
+            $dbman->create_table($table);
+            $this->fail('Exception expected');
+        } catch (Exception $e) {
+            $this->assertIdentical(get_class($e), 'coding_exception');
+        }
+
+        // Invalid integer default
+        $table = new xmldb_table('test_table4');
+        $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
+        $table->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, 'x');
+        $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
+        $table->setComment("This is a test'n drop table. You can drop it safely");
+
+        $this->tables[$table->getName()] = $table;
+
+        try {
+            $dbman->create_table($table);
+            $this->fail('Exception expected');
+        } catch (Exception $e) {
+            $this->assertIdentical(get_class($e), 'coding_exception');
+        }
+
+        // Invalid decimal length
+        $table = new xmldb_table('test_table4');
+        $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
+        $table->add_field('num', XMLDB_TYPE_NUMBER, '21,10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null);
+        $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
+        $table->setComment("This is a test'n drop table. You can drop it safely");
+
+        $this->tables[$table->getName()] = $table;
+
+        try {
+            $dbman->create_table($table);
+            $this->fail('Exception expected');
+        } catch (Exception $e) {
+            $this->assertIdentical(get_class($e), 'coding_exception');
+        }
+
+        // Invalid decimal decimals
+        $table = new xmldb_table('test_table4');
+        $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
+        $table->add_field('num', XMLDB_TYPE_NUMBER, '10,11', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null);
+        $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
+        $table->setComment("This is a test'n drop table. You can drop it safely");
+
+        $this->tables[$table->getName()] = $table;
+
+        try {
+            $dbman->create_table($table);
+            $this->fail('Exception expected');
+        } catch (Exception $e) {
+            $this->assertIdentical(get_class($e), 'coding_exception');
+        }
+
+        // Invalid decimal default
+        $table = new xmldb_table('test_table4');
+        $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
+        $table->add_field('num', XMLDB_TYPE_NUMBER, '10,5', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, 'x');
+        $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
+        $table->setComment("This is a test'n drop table. You can drop it safely");
+
+        $this->tables[$table->getName()] = $table;
+
+        try {
+            $dbman->create_table($table);
+            $this->fail('Exception expected');
+        } catch (Exception $e) {
+            $this->assertIdentical(get_class($e), 'coding_exception');
+        }
+
+        // Invalid float length
+        $table = new xmldb_table('test_table4');
+        $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
+        $table->add_field('num', XMLDB_TYPE_FLOAT, '21,10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null);
+        $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
+        $table->setComment("This is a test'n drop table. You can drop it safely");
+
+        $this->tables[$table->getName()] = $table;
+
+        try {
+            $dbman->create_table($table);
+            $this->fail('Exception expected');
+        } catch (Exception $e) {
+            $this->assertIdentical(get_class($e), 'coding_exception');
+        }
+
+        // Invalid float decimals
+        $table = new xmldb_table('test_table4');
+        $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
+        $table->add_field('num', XMLDB_TYPE_FLOAT, '10,11', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null);
+        $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
+        $table->setComment("This is a test'n drop table. You can drop it safely");
+
+        $this->tables[$table->getName()] = $table;
+
+        try {
+            $dbman->create_table($table);
+            $this->fail('Exception expected');
+        } catch (Exception $e) {
+            $this->assertIdentical(get_class($e), 'coding_exception');
+        }
+
+        // Invalid float default
+        $table = new xmldb_table('test_table4');
+        $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
+        $table->add_field('num', XMLDB_TYPE_FLOAT, '10,5', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, 'x');
+        $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
+        $table->setComment("This is a test'n drop table. You can drop it safely");
+
+        $this->tables[$table->getName()] = $table;
+
+        try {
+            $dbman->create_table($table);
+            $this->fail('Exception expected');
+        } catch (Exception $e) {
+            $this->assertIdentical(get_class($e), 'coding_exception');
+        }
+
     }
 
     /**
index 6103931..cb18729 100644 (file)
@@ -292,6 +292,9 @@ abstract class sql_generator {
      * by any of its comments, indexes and sequence creation SQL statements.
      */
     public function getCreateTableSQL($xmldb_table) {
+        if ($error = $xmldb_table->validateDefinition()) {
+            throw new coding_exception($error);
+        }
 
         $results = array();  //Array where all the sentences will be stored
 
index 18e7681..6e8b357 100644 (file)
@@ -351,10 +351,12 @@ class mssql_native_moodle_database extends moodle_database {
         if ($result) {
             while ($row = mssql_fetch_row($result)) {
                 $tablename = reset($row);
-                if (strpos($tablename, $this->prefix) !== 0) {
-                    continue;
+                if ($this->prefix !== '') {
+                    if (strpos($tablename, $this->prefix) !== 0) {
+                        continue;
+                    }
+                    $tablename = substr($tablename, strlen($this->prefix));
                 }
-                $tablename = substr($tablename, strlen($this->prefix));
                 $this->tables[$tablename] = $tablename;
             }
             $this->free_result($result);
index 8beaf21..a529277 100644 (file)
@@ -419,10 +419,12 @@ class oci_native_moodle_database extends moodle_database {
         oci_free_statement($stmt);
         $records = array_map('strtolower', $records['TABLE_NAME']);
         foreach ($records as $tablename) {
-            if (strpos($tablename, $this->prefix) !== 0) {
-                continue;
+            if ($this->prefix !== '') {
+                if (strpos($tablename, $this->prefix) !== 0) {
+                    continue;
+                }
+                $tablename = substr($tablename, strlen($this->prefix));
             }
-            $tablename = substr($tablename, strlen($this->prefix));
             $this->tables[$tablename] = $tablename;
         }
 
index 7262f65..3d9771d 100644 (file)
@@ -297,10 +297,12 @@ class pgsql_native_moodle_database extends moodle_database {
         if ($result) {
             while ($row = pg_fetch_row($result)) {
                 $tablename = reset($row);
-                if (strpos($tablename, $this->prefix) !== 0) {
-                    continue;
+                if ($this->prefix !== '') {
+                    if (strpos($tablename, $this->prefix) !== 0) {
+                        continue;
+                    }
+                    $tablename = substr($tablename, strlen($this->prefix));
                 }
-                $tablename = substr($tablename, strlen($this->prefix));
                 $this->tables[$tablename] = $tablename;
             }
             pg_free_result($result);
index 01731fc..c52b2f1 100644 (file)
@@ -152,10 +152,13 @@ class sqlite3_pdo_moodle_database extends pdo_moodle_database {
         foreach ($rstables as $table) {
             $table = $table['name'];
             $table = strtolower($table);
-            if (empty($this->prefix) || strpos($table, $this->prefix) === 0) {
+            if ($this->prefix !== '') {
+                if (strpos($table, $this->prefix) !== 0) {
+                    continue;
+                }
                 $table = substr($table, strlen($this->prefix));
-                $tables[$table] = $table;
             }
+            $tables[$table] = $table;
         }
         return $tables;
     }
index 2147e6c..5fe2ab2 100644 (file)
@@ -401,10 +401,12 @@ class sqlsrv_native_moodle_database extends moodle_database {
         if ($result) {
             while ($row = sqlsrv_fetch_array($result)) {
                 $tablename = reset($row);
-                if (strpos($tablename, $this->prefix) !== 0) {
-                    continue;
+                if ($this->prefix !== '') {
+                    if (strpos($tablename, $this->prefix) !== 0) {
+                        continue;
+                    }
+                    $tablename = substr($tablename, strlen($this->prefix));
                 }
-                $tablename = substr($tablename, strlen($this->prefix));
                 $this->tables[$tablename] = $tablename;
             }
             $this->free_result($result);
index 43bc8dd..1d0b01c 100644 (file)
@@ -1596,9 +1596,19 @@ function get_mimetype_description($mimetype, $capitalise=false) {
  */
 function send_file_not_found() {
     global $CFG, $COURSE;
-    header('HTTP/1.0 404 not found');
+    send_header_404();
     print_error('filenotfound', 'error', $CFG->wwwroot.'/course/view.php?id='.$COURSE->id); //this is not displayed on IIS??
 }
+/**
+ * Helper function to send correct 404 for server.
+ */
+function send_header_404() {
+    if (substr(php_sapi_name(), 0, 3) == 'cgi') {
+        header("Status: 404 Not Found");
+    } else {
+        header('HTTP/1.0 404 not found');
+    }
+}
 
 /**
  * Check output buffering settings before sending file.
@@ -1651,7 +1661,7 @@ function send_temp_file($path, $filename, $pathisstring=false) {
 
     if (!$pathisstring) {
         if (!file_exists($path)) {
-            header('HTTP/1.0 404 not found');
+            send_header_404();
             print_error('filenotfound', 'error', $CFG->wwwroot.'/');
         }
         // executed after normal finish or abort
index a005064..18c0c89 100644 (file)
@@ -1009,7 +1009,7 @@ abstract class moodleform {
 
                     switch ($option){
                         case 'default' :
-                            $mform->setDefault($realelementname, $params);
+                            $mform->setDefault($realelementname, str_replace('{no}', $i + 1, $params));
                             break;
                         case 'helpbutton' :
                             $params = array_merge(array($realelementname), $params);
index 9619b96..b86ac10 100644 (file)
@@ -128,7 +128,7 @@ function message_send($eventdata) {
         } else {
             //MDL-25114 They supplied an $eventdata->component $eventdata->name combination which doesn't
             //exist in the message_provider table (thus there is no default settings for them)
-            $preferrormsg = get_string('couldnotfindpreference', 'message', $preferencename); //TODO: undefined $preferencename
+            $preferrormsg = get_string('couldnotfindpreference', 'message', $defaultpreference);
             throw new coding_exception($preferrormsg,'blah');
         }
 
index e2f709c..90e557f 100644 (file)
@@ -17,7 +17,7 @@ $min_errorLogger = false;
 $min_allowDebugFlag = debugging('', DEBUG_DEVELOPER);
 $min_cachePath = $CFG->tempdir;
 $min_documentRoot = $CFG->dirroot.'/lib/minify';
-$min_cacheFileLocking = true;
+$min_cacheFileLocking = empty($CFG->preventfilelocking);
 $min_serveOptions['bubbleCssImports'] = false;
 $min_serveOptions['maxAge'] = 1800;
 $min_serveOptions['minApp']['groupsOnly'] = true;
index c737f5a..fe642a9 100644 (file)
@@ -2726,7 +2726,9 @@ function require_login($courseorid = NULL, $autologinguest = true, $cm = NULL, $
     if (get_user_preferences('auth_forcepasswordchange') && !session_is_loggedinas()) {
         $userauth = get_auth_plugin($USER->auth);
         if ($userauth->can_change_password() and !$preventredirect) {
-            $SESSION->wantsurl = $FULLME;
+            if ($setwantsurltome) {
+                $SESSION->wantsurl = $FULLME;
+            }
             if ($changeurl = $userauth->change_password_url()) {
                 //use plugin custom url
                 redirect($changeurl);
@@ -2749,7 +2751,9 @@ function require_login($courseorid = NULL, $autologinguest = true, $cm = NULL, $
         if ($preventredirect) {
             throw new require_login_exception('User not fully set-up');
         }
-        $SESSION->wantsurl = $FULLME;
+        if ($setwantsurltome) {
+            $SESSION->wantsurl = $FULLME;
+        }
         redirect($CFG->wwwroot .'/user/edit.php?id='. $USER->id .'&amp;course='. SITEID);
     }
 
@@ -2769,13 +2773,17 @@ function require_login($courseorid = NULL, $autologinguest = true, $cm = NULL, $
             if ($preventredirect) {
                 throw new require_login_exception('Policy not agreed');
             }
-            $SESSION->wantsurl = $FULLME;
+            if ($setwantsurltome) {
+                $SESSION->wantsurl = $FULLME;
+            }
             redirect($CFG->wwwroot .'/user/policy.php');
         } else if (!empty($CFG->sitepolicyguest) and isguestuser()) {
             if ($preventredirect) {
                 throw new require_login_exception('Policy not agreed');
             }
-            $SESSION->wantsurl = $FULLME;
+            if ($setwantsurltome) {
+                $SESSION->wantsurl = $FULLME;
+            }
             redirect($CFG->wwwroot .'/user/policy.php');
         }
     }
@@ -2927,7 +2935,9 @@ function require_login($courseorid = NULL, $autologinguest = true, $cm = NULL, $
             if ($preventredirect) {
                 throw new require_login_exception('Not enrolled');
             }
-            $SESSION->wantsurl = $FULLME;
+            if ($setwantsurltome) {
+                $SESSION->wantsurl = $FULLME;
+            }
             redirect($CFG->wwwroot .'/enrol/index.php?id='. $course->id);
         }
     }
@@ -5020,6 +5030,7 @@ function get_mailer($action='get') {
                 $mailer->SMTPDebug = true;
             }
             $mailer->Host          = $CFG->smtphosts;        // specify main and backup servers
+            $mailer->SMTPSecure    = $CFG->smtpsecure;       // specify secure connection protocol
             $mailer->SMTPKeepAlive = $prevkeepalive;         // use previous keepalive
 
             if ($CFG->smtpuser) {                            // Use SMTP authentication
index a47f87e..11e7a2d 100644 (file)
@@ -46,6 +46,30 @@ class xmldb_field extends xmldb_object {
      */
     const CHAR_MAX_LENGTH = 1333;
 
+
+    /**
+     * @const maximum number of digits of integers
+     */
+    const INTEGER_MAX_LENGTH = 20;
+
+    /**
+     * @const max length of decimals
+     */
+    const NUMBER_MAX_LENGTH = 20;
+
+    /**
+     * @const max length of floats
+     */
+    const FLOAT_MAX_LENGTH = 20;
+
+    /**
+     * Note:
+     *  - Oracle has 30 chars limit for all names
+     *
+     * @const maximumn length of field names
+     */
+    const NAME_MAX_LENGTH = 30;
+
     /**
      * Creates one new xmldb_field
      */
@@ -701,17 +725,66 @@ class xmldb_field extends xmldb_object {
      */
     function validateDefinition(xmldb_table $xmldb_table=null) {
         if (!$xmldb_table) {
-            return 'Invalid xmldb_field->validateDefinition() call, $xmldb_table si required.';
+            return 'Invalid xmldb_field->validateDefinition() call, $xmldb_table is required.';
+        }
+
+        $name = $this->getName();
+        if (strlen($name) > self::NAME_MAX_LENGTH) {
+            return 'Invalid field name in table {'.$xmldb_table->getName().'}: field "'.$this->getName().'" name is too long.'
+                .' Limit is '.self::NAME_MAX_LENGTH.' chars.';
+        }
+        if (!preg_match('/^[a-z][a-z0-9_]*$/', $name)) {
+            return 'Invalid field name in table {'.$xmldb_table->getName().'}: field "'.$this->getName().'" name includes invalid characters.';
         }
 
         switch ($this->getType()) {
             case XMLDB_TYPE_INTEGER:
+                $length = $this->getLength();
+                if (!is_number($length) or $length <= 0 or $length > self::INTEGER_MAX_LENGTH) {
+                    return 'Invalid field definition in table {'.$xmldb_table->getName().'}: XMLDB_TYPE_INTEGER field "'.$this->getName().'" has invalid length';
+                }
+                $default = $this->getDefault();
+                if (!empty($default) and !is_number($default)) {
+                    return 'Invalid field definition in table {'.$xmldb_table->getName().'}: XMLDB_TYPE_INTEGER field "'.$this->getName().'" has invalid default';
+                }
                 break;
 
             case XMLDB_TYPE_NUMBER:
+                $maxlength = self::NUMBER_MAX_LENGTH;
+                if ($xmldb_table->getName() === 'question_numerical_units' and $name === 'multiplier') {
+                    //TODO: remove after MDL-32113 is resolved
+                    $maxlength = 40;
+                }
+                $length = $this->getLength();
+                if (!is_number($length) or $length <= 0 or $length > $maxlength) {
+                    return 'Invalid field definition in table {'.$xmldb_table->getName().'}: XMLDB_TYPE_NUMBER field "'.$this->getName().'" has invalid length';
+                }
+                $decimals = $this->getDecimals();
+                $decimals = empty($decimals) ? 0 : $decimals; // fix missing decimals
+                if (!is_number($decimals) or $decimals < 0 or $decimals > $length) {
+                    return 'Invalid field definition in table {'.$xmldb_table->getName().'}: XMLDB_TYPE_NUMBER field "'.$this->getName().'" has invalid decimals';
+                }
+                $default = $this->getDefault();
+                if (!empty($default) and !is_numeric($default)) {
+                    return 'Invalid field definition in table {'.$xmldb_table->getName().'}: XMLDB_TYPE_NUMBER field "'.$this->getName().'" has invalid default';
+                }
                 break;
 
             case XMLDB_TYPE_FLOAT:
+                $length = $this->getLength();
+                $length = empty($length) ? 6 : $length; // weird, it might be better to require something here...
+                if (!is_number($length) or $length <= 0 or $length > self::FLOAT_MAX_LENGTH) {
+                    return 'Invalid field definition in table {'.$xmldb_table->getName().'}: XMLDB_TYPE_FLOAT field "'.$this->getName().'" has invalid length';
+                }
+                $decimals = $this->getDecimals();
+                $decimals = empty($decimals) ? 0 : $decimals; // fix missing decimals
+                if (!is_number($decimals) or $decimals < 0 or $decimals > $length) {
+                    return 'Invalid field definition in table {'.$xmldb_table->getName().'}: XMLDB_TYPE_FLOAT field "'.$this->getName().'" has invalid decimals';
+                }
+                $default = $this->getDefault();
+                if (!empty($default) and !is_numeric($default)) {
+                    return 'Invalid field definition in table {'.$xmldb_table->getName().'}: XMLDB_TYPE_FLOAT field "'.$this->getName().'" has invalid default';
+                }
                 break;
 
             case XMLDB_TYPE_CHAR:
index 66148df..614354f 100644 (file)
@@ -32,6 +32,15 @@ class xmldb_table extends xmldb_object {
     var $keys;
     var $indexes;
 
+    /**
+     * Note:
+     *  - Oracle has 30 chars limit for all names,
+     *    2 chars are reserved for prefix.
+     *
+     * @const maximumn length of field names
+     */
+    const NAME_MAX_LENGTH = 28;
+
     /**
      * Creates one new xmldb_table
      */
@@ -660,6 +669,27 @@ class xmldb_table extends xmldb_object {
     }
 
     /**
+     * Validates the table restrictions (does not validate child elements).
+     *
+     * The error message should not be localised because it is intended for developers,
+     * end users and admins should never see these problems!
+     *
+     * @param xmldb_table $xmldb_table optional when object is table
+     * @return string null if ok, error message if problem found
+     */
+    function validateDefinition(xmldb_table $xmldb_table=null) {
+        // table parameter is ignored
+        $name = $this->getName();
+        if (strlen($name) > self::NAME_MAX_LENGTH) {
+            return 'Invalid table name {'.$name.'}: name is too long. Limit is 28 chars.';
+        }
+        if (!preg_match('/^[a-z][a-z0-9_]*$/', $name)) {
+            return 'Invalid table name {'.$name.'}: name includes invalid characters.';
+        }
+
+        return null;
+    }
+        /**
      * This function will output the XML text for one table
      */
     function xmlOutput() {
index 6fd8a46..7e80811 100644 (file)
@@ -1503,7 +1503,7 @@ function message_search_users($courseid, $searchtext, $sort='', $exceptions='')
 
         // everyone who has a role assignment in this course or higher
         $params = array($USER->id, "%$searchtext%");
-        $users = $DB->get_records_sql("SELECT $ufields, mc.id as contactlistid, mc.blocked
+        $users = $DB->get_records_sql("SELECT DISTINCT $ufields, mc.id as contactlistid, mc.blocked
                                          FROM {user} u
                                          JOIN {role_assignments} ra ON ra.userid = u.id
                                          LEFT JOIN {message_contacts} mc
index 32a16f7..248253a 100644 (file)
@@ -27,16 +27,19 @@ $string['configallowusermailcharset'] = 'Enabling this, every user in the site w
 $string['configmailnewline'] = 'Newline characters used in mail messages. CRLF is required according to RFC 822bis, some mail servers do automatic conversion from LF to CRLF, other mail servers do incorrect conversion from CRLF to CRCRLF, yet others reject mails with bare LF (qmail for example). Try changing this setting if you are having problems with undelivered emails or double newlines.';
 $string['confignoreplyaddress'] = 'Emails are sometimes sent out on behalf of a user (eg forum posts). The email address you specify here will be used as the "From" address in those cases when the recipients should not be able to reply directly to the user (eg when a user chooses to keep their address private).';
 $string['configsitemailcharset'] = 'All the emails generated by your site will be sent in the charset specified here. Anyway, every individual user will be able to adjust it if the next setting is enabled.';
-$string['configsmtphosts'] = 'Give the full name of one or more local SMTP servers that Moodle should use to send mail (eg \'mail.a.com\' or \'mail.a.com;mail.b.com\'). To specify a non-default port (i.e other than port 25), you can use the [server]:[port] syntax (eg \'mail.a.com:587\'. If you leave it blank, Moodle will use the PHP default method of sending mail.';
+$string['configsmtphosts'] = 'Give the full name of one or more local SMTP servers that Moodle should use to send mail (eg \'mail.a.com\' or \'mail.a.com;mail.b.com\'). To specify a non-default port (i.e other than port 25), you can use the [server]:[port] syntax (eg \'mail.a.com:587\'). For secure connections, port 465 is usually used with SSL, port 587 is usually used with TLS, specify security protocol below if required. If you leave this field blank, Moodle will use the PHP default method of sending mail.';
 $string['configsmtpmaxbulk'] = 'Maximum number of messages sent per SMTP session. Grouping messages may speed up the sending of emails. Values lower than 2 force creation of new SMTP session for each email.';
+$string['configsmtpsecure'] = 'If smtp server requires secure connection, specify the correct protocol type.';
 $string['configsmtpuser'] = 'If you have specified an SMTP server above, and the server requires authentication, then enter the username and password here.';
 $string['email'] = 'Send email notifications to';
 $string['ifemailleftempty'] = 'Leave empty to send notifications to {$a}';
 $string['mailnewline'] = 'Newline characters in mail';
+$string['none'] = 'None';
 $string['noreplyaddress'] = 'No-reply address';
 $string['pluginname'] = 'Email';
 $string['sitemailcharset'] = 'Character set';
 $string['smtphosts'] = 'SMTP hosts';
 $string['smtpmaxbulk'] = 'SMTP session limit';
 $string['smtppass'] = 'SMTP password';
-$string['smtpuser'] = 'SMTP username';
+$string['smtpsecure'] = 'SMTP security';
+$string['smtpuser'] = 'SMTP username';
\ No newline at end of file
diff --git a/message/output/email/lib.php b/message/output/email/lib.php
deleted file mode 100644 (file)
index 26d0754..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-<?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/>.
-
-/**
- * Email message processor library file
- *
- * @package    message_email
- * @copyright  2008 Luis Rodrigues and Martin Dougiamas
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-/**
- * Register the processor
- */
-function email_install(){
-    global $DB;
-    $result = true;
-
-    $provider = new stdClass();
-    $provider->name  = 'email';
-    $DB->insert_record('message_processors', $provider);
-    return $result;
-}
index 240a9fb..8f7c2fb 100644 (file)
@@ -26,6 +26,8 @@ defined('MOODLE_INTERNAL') || die;
 
 if ($ADMIN->fulltree) {
     $settings->add(new admin_setting_configtext('smtphosts', get_string('smtphosts', 'message_email'), get_string('configsmtphosts', 'message_email'), '', PARAM_RAW));
+    $options = array('' => get_string('none', 'message_email'), 'ssl' => 'SSL', 'tls' => 'TLS');
+    $settings->add(new admin_setting_configselect('smtpsecure', get_string('smtpsecure', 'message_email'), get_string('configsmtpsecure', 'message_email'), '', $options));
     $settings->add(new admin_setting_configtext('smtpuser', get_string('smtpuser', 'message_email'), get_string('configsmtpuser', 'message_email'), '', PARAM_NOTAGS));
     $settings->add(new admin_setting_configpasswordunmask('smtppass', get_string('smtppass', 'message_email'), get_string('configsmtpuser', 'message_email'), ''));
     $settings->add(new admin_setting_configtext('smtpmaxbulk', get_string('smtpmaxbulk', 'message_email'), get_string('configsmtpmaxbulk', 'message_email'), 1, PARAM_INT));
diff --git a/message/output/jabber/lib.php b/message/output/jabber/lib.php
deleted file mode 100644 (file)
index c0e677f..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-<?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/>.
-
-/**
- * Jabber message processor - lib file
- *
- * @package    message_jabber
- * @copyright  2008 Luis Rodrigues
- * @license    http://www.gnu.org/copyleft/gpl.html GNU Public License
- */
-
-/**
- * Register the processor.
- */
-function jabber_install(){
-    global $DB;
-
-    $result = true;
-
-    $provider = new stdClass();
-    $provider->name  = 'jabber';
-    $DB->insert_record('message_processors', $provider);
-    return $result;
-}
diff --git a/message/output/popup/lib.php b/message/output/popup/lib.php
deleted file mode 100644 (file)
index dd16ff3..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-<?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/>.
-
-/**
- * Popup message processor - lib file
- *
- * @package   message_popup
- * @copyright 2008 Luis Rodrigues
- * @license   http://www.gnu.org/copyleft/gpl.html GNU Public License
- */
-
-/**
- * Register the popup message processor
- */
-function popup_install(){
-    global $DB;
-
-    $result = true;
-
-    $provider = new stdClass();
-    $provider->name  = 'popup';
-    $DB->insert_record('message_processors', $provider);
-    return $result;
-}
-
index ecfa5d3..df12a01 100644 (file)
@@ -28,6 +28,7 @@ class mod_assignment_upload_form extends moodleform {
 
         // visible elements
         $mform->addElement('filemanager', 'files_filemanager', get_string('uploadafile'), null, $instance['options']);
+        $mform->addRule('files_filemanager', get_string('uploadnofilefound'), 'required', null, 'client');
 
         // hidden params
         $mform->addElement('hidden', 'contextid', $instance['contextid']);
index 0a79a85..1edb37e 100644 (file)
@@ -30,6 +30,7 @@ class mod_assignment_uploadsingle_form extends moodleform {
         //$mform->addElement('filemanager', 'newfile', get_string('uploadafile'));
         //$mform->addElement('filemanager', 'files_filemanager', get_string('uploadafile'), null, $instance['options']);
         $mform->addElement('filepicker', 'assignment_file', get_string('uploadafile'), null, $instance['options']);
+        $mform->addRule('assignment_file', get_string('uploadnofilefound'), 'required', null, 'client');
 
         // hidden params
         $mform->addElement('hidden', 'contextid', $instance['contextid']);
index e4a49b0..d097286 100644 (file)
         echo $OUTPUT->box(format_module_intro('choice', $choice, $cm->id), 'generalbox', 'intro');
     }
 
+    $timenow = time();
     $current = false;  // Initialise for later
-    //if user has already made a selection, and they are not allowed to update it, show their selected answer.
+    //if user has already made a selection, and they are not allowed to update it or if choice is not open, show their selected answer.
     if (isloggedin() && ($current = $DB->get_record('choice_answers', array('choiceid' => $choice->id, 'userid' => $USER->id))) &&
-        empty($choice->allowupdate) ) {
+        (empty($choice->allowupdate) || ($timenow > $choice->timeclose)) ) {
         echo $OUTPUT->box(get_string("yourselection", "choice", userdate($choice->timeopen)).": ".format_string(choice_get_option_text($choice, $current->optionid)), 'generalbox', 'yourselection');
     }
 
 /// Print the form
     $choiceopen = true;
-    $timenow = time();
     if ($choice->timeclose !=0) {
         if ($choice->timeopen > $timenow ) {
             echo $OUTPUT->box(get_string("notopenyet", "choice", userdate($choice->timeopen)), "generalbox notopenyet");
index f35864e..0eefb50 100644 (file)
@@ -201,6 +201,7 @@ function lesson_unseen_branch_jump($lesson, $userid) {
     // this function searches through the lesson pages to find all the branch tables
     // that follow the flagged branch table
     $pageid = $lessonpages[$start]->nextpageid; // move down from the flagged branch table
+    $branchtables = array();
     while ($pageid != 0) {  // grab all of the branch table till eol
         if ($lessonpages[$pageid]->qtype == LESSON_PAGE_BRANCHTABLE) {
             $branchtables[] = $lessonpages[$pageid]->id;
index 3965bf7..6f29bb8 100644 (file)
@@ -79,6 +79,10 @@ class lesson_page_type_branchtable extends lesson_page {
         $jump[LESSON_NEXTPAGE] = get_string("nextpage", "lesson");
         $jump[LESSON_PREVIOUSPAGE] = get_string("previouspage", "lesson");
         $jump[LESSON_EOL] = get_string("endoflesson", "lesson");
+        $jump[LESSON_UNSEENBRANCHPAGE] = get_string("unseenpageinbranch", "lesson");
+        $jump[LESSON_RANDOMPAGE] = get_string("randompageinbranch", "lesson");
+        $jump[LESSON_RANDOMBRANCH] = get_string("randombranch", "lesson");
+
         if (!$firstpage) {
             if (!$apageid = $DB->get_field("lesson_pages", "id", array("lessonid" => $lesson->id, "prevpageid" => 0))) {
                 print_error('cannotfindfirstpage', 'lesson');
index e0540b0..c274104 100644 (file)
@@ -194,20 +194,18 @@ if (empty($pageid)) {
     // if there are any questions have been answered correctly in this attempt
     $corrrectattempts = $lesson->get_attempts($retries, true);
     if ($corrrectattempts>0) {
-        foreach ($corrrectattempts as $attempt) {
-            $jumpto = $DB->get_field('lesson_answers', 'jumpto', array('id' => $attempt->answerid));
-            // convert the jumpto to a proper page id
-            if ($jumpto == 0) { // unlikely value!
-                $lastpageseen = $attempt->pageid;
-            } elseif ($jumpto == LESSON_NEXTPAGE) {
-                if (!$lastpageseen = $DB->get_field('lesson_pages', 'nextpageid', array('id' => $attempt->pageid))) {
-                    // no nextpage go to end of lesson
-                    $lastpageseen = LESSON_EOL;
-                }
-            } else {
-                $lastpageseen = $jumpto;
+        $attempt = end($corrrectattempts);
+        $jumpto = $DB->get_field('lesson_answers', 'jumpto', array('id' => $attempt->answerid));
+        // convert the jumpto to a proper page id
+        if ($jumpto == 0) { // unlikely value!
+            $lastpageseen = $attempt->pageid;
+        } elseif ($jumpto == LESSON_NEXTPAGE) {
+            if (!$lastpageseen = $DB->get_field('lesson_pages', 'nextpageid', array('id' => $attempt->pageid))) {
+                // no nextpage go to end of lesson
+                $lastpageseen = LESSON_EOL;
             }
-            break; // only look at the latest correct attempt
+        } else {
+            $lastpageseen = $jumpto;
         }
     }
 
index c5611a4..1ebc2ec 100644 (file)
 <?xml version="1.0" encoding="UTF-8" ?>
-<XMLDB PATH="mod/scorm/db" VERSION="20120122" COMMENT="XMLDB file for Moodle mod/scorm"
-       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-       xsi:noNamespaceSchemaLocation="../../../lib/xmldb/xmldb.xsd"
-        >
-    <TABLES>
-        <TABLE NAME="scorm" COMMENT="each table is one SCORM module and its configuration" NEXT="scorm_scoes">
-            <FIELDS>
-                <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true" NEXT="course"/>
-                <FIELD NAME="course" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="id" NEXT="name"/>
-                <FIELD NAME="name" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" PREVIOUS="course" NEXT="scormtype"/>
-                <FIELD NAME="scormtype" TYPE="char" LENGTH="50" NOTNULL="true" DEFAULT="local" SEQUENCE="false" COMMENT="local, external or repository" PREVIOUS="name" NEXT="reference"/>
-                <FIELD NAME="reference" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" PREVIOUS="scormtype" NEXT="intro"/>
-                <FIELD NAME="intro" TYPE="text" NOTNULL="true" SEQUENCE="false" PREVIOUS="reference" NEXT="introformat"/>
-                <FIELD NAME="introformat" TYPE="int" LENGTH="4" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="intro" NEXT="version"/>
-                <FIELD NAME="version" TYPE="char" LENGTH="9" NOTNULL="true" SEQUENCE="false" PREVIOUS="introformat" NEXT="maxgrade"/>
-                <FIELD NAME="maxgrade" TYPE="float" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="version" NEXT="grademethod"/>
-                <FIELD NAME="grademethod" TYPE="int" LENGTH="2" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="maxgrade" NEXT="whatgrade"/>
-                <FIELD NAME="whatgrade" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="grademethod" NEXT="maxattempt"/>
-                <FIELD NAME="maxattempt" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="1" SEQUENCE="false" PREVIOUS="whatgrade" NEXT="forcecompleted"/>
-                <FIELD NAME="forcecompleted" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="1" SEQUENCE="false" PREVIOUS="maxattempt" NEXT="forcenewattempt"/>
-                <FIELD NAME="forcenewattempt" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="forcecompleted" NEXT="lastattemptlock"/>
-                <FIELD NAME="lastattemptlock" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="forcenewattempt" NEXT="displayattemptstatus"/>
-                <FIELD NAME="displayattemptstatus" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="1" SEQUENCE="false" PREVIOUS="lastattemptlock" NEXT="displaycoursestructure"/>
-                <FIELD NAME="displaycoursestructure" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="1" SEQUENCE="false" PREVIOUS="displayattemptstatus" NEXT="updatefreq"/>
-                <FIELD NAME="updatefreq" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Define when the package must be automatically update" PREVIOUS="displaycoursestructure" NEXT="sha1hash"/>
-                <FIELD NAME="sha1hash" TYPE="char" LENGTH="40" NOTNULL="false" SEQUENCE="false" COMMENT="package content or ext path hash" PREVIOUS="updatefreq" NEXT="md5hash"/>
-                <FIELD NAME="md5hash" TYPE="char" LENGTH="32" NOTNULL="true" SEQUENCE="false" COMMENT="MD5 Hash of package file" PREVIOUS="sha1hash" NEXT="revision"/>
-                <FIELD NAME="revision" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="revison number" PREVIOUS="md5hash" NEXT="launch"/>
-                <FIELD NAME="launch" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="revision" NEXT="skipview"/>
-                <FIELD NAME="skipview" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="1" SEQUENCE="false" PREVIOUS="launch" NEXT="hidebrowse"/>
-                <FIELD NAME="hidebrowse" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="skipview" NEXT="hidetoc"/>
-                <FIELD NAME="hidetoc" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="hidebrowse" NEXT="hidenav"/>
-                <FIELD NAME="hidenav" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="hidetoc" NEXT="auto"/>
-                <FIELD NAME="auto" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="hidenav" NEXT="popup"/>
-                <FIELD NAME="popup" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="auto" NEXT="options"/>
-                <FIELD NAME="options" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" PREVIOUS="popup" NEXT="width"/>
-                <FIELD NAME="width" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="100" SEQUENCE="false" PREVIOUS="options" NEXT="height"/>
-                <FIELD NAME="height" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="600" SEQUENCE="false" PREVIOUS="width" NEXT="timeopen"/>
-                <FIELD NAME="timeopen" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="height" NEXT="timeclose"/>
-                <FIELD NAME="timeclose" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="timeopen" NEXT="timemodified"/>
-                <FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="timeclose" NEXT="completionstatusrequired"/>
-                <FIELD NAME="completionstatusrequired" TYPE="int" LENGTH="1" NOTNULL="false" DEFAULT="null" SEQUENCE="false" PREVIOUS="timemodified" NEXT="completionscorerequired"/>
-                <FIELD NAME="completionscorerequired" TYPE="int" LENGTH="2" NOTNULL="false" DEFAULT="null" SEQUENCE="false" PREVIOUS="completionstatusrequired"/>
-            </FIELDS>
-            <KEYS>
-                <KEY NAME="primary" TYPE="primary" FIELDS="id"/>
-            </KEYS>
-            <INDEXES>
-                <INDEX NAME="course" UNIQUE="false" FIELDS="course"/>
-            </INDEXES>
-        </TABLE>
-        <TABLE NAME="scorm_scoes" COMMENT="each SCO part of the SCORM module" PREVIOUS="scorm" NEXT="scorm_scoes_data">
-            <FIELDS>
-                <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true" NEXT="scorm"/>
-                <FIELD NAME="scorm" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="id" NEXT="manifest"/>
-                <FIELD NAME="manifest" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" PREVIOUS="scorm" NEXT="organization"/>
-                <FIELD NAME="organization" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" PREVIOUS="manifest" NEXT="parent"/>
-                <FIELD NAME="parent" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" PREVIOUS="organization" NEXT="identifier"/>
-                <FIELD NAME="identifier" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" PREVIOUS="parent" NEXT="launch"/>
-                <FIELD NAME="launch" TYPE="text" NOTNULL="true" SEQUENCE="false" PREVIOUS="identifier" NEXT="scormtype"/>
-                <FIELD NAME="scormtype" TYPE="char" LENGTH="5" NOTNULL="true" SEQUENCE="false" PREVIOUS="launch" NEXT="title"/>
-                <FIELD NAME="title" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" PREVIOUS="scormtype"/>
-            </FIELDS>
-            <KEYS>
-                <KEY NAME="primary" TYPE="primary" FIELDS="id" NEXT="scorm"/>
-                <KEY NAME="scorm" TYPE="foreign" FIELDS="scorm" REFTABLE="scorm" REFFIELDS="id" PREVIOUS="primary"/>
-            </KEYS>
-        </TABLE>
-        <TABLE NAME="scorm_scoes_data" COMMENT="Contains variable data get from packages" PREVIOUS="scorm_scoes" NEXT="scorm_scoes_track">
-            <FIELDS>
-                <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true" NEXT="scoid"/>
-                <FIELD NAME="scoid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="id" NEXT="name"/>
-                <FIELD NAME="name" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" PREVIOUS="scoid" NEXT="value"/>
-                <FIELD NAME="value" TYPE="text" NOTNULL="true" SEQUENCE="false" PREVIOUS="name"/>
-            </FIELDS>
-            <KEYS>
-                <KEY NAME="primary" TYPE="primary" FIELDS="id" NEXT="scorm_scoes_data_scoid"/>
-                <KEY NAME="scorm_scoes_data_scoid" TYPE="foreign" FIELDS="scoid" REFTABLE="scorm_scoes" REFFIELDS="id" COMMENT="The relative sco" PREVIOUS="primary"/>
-            </KEYS>
-        </TABLE>
-        <TABLE NAME="scorm_scoes_track" COMMENT="to track SCOes" PREVIOUS="scorm_scoes_data" NEXT="scorm_seq_objective">
-            <FIELDS>
-                <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true" NEXT="userid"/>
-                <FIELD NAME="userid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="id" NEXT="scormid"/>
-                <FIELD NAME="scormid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="userid" NEXT="scoid"/>
-                <FIELD NAME="scoid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="scormid" NEXT="attempt"/>
-                <FIELD NAME="attempt" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="1" SEQUENCE="false" PREVIOUS="scoid" NEXT="element"/>
-                <FIELD NAME="element" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" PREVIOUS="attempt" NEXT="value"/>
-                <FIELD NAME="value" TYPE="text" NOTNULL="true" SEQUENCE="false" PREVIOUS="element" NEXT="timemodified"/>
-                <FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="value"/>
-            </FIELDS>
-            <KEYS>
-                <KEY NAME="primary" TYPE="primary" FIELDS="id" NEXT="scormid"/>
-                <KEY NAME="scormid" TYPE="foreign" FIELDS="scormid" REFTABLE="scorm" REFFIELDS="id" PREVIOUS="primary" NEXT="scoid"/>
-                <KEY NAME="scoid" TYPE="foreign" FIELDS="scoid" REFTABLE="scorm_scoes" REFFIELDS="id" PREVIOUS="scormid"/>
-            </KEYS>
-            <INDEXES>
-                <INDEX NAME="userid-scormid-scoid-attempt-element" UNIQUE="true" FIELDS="userid, scormid, scoid, attempt, element" NEXT="userid"/>
-                <INDEX NAME="userid" UNIQUE="false" FIELDS="userid" PREVIOUS="userid-scormid-scoid-attempt-element" NEXT="element"/>
-                <INDEX NAME="element" UNIQUE="false" FIELDS="element" PREVIOUS="userid"/>
-            </INDEXES>
-        </TABLE>
-        <TABLE NAME="scorm_seq_objective" COMMENT="SCORM2004 objective description" PREVIOUS="scorm_scoes_track" NEXT="scorm_seq_mapinfo">
-            <FIELDS>
-                <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true" NEXT="scoid"/>
-                <FIELD NAME="scoid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="id" NEXT="primaryobj"/>
-                <FIELD NAME="primaryobj" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="scoid" NEXT="objectiveid"/>
-                <FIELD NAME="objectiveid" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" PREVIOUS="primaryobj" NEXT="satisfiedbymeasure"/>
-                <FIELD NAME="satisfiedbymeasure" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="1" SEQUENCE="false" PREVIOUS="objectiveid" NEXT="minnormalizedmeasure"/>
-                <FIELD NAME="minnormalizedmeasure" TYPE="float" LENGTH="11" NOTNULL="true" DEFAULT="0.0000" SEQUENCE="false" DECIMALS="4" PREVIOUS="satisfiedbymeasure"/>
-            </FIELDS>
-            <KEYS>
-                <KEY NAME="primary" TYPE="primary" FIELDS="id" NEXT="scorm_objective_uniq"/>
-                <KEY NAME="scorm_objective_uniq" TYPE="unique" FIELDS="scoid, id" PREVIOUS="primary" NEXT="scorm_objective_scoid"/>
-                <KEY NAME="scorm_objective_scoid" TYPE="foreign" FIELDS="scoid" REFTABLE="scorm_scoes" REFFIELDS="id" COMMENT="The relative sco" PREVIOUS="scorm_objective_uniq"/>
-            </KEYS>
-        </TABLE>
-        <TABLE NAME="scorm_seq_mapinfo" COMMENT="SCORM2004 objective mapinfo description" PREVIOUS="scorm_seq_objective" NEXT="scorm_seq_ruleconds">
-            <FIELDS>
-                <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true" NEXT="scoid"/>
-                <FIELD NAME="scoid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="id" NEXT="objectiveid"/>
-                <FIELD NAME="objectiveid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="scoid" NEXT="targetobjectiveid"/>
-                <FIELD NAME="targetobjectiveid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="objectiveid" NEXT="readsatisfiedstatus"/>
-                <FIELD NAME="readsatisfiedstatus" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="1" SEQUENCE="false" PREVIOUS="targetobjectiveid" NEXT="readnormalizedmeasure"/>
-                <FIELD NAME="readnormalizedmeasure" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="1" SEQUENCE="false" PREVIOUS="readsatisfiedstatus" NEXT="writesatisfiedstatus"/>
-                <FIELD NAME="writesatisfiedstatus" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="readnormalizedmeasure" NEXT="writenormalizedmeasure"/>
-                <FIELD NAME="writenormalizedmeasure" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="writesatisfiedstatus"/>
-            </FIELDS>
-            <KEYS>
-                <KEY NAME="primary" TYPE="primary" FIELDS="id" NEXT="scorm_mapinfo_uniq"/>
-                <KEY NAME="scorm_mapinfo_uniq" TYPE="unique" FIELDS="scoid, id, objectiveid" PREVIOUS="primary" NEXT="scorm_mapinfo_scoid"/>
-                <KEY NAME="scorm_mapinfo_scoid" TYPE="foreign" FIELDS="scoid" REFTABLE="scorm_scoes" REFFIELDS="id" COMMENT="The relative sco" PREVIOUS="scorm_mapinfo_uniq" NEXT="scorm_mapinfo_objectiveid"/>
-                <KEY NAME="scorm_mapinfo_objectiveid" TYPE="foreign" FIELDS="objectiveid" REFTABLE="scorm_seq_objective" REFFIELDS="id" COMMENT="The relative objective" PREVIOUS="scorm_mapinfo_scoid"/>
-            </KEYS>
-        </TABLE>
-        <TABLE NAME="scorm_seq_ruleconds" COMMENT="SCORM2004 rule conditions" PREVIOUS="scorm_seq_mapinfo" NEXT="scorm_seq_rulecond">
-            <FIELDS>
-                <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true" NEXT="scoid"/>
-                <FIELD NAME="scoid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="id" NEXT="conditioncombination"/>
-                <FIELD NAME="conditioncombination" TYPE="char" LENGTH="3" NOTNULL="true" DEFAULT="all" SEQUENCE="false" PREVIOUS="scoid" NEXT="ruletype"/>
-                <FIELD NAME="ruletype" TYPE="int" LENGTH="2" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="conditioncombination" NEXT="action"/>
-                <FIELD NAME="action" TYPE="char" LENGTH="25" NOTNULL="true" SEQUENCE="false" PREVIOUS="ruletype"/>
-            </FIELDS>
-            <KEYS>
-                <KEY NAME="primary" TYPE="primary" FIELDS="id" NEXT="scorm_ruleconds_un"/>
-                <KEY NAME="scorm_ruleconds_un" TYPE="unique" FIELDS="scoid, id" PREVIOUS="primary" NEXT="scorm_ruleconds_scoid"/>
-                <KEY NAME="scorm_ruleconds_scoid" TYPE="foreign" FIELDS="scoid" REFTABLE="scorm_scoes" REFFIELDS="id" COMMENT="The relative sco" PREVIOUS="scorm_ruleconds_un"/>
-            </KEYS>
-        </TABLE>
-        <TABLE NAME="scorm_seq_rulecond" COMMENT="SCORM2004 rule condition" PREVIOUS="scorm_seq_ruleconds" NEXT="scorm_seq_rolluprule">
-            <FIELDS>
-                <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true" NEXT="scoid"/>
-                <FIELD NAME="scoid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="id" NEXT="ruleconditionsid"/>
-                <FIELD NAME="ruleconditionsid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="scoid" NEXT="refrencedobjective"/>
-                <FIELD NAME="refrencedobjective" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" PREVIOUS="ruleconditionsid" NEXT="measurethreshold"/>
-                <FIELD NAME="measurethreshold" TYPE="float" LENGTH="11" NOTNULL="true" DEFAULT="0.0000" SEQUENCE="false" DECIMALS="4" PREVIOUS="refrencedobjective" NEXT="operator"/>
-                <FIELD NAME="operator" TYPE="char" LENGTH="5" NOTNULL="true" DEFAULT="noOp" SEQUENCE="false" PREVIOUS="measurethreshold" NEXT="cond"/>
-                <FIELD NAME="cond" TYPE="char" LENGTH="30" NOTNULL="true" DEFAULT="always" SEQUENCE="false" PREVIOUS="operator"/>
-            </FIELDS>
-            <KEYS>
-                <KEY NAME="primary" TYPE="primary" FIELDS="id" NEXT="scorm_rulecond_uniq"/>
-                <KEY NAME="scorm_rulecond_uniq" TYPE="unique" FIELDS="id, scoid, ruleconditionsid" PREVIOUS="primary" NEXT="scorm_rulecond_scoid"/>
-                <KEY NAME="scorm_rulecond_scoid" TYPE="foreign" FIELDS="scoid" REFTABLE="scorm_scoes" REFFIELDS="id" COMMENT="The relative sco" PREVIOUS="scorm_rulecond_uniq" NEXT="scorm_rulecond_ruleconditionsid"/>
-                <KEY NAME="scorm_rulecond_ruleconditionsid" TYPE="foreign" FIELDS="ruleconditionsid" REFTABLE="scorm_seq_ruleconds" REFFIELDS="id" COMMENT="The relative rulecondition" PREVIOUS="scorm_rulecond_scoid"/>
-            </KEYS>
-        </TABLE>
-        <TABLE NAME="scorm_seq_rolluprule" COMMENT="SCORM2004 sequencing rule" PREVIOUS="scorm_seq_rulecond" NEXT="scorm_seq_rolluprulecond">
-            <FIELDS>
-                <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true" NEXT="scoid"/>
-                <FIELD NAME="scoid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="id" NEXT="childactivityset"/>
-                <FIELD NAME="childactivityset" TYPE="char" LENGTH="15" NOTNULL="true" SEQUENCE="false" PREVIOUS="scoid" NEXT="minimumcount"/>
-                <FIELD NAME="minimumcount" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="childactivityset" NEXT="minimumpercent"/>
-                <FIELD NAME="minimumpercent" TYPE="float" LENGTH="11" NOTNULL="true" DEFAULT="0.0000" SEQUENCE="false" DECIMALS="4" PREVIOUS="minimumcount" NEXT="conditioncombination"/>
-                <FIELD NAME="conditioncombination" TYPE="char" LENGTH="3" NOTNULL="true" DEFAULT="all" SEQUENCE="false" PREVIOUS="minimumpercent" NEXT="action"/>
-                <FIELD NAME="action" TYPE="char" LENGTH="15" NOTNULL="true" SEQUENCE="false" PREVIOUS="conditioncombination"/>
-            </FIELDS>
-            <KEYS>
-                <KEY NAME="primary" TYPE="primary" FIELDS="id" NEXT="scorm_rolluprule_uniq"/>
-                <KEY NAME="scorm_rolluprule_uniq" TYPE="unique" FIELDS="scoid, id" PREVIOUS="primary" NEXT="scorm_rolluprule_scoid"/>
-                <KEY NAME="scorm_rolluprule_scoid" TYPE="foreign" FIELDS="scoid" REFTABLE="scorm_scoes" REFFIELDS="id" COMMENT="The relative sco" PREVIOUS="scorm_rolluprule_uniq"/>
-            </KEYS>
-        </TABLE>
-        <TABLE NAME="scorm_seq_rolluprulecond" COMMENT="SCORM2004 sequencing rule" PREVIOUS="scorm_seq_rolluprule" NEXT="scorm_aicc_session">
-            <FIELDS>
-                <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true" NEXT="scoid"/>
-                <FIELD NAME="scoid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="id" NEXT="rollupruleid"/>
-                <FIELD NAME="rollupruleid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="scoid" NEXT="operator"/>
-                <FIELD NAME="operator" TYPE="char" LENGTH="5" NOTNULL="true" DEFAULT="noOp" SEQUENCE="false" PREVIOUS="rollupruleid" NEXT="cond"/>
-                <FIELD NAME="cond" TYPE="char" LENGTH="25" NOTNULL="true" SEQUENCE="false" PREVIOUS="operator"/>
-            </FIELDS>
-            <KEYS>
-                <KEY NAME="primary" TYPE="primary" FIELDS="id" NEXT="scorm_rulluprulecond_uniq"/>
-                <KEY NAME="scorm_rulluprulecond_uniq" TYPE="unique" FIELDS="scoid, rollupruleid, id" PREVIOUS="primary" NEXT="scorm_rolluprulecond_scoid"/>
-                <KEY NAME="scorm_rolluprulecond_scoid" TYPE="foreign" FIELDS="scoid" REFTABLE="scorm_scoes" REFFIELDS="id" COMMENT="The relative sco" PREVIOUS="scorm_rulluprulecond_uniq" NEXT="scorm_rolluprulecond_rolluprule"/>
-                <KEY NAME="scorm_rolluprulecond_rolluprule" TYPE="foreign" FIELDS="rollupruleid" REFTABLE="scorm_seq_rolluprule" REFFIELDS="id" COMMENT="The relative rolluprule" PREVIOUS="scorm_rolluprulecond_scoid"/>
-            </KEYS>
-        </TABLE>
-        <TABLE NAME="scorm_aicc_session" COMMENT="Used by AICC HACP to store session information" PREVIOUS="scorm_seq_rolluprulecond">
-            <FIELDS>
-                <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true" NEXT="userid"/>
-                <FIELD NAME="userid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="id from user table" PREVIOUS="id" NEXT="scormid"/>
-                <FIELD NAME="scormid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="id from scorm table" PREVIOUS="userid" NEXT="hacpsession"/>
-                <FIELD NAME="hacpsession" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" COMMENT="sessionid used to authenticate AICC HACP communication" PREVIOUS="scormid" NEXT="scoid"/>
-                <FIELD NAME="scoid" TYPE="int" LENGTH="10" NOTNULL="false" DEFAULT="0" SEQUENCE="false" COMMENT="id from scorm_scoes table" PREVIOUS="hacpsession" NEXT="scormmode"/>
-                <FIELD NAME="scormmode" TYPE="char" LENGTH="50" NOTNULL="false" SEQUENCE="false" PREVIOUS="scoid" NEXT="scormstatus"/>
-                <FIELD NAME="scormstatus" TYPE="char" LENGTH="255" NOTNULL="false" SEQUENCE="false" PREVIOUS="scormmode" NEXT="attempt"/>
-                <FIELD NAME="attempt" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false" PREVIOUS="scormstatus" NEXT="lessonstatus"/>
-                <FIELD NAME="lessonstatus" TYPE="char" LENGTH="255" NOTNULL="false" SEQUENCE="false" PREVIOUS="attempt" NEXT="sessiontime"/>
-                <FIELD NAME="sessiontime" TYPE="char" LENGTH="255" NOTNULL="false" SEQUENCE="false" PREVIOUS="lessonstatus" NEXT="timecreated"/>
-                <FIELD NAME="timecreated" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="time this session was created" PREVIOUS="sessiontime" NEXT="timemodified"/>
-                <FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="time this session was last used" PREVIOUS="timecreated"/>
-            </FIELDS>
-            <KEYS>
-                <KEY NAME="primary" TYPE="primary" FIELDS="id" NEXT="scormid"/>
-                <KEY NAME="scormid" TYPE="foreign" FIELDS="scormid" REFTABLE="scorm" REFFIELDS="id" PREVIOUS="primary" NEXT="userid"/>
-                <KEY NAME="userid" TYPE="foreign" FIELDS="userid" REFTABLE="user" REFFIELDS="id" PREVIOUS="scormid"/>
-            </KEYS>
-        </TABLE>
-    </TABLES>
+<XMLDB PATH="mod/scorm/db" VERSION="20120326" COMMENT="XMLDB file for Moodle mod/scorm"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:noNamespaceSchemaLocation="../../../lib/xmldb/xmldb.xsd"
+>
+  <TABLES>
+    <TABLE NAME="scorm" COMMENT="each table is one SCORM module and its configuration" NEXT="scorm_scoes">
+      <FIELDS>
+        <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true" NEXT="course"/>
+        <FIELD NAME="course" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="id" NEXT="name"/>
+        <FIELD NAME="name" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" PREVIOUS="course" NEXT="scormtype"/>
+        <FIELD NAME="scormtype" TYPE="char" LENGTH="50" NOTNULL="true" DEFAULT="local" SEQUENCE="false" COMMENT="local, external or repository" PREVIOUS="name" NEXT="reference"/>
+        <FIELD NAME="reference" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" PREVIOUS="scormtype" NEXT="intro"/>
+        <FIELD NAME="intro" TYPE="text" NOTNULL="true" SEQUENCE="false" PREVIOUS="reference" NEXT="introformat"/>
+        <FIELD NAME="introformat" TYPE="int" LENGTH="4" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="intro" NEXT="version"/>
+        <FIELD NAME="version" TYPE="char" LENGTH="9" NOTNULL="true" SEQUENCE="false" PREVIOUS="introformat" NEXT="maxgrade"/>
+        <FIELD NAME="maxgrade" TYPE="float" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="version" NEXT="grademethod"/>
+        <FIELD NAME="grademethod" TYPE="int" LENGTH="2" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="maxgrade" NEXT="whatgrade"/>
+        <FIELD NAME="whatgrade" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="grademethod" NEXT="maxattempt"/>
+        <FIELD NAME="maxattempt" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="1" SEQUENCE="false" PREVIOUS="whatgrade" NEXT="forcecompleted"/>
+        <FIELD NAME="forcecompleted" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="1" SEQUENCE="false" PREVIOUS="maxattempt" NEXT="forcenewattempt"/>
+        <FIELD NAME="forcenewattempt" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="forcecompleted" NEXT="lastattemptlock"/>
+        <FIELD NAME="lastattemptlock" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="forcenewattempt" NEXT="displayattemptstatus"/>
+        <FIELD NAME="displayattemptstatus" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="1" SEQUENCE="false" PREVIOUS="lastattemptlock" NEXT="displaycoursestructure"/>
+        <FIELD NAME="displaycoursestructure" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="1" SEQUENCE="false" PREVIOUS="displayattemptstatus" NEXT="updatefreq"/>
+        <FIELD NAME="updatefreq" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Define when the package must be automatically update" PREVIOUS="displaycoursestructure" NEXT="sha1hash"/>
+        <FIELD NAME="sha1hash" TYPE="char" LENGTH="40" NOTNULL="false" SEQUENCE="false" COMMENT="package content or ext path hash" PREVIOUS="updatefreq" NEXT="md5hash"/>
+        <FIELD NAME="md5hash" TYPE="char" LENGTH="32" NOTNULL="true" SEQUENCE="false" COMMENT="MD5 Hash of package file" PREVIOUS="sha1hash" NEXT="revision"/>
+        <FIELD NAME="revision" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="revison number" PREVIOUS="md5hash" NEXT="launch"/>
+        <FIELD NAME="launch" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="revision" NEXT="skipview"/>
+        <FIELD NAME="skipview" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="1" SEQUENCE="false" PREVIOUS="launch" NEXT="hidebrowse"/>
+        <FIELD NAME="hidebrowse" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="skipview" NEXT="hidetoc"/>
+        <FIELD NAME="hidetoc" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="hidebrowse" NEXT="hidenav"/>
+        <FIELD NAME="hidenav" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="hidetoc" NEXT="auto"/>
+        <FIELD NAME="auto" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="hidenav" NEXT="popup"/>
+        <FIELD NAME="popup" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="auto" NEXT="options"/>
+        <FIELD NAME="options" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" PREVIOUS="popup" NEXT="width"/>
+        <FIELD NAME="width" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="100" SEQUENCE="false" PREVIOUS="options" NEXT="height"/>
+        <FIELD NAME="height" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="600" SEQUENCE="false" PREVIOUS="width" NEXT="timeopen"/>
+        <FIELD NAME="timeopen" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="height" NEXT="timeclose"/>
+        <FIELD NAME="timeclose" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="timeopen" NEXT="timemodified"/>
+        <FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="timeclose" NEXT="completionstatusrequired"/>
+        <FIELD NAME="completionstatusrequired" TYPE="int" LENGTH="1" NOTNULL="false" SEQUENCE="false" PREVIOUS="timemodified" NEXT="completionscorerequired"/>
+        <FIELD NAME="completionscorerequired" TYPE="int" LENGTH="2" NOTNULL="false" SEQUENCE="false" PREVIOUS="completionstatusrequired"/>
+      </FIELDS>
+      <KEYS>
+        <KEY NAME="primary" TYPE="primary" FIELDS="id"/>
+      </KEYS>
+      <INDEXES>
+        <INDEX NAME="course" UNIQUE="false" FIELDS="course"/>
+      </INDEXES>
+    </TABLE>
+    <TABLE NAME="scorm_scoes" COMMENT="each SCO part of the SCORM module" PREVIOUS="scorm" NEXT="scorm_scoes_data">
+      <FIELDS>
+        <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true" NEXT="scorm"/>
+        <FIELD NAME="scorm" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="id" NEXT="manifest"/>
+        <FIELD NAME="manifest" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" PREVIOUS="scorm" NEXT="organization"/>
+        <FIELD NAME="organization" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" PREVIOUS="manifest" NEXT="parent"/>
+        <FIELD NAME="parent" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" PREVIOUS="organization" NEXT="identifier"/>
+        <FIELD NAME="identifier" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" PREVIOUS="parent" NEXT="launch"/>
+        <FIELD NAME="launch" TYPE="text" NOTNULL="true" SEQUENCE="false" PREVIOUS="identifier" NEXT="scormtype"/>
+        <FIELD NAME="scormtype" TYPE="char" LENGTH="5" NOTNULL="true" SEQUENCE="false" PREVIOUS="launch" NEXT="title"/>
+        <FIELD NAME="title" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" PREVIOUS="scormtype"/>
+      </FIELDS>
+      <KEYS>
+        <KEY NAME="primary" TYPE="primary" FIELDS="id" NEXT="scorm"/>
+        <KEY NAME="scorm" TYPE="foreign" FIELDS="scorm" REFTABLE="scorm" REFFIELDS="id" PREVIOUS="primary"/>
+      </KEYS>
+    </TABLE>
+    <TABLE NAME="scorm_scoes_data" COMMENT="Contains variable data get from packages" PREVIOUS="scorm_scoes" NEXT="scorm_scoes_track">
+      <FIELDS>
+        <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true" NEXT="scoid"/>
+        <FIELD NAME="scoid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="id" NEXT="name"/>
+        <FIELD NAME="name" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" PREVIOUS="scoid" NEXT="value"/>
+        <FIELD NAME="value" TYPE="text" NOTNULL="true" SEQUENCE="false" PREVIOUS="name"/>
+      </FIELDS>
+      <KEYS>
+        <KEY NAME="primary" TYPE="primary" FIELDS="id" NEXT="scorm_scoes_data_scoid"/>
+        <KEY NAME="scorm_scoes_data_scoid" TYPE="foreign" FIELDS="scoid" REFTABLE="scorm_scoes" REFFIELDS="id" COMMENT="The relative sco" PREVIOUS="primary"/>
+      </KEYS>
+    </TABLE>
+    <TABLE NAME="scorm_scoes_track" COMMENT="to track SCOes" PREVIOUS="scorm_scoes_data" NEXT="scorm_seq_objective">
+      <FIELDS>
+        <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true" NEXT="userid"/>
+        <FIELD NAME="userid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="id" NEXT="scormid"/>
+        <FIELD NAME="scormid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="userid" NEXT="scoid"/>
+        <FIELD NAME="scoid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="scormid" NEXT="attempt"/>
+        <FIELD NAME="attempt" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="1" SEQUENCE="false" PREVIOUS="scoid" NEXT="element"/>
+        <FIELD NAME="element" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" PREVIOUS="attempt" NEXT="value"/>
+        <FIELD NAME="value" TYPE="text" NOTNULL="true" SEQUENCE="false" PREVIOUS="element" NEXT="timemodified"/>
+        <FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="value"/>
+      </FIELDS>
+      <KEYS>
+        <KEY NAME="primary" TYPE="primary" FIELDS="id" NEXT="scormid"/>
+        <KEY NAME="scormid" TYPE="foreign" FIELDS="scormid" REFTABLE="scorm" REFFIELDS="id" PREVIOUS="primary" NEXT="scoid"/>
+        <KEY NAME="scoid" TYPE="foreign" FIELDS="scoid" REFTABLE="scorm_scoes" REFFIELDS="id" PREVIOUS="scormid"/>
+      </KEYS>
+      <INDEXES>
+        <INDEX NAME="userid-scormid-scoid-attempt-element" UNIQUE="true" FIELDS="userid, scormid, scoid, attempt, element" NEXT="userid"/>
+        <INDEX NAME="userid" UNIQUE="false" FIELDS="userid" PREVIOUS="userid-scormid-scoid-attempt-element" NEXT="element"/>
+        <INDEX NAME="element" UNIQUE="false" FIELDS="element" PREVIOUS="userid"/>
+      </INDEXES>
+    </TABLE>
+    <TABLE NAME="scorm_seq_objective" COMMENT="SCORM2004 objective description" PREVIOUS="scorm_scoes_track" NEXT="scorm_seq_mapinfo">
+      <FIELDS>
+        <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true" NEXT="scoid"/>
+        <FIELD NAME="scoid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="id" NEXT="primaryobj"/>
+        <FIELD NAME="primaryobj" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="scoid" NEXT="objectiveid"/>
+        <FIELD NAME="objectiveid" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" PREVIOUS="primaryobj" NEXT="satisfiedbymeasure"/>
+        <FIELD NAME="satisfiedbymeasure" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="1" SEQUENCE="false" PREVIOUS="objectiveid" NEXT="minnormalizedmeasure"/>
+        <FIELD NAME="minnormalizedmeasure" TYPE="float" LENGTH="11" NOTNULL="true" DEFAULT="0.0000" SEQUENCE="false" DECIMALS="4" PREVIOUS="satisfiedbymeasure"/>
+      </FIELDS>
+      <KEYS>
+        <KEY NAME="primary" TYPE="primary" FIELDS="id" NEXT="scorm_objective_uniq"/>
+        <KEY NAME="scorm_objective_uniq" TYPE="unique" FIELDS="scoid, id" PREVIOUS="primary" NEXT="scorm_objective_scoid"/>
+        <KEY NAME="scorm_objective_scoid" TYPE="foreign" FIELDS="scoid" REFTABLE="scorm_scoes" REFFIELDS="id" COMMENT="The relative sco" PREVIOUS="scorm_objective_uniq"/>
+      </KEYS>
+    </TABLE>
+    <TABLE NAME="scorm_seq_mapinfo" COMMENT="SCORM2004 objective mapinfo description" PREVIOUS="scorm_seq_objective" NEXT="scorm_seq_ruleconds">
+      <FIELDS>
+        <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true" NEXT="scoid"/>
+        <FIELD NAME="scoid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="id" NEXT="objectiveid"/>
+        <FIELD NAME="objectiveid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="scoid" NEXT="targetobjectiveid"/>
+        <FIELD NAME="targetobjectiveid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="objectiveid" NEXT="readsatisfiedstatus"/>
+        <FIELD NAME="readsatisfiedstatus" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="1" SEQUENCE="false" PREVIOUS="targetobjectiveid" NEXT="readnormalizedmeasure"/>
+        <FIELD NAME="readnormalizedmeasure" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="1" SEQUENCE="false" PREVIOUS="readsatisfiedstatus" NEXT="writesatisfiedstatus"/>
+        <FIELD NAME="writesatisfiedstatus" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="readnormalizedmeasure" NEXT="writenormalizedmeasure"/>
+        <FIELD NAME="writenormalizedmeasure" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="writesatisfiedstatus"/>
+      </FIELDS>
+      <KEYS>
+        <KEY NAME="primary" TYPE="primary" FIELDS="id" NEXT="scorm_mapinfo_uniq"/>
+        <KEY NAME="scorm_mapinfo_uniq" TYPE="unique" FIELDS="scoid, id, objectiveid" PREVIOUS="primary" NEXT="scorm_mapinfo_scoid"/>
+        <KEY NAME="scorm_mapinfo_scoid" TYPE="foreign" FIELDS="scoid" REFTABLE="scorm_scoes" REFFIELDS="id" COMMENT="The relative sco" PREVIOUS="scorm_mapinfo_uniq" NEXT="scorm_mapinfo_objectiveid"/>
+        <KEY NAME="scorm_mapinfo_objectiveid" TYPE="foreign" FIELDS="objectiveid" REFTABLE="scorm_seq_objective" REFFIELDS="id" COMMENT="The relative objective" PREVIOUS="scorm_mapinfo_scoid"/>
+      </KEYS>
+    </TABLE>
+    <TABLE NAME="scorm_seq_ruleconds" COMMENT="SCORM2004 rule conditions" PREVIOUS="scorm_seq_mapinfo" NEXT="scorm_seq_rulecond">
+      <FIELDS>
+        <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true" NEXT="scoid"/>
+        <FIELD NAME="scoid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="id" NEXT="conditioncombination"/>
+        <FIELD NAME="conditioncombination" TYPE="char" LENGTH="3" NOTNULL="true" DEFAULT="all" SEQUENCE="false" PREVIOUS="scoid" NEXT="ruletype"/>
+        <FIELD NAME="ruletype" TYPE="int" LENGTH="2" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="conditioncombination" NEXT="action"/>
+        <FIELD NAME="action" TYPE="char" LENGTH="25" NOTNULL="true" SEQUENCE="false" PREVIOUS="ruletype"/>
+      </FIELDS>
+      <KEYS>
+        <KEY NAME="primary" TYPE="primary" FIELDS="id" NEXT="scorm_ruleconds_un"/>
+        <KEY NAME="scorm_ruleconds_un" TYPE="unique" FIELDS="scoid, id" PREVIOUS="primary" NEXT="scorm_ruleconds_scoid"/>
+        <KEY NAME="scorm_ruleconds_scoid" TYPE="foreign" FIELDS="scoid" REFTABLE="scorm_scoes" REFFIELDS="id" COMMENT="The relative sco" PREVIOUS="scorm_ruleconds_un"/>
+      </KEYS>
+    </TABLE>
+    <TABLE NAME="scorm_seq_rulecond" COMMENT="SCORM2004 rule condition" PREVIOUS="scorm_seq_ruleconds" NEXT="scorm_seq_rolluprule">
+      <FIELDS>
+        <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true" NEXT="scoid"/>
+        <FIELD NAME="scoid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="id" NEXT="ruleconditionsid"/>
+        <FIELD NAME="ruleconditionsid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="scoid" NEXT="refrencedobjective"/>
+        <FIELD NAME="refrencedobjective" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" PREVIOUS="ruleconditionsid" NEXT="measurethreshold"/>
+        <FIELD NAME="measurethreshold" TYPE="float" LENGTH="11" NOTNULL="true" DEFAULT="0.0000" SEQUENCE="false" DECIMALS="4" PREVIOUS="refrencedobjective" NEXT="operator"/>
+        <FIELD NAME="operator" TYPE="char" LENGTH="5" NOTNULL="true" DEFAULT="noOp" SEQUENCE="false" PREVIOUS="measurethreshold" NEXT="cond"/>
+        <FIELD NAME="cond" TYPE="char" LENGTH="30" NOTNULL="true" DEFAULT="always" SEQUENCE="false" PREVIOUS="operator"/>
+      </FIELDS>
+      <KEYS>
+        <KEY NAME="primary" TYPE="primary" FIELDS="id" NEXT="scorm_rulecond_uniq"/>
+        <KEY NAME="scorm_rulecond_uniq" TYPE="unique" FIELDS="id, scoid, ruleconditionsid" PREVIOUS="primary" NEXT="scorm_rulecond_scoid"/>
+        <KEY NAME="scorm_rulecond_scoid" TYPE="foreign" FIELDS="scoid" REFTABLE="scorm_scoes" REFFIELDS="id" COMMENT="The relative sco" PREVIOUS="scorm_rulecond_uniq" NEXT="scorm_rulecond_ruleconditionsid"/>
+        <KEY NAME="scorm_rulecond_ruleconditionsid" TYPE="foreign" FIELDS="ruleconditionsid" REFTABLE="scorm_seq_ruleconds" REFFIELDS="id" COMMENT="The relative rulecondition" PREVIOUS="scorm_rulecond_scoid"/>
+      </KEYS>
+    </TABLE>
+    <TABLE NAME="scorm_seq_rolluprule" COMMENT="SCORM2004 sequencing rule" PREVIOUS="scorm_seq_rulecond" NEXT="scorm_seq_rolluprulecond">
+      <FIELDS>
+        <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true" NEXT="scoid"/>
+        <FIELD NAME="scoid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="id" NEXT="childactivityset"/>
+        <FIELD NAME="childactivityset" TYPE="char" LENGTH="15" NOTNULL="true" SEQUENCE="false" PREVIOUS="scoid" NEXT="minimumcount"/>
+        <FIELD NAME="minimumcount" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="childactivityset" NEXT="minimumpercent"/>
+        <FIELD NAME="minimumpercent" TYPE="float" LENGTH="11" NOTNULL="true" DEFAULT="0.0000" SEQUENCE="false" DECIMALS="4" PREVIOUS="minimumcount" NEXT="conditioncombination"/>
+        <FIELD NAME="conditioncombination" TYPE="char" LENGTH="3" NOTNULL="true" DEFAULT="all" SEQUENCE="false" PREVIOUS="minimumpercent" NEXT="action"/>
+        <FIELD NAME="action" TYPE="char" LENGTH="15" NOTNULL="true" SEQUENCE="false" PREVIOUS="conditioncombination"/>
+      </FIELDS>
+      <KEYS>
+        <KEY NAME="primary" TYPE="primary" FIELDS="id" NEXT="scorm_rolluprule_uniq"/>
+        <KEY NAME="scorm_rolluprule_uniq" TYPE="unique" FIELDS="scoid, id" PREVIOUS="primary" NEXT="scorm_rolluprule_scoid"/>
+        <KEY NAME="scorm_rolluprule_scoid" TYPE="foreign" FIELDS="scoid" REFTABLE="scorm_scoes" REFFIELDS="id" COMMENT="The relative sco" PREVIOUS="scorm_rolluprule_uniq"/>
+      </KEYS>
+    </TABLE>
+    <TABLE NAME="scorm_seq_rolluprulecond" COMMENT="SCORM2004 sequencing rule" PREVIOUS="scorm_seq_rolluprule" NEXT="scorm_aicc_session">
+      <FIELDS>
+        <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true" NEXT="scoid"/>
+        <FIELD NAME="scoid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="id" NEXT="rollupruleid"/>
+        <FIELD NAME="rollupruleid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="scoid" NEXT="operator"/>
+        <FIELD NAME="operator" TYPE="char" LENGTH="5" NOTNULL="true" DEFAULT="noOp" SEQUENCE="false" PREVIOUS="rollupruleid" NEXT="cond"/>
+        <FIELD NAME="cond" TYPE="char" LENGTH="25" NOTNULL="true" SEQUENCE="false" PREVIOUS="operator"/>
+      </FIELDS>
+      <KEYS>
+        <KEY NAME="primary" TYPE="primary" FIELDS="id" NEXT="scorm_rulluprulecond_uniq"/>
+        <KEY NAME="scorm_rulluprulecond_uniq" TYPE="unique" FIELDS="scoid, rollupruleid, id" PREVIOUS="primary" NEXT="scorm_rolluprulecond_scoid"/>
+        <KEY NAME="scorm_rolluprulecond_scoid" TYPE="foreign" FIELDS="scoid" REFTABLE="scorm_scoes" REFFIELDS="id" COMMENT="The relative sco" PREVIOUS="scorm_rulluprulecond_uniq" NEXT="scorm_rolluprulecond_rolluprule"/>
+        <KEY NAME="scorm_rolluprulecond_rolluprule" TYPE="foreign" FIELDS="rollupruleid" REFTABLE="scorm_seq_rolluprule" REFFIELDS="id" COMMENT="The relative rolluprule" PREVIOUS="scorm_rolluprulecond_scoid"/>
+      </KEYS>
+    </TABLE>
+    <TABLE NAME="scorm_aicc_session" COMMENT="Used by AICC HACP to store session information" PREVIOUS="scorm_seq_rolluprulecond">
+      <FIELDS>
+        <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true" NEXT="userid"/>
+        <FIELD NAME="userid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="id from user table" PREVIOUS="id" NEXT="scormid"/>
+        <FIELD NAME="scormid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="id from scorm table" PREVIOUS="userid" NEXT="hacpsession"/>
+        <FIELD NAME="hacpsession" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" COMMENT="sessionid used to authenticate AICC HACP communication" PREVIOUS="scormid" NEXT="scoid"/>
+        <FIELD NAME="scoid" TYPE="int" LENGTH="10" NOTNULL="false" DEFAULT="0" SEQUENCE="false" COMMENT="id from scorm_scoes table" PREVIOUS="hacpsession" NEXT="scormmode"/>
+        <FIELD NAME="scormmode" TYPE="char" LENGTH="50" NOTNULL="false" SEQUENCE="false" PREVIOUS="scoid" NEXT="scormstatus"/>
+        <FIELD NAME="scormstatus" TYPE="char" LENGTH="255" NOTNULL="false" SEQUENCE="false" PREVIOUS="scormmode" NEXT="attempt"/>
+        <FIELD NAME="attempt" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false" PREVIOUS="scormstatus" NEXT="lessonstatus"/>
+        <FIELD NAME="lessonstatus" TYPE="char" LENGTH="255" NOTNULL="false" SEQUENCE="false" PREVIOUS="attempt" NEXT="sessiontime"/>
+        <FIELD NAME="sessiontime" TYPE="char" LENGTH="255" NOTNULL="false" SEQUENCE="false" PREVIOUS="lessonstatus" NEXT="timecreated"/>
+        <FIELD NAME="timecreated" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="time this session was created" PREVIOUS="sessiontime" NEXT="timemodified"/>
+        <FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="time this session was last used" PREVIOUS="timecreated"/>
+      </FIELDS>
+      <KEYS>
+        <KEY NAME="primary" TYPE="primary" FIELDS="id" NEXT="scormid"/>
+        <KEY NAME="scormid" TYPE="foreign" FIELDS="scormid" REFTABLE="scorm" REFFIELDS="id" PREVIOUS="primary" NEXT="userid"/>
+        <KEY NAME="userid" TYPE="foreign" FIELDS="userid" REFTABLE="user" REFFIELDS="id" PREVIOUS="scormid"/>
+      </KEYS>
+    </TABLE>
+  </TABLES>
 </XMLDB>
\ No newline at end of file
index 15b7b44..901433b 100644 (file)
@@ -960,6 +960,10 @@ function scorm_pluginfile($course, $cm, $context, $filearea, $args, $forcedownlo
 
     $fs = get_file_storage();
     if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) {
+        if ($filearea === 'content') { //return file not found straight away to improve performance.
+            send_header_404();
+            die;
+        }
         return false;
     }
 
index fe38c21..ef37f94 100644 (file)
@@ -24,7 +24,6 @@
 #page-mod-scorm-view .structurelist  {list-style-type: none;white-space: nowrap;}
 
 #page-mod-scorm-player #altfinishlink {font-size: 140%;border: 0px; padding: 0px; }
-#page-mod-scorm-player #altpopuplink  {position: left; padding: 5px; border: 0px; }
 #page-mod-scorm-player #scormmode  {float: left; border: 0px; }
 #page-mod-scorm-player.pagelayout-popup #page-content .region-content {padding: 0px; }
 #page-mod-scorm-player.pagelayout-popup #page-wrapper {width:100%;}
index a0c80c4..f01e2d5 100644 (file)
@@ -431,7 +431,8 @@ abstract class question_edit_form extends question_wizard_form {
         if (!empty($question->questiontext)) {
             $questiontext = $question->questiontext;
         } else {
-            $questiontext = '';
+            $questiontext = $this->_form->getElement('questiontext')->getValue();
+            $questiontext = $questiontext['text'];
         }
         $questiontext = file_prepare_draft_area($draftid, $this->context->id,
                 'question', 'questiontext', empty($question->id) ? null : (int) $question->id,
@@ -447,7 +448,8 @@ abstract class question_edit_form extends question_wizard_form {
         $draftid = file_get_submitted_draft_itemid('generalfeedback');
 
         if (empty($question->generalfeedback)) {
-            $question->generalfeedback = '';
+            $generalfeedback = $this->_form->getElement('generalfeedback')->getValue();
+            $question->generalfeedback = $generalfeedback['text'];
         }
 
         $feedback = file_prepare_draft_area($draftid, $this->context->id,
index eb42816..cfdb62b 100644 (file)
@@ -370,4 +370,15 @@ h2.headingblock {
     float: right;
 }
 
-.pagelayout-redirect {background-position:0 0;}
+.pagelayout-redirect {
+    background-position:0 0;
+}
+
+#page-mod-assignment-submissions #wrapper {
+    padding: 0 1%;
+}
+
+#page-mod-assignment-submissions #attempts td,
+#page-mod-assignment-submissions #attempts th.header {
+    font-size: 80%;
+}
index 1d25f42..08a5196 100644 (file)
 
                     $row->cells[2]->text .= implode('', $links);
 
-                    if (!empty($messageselect)) {
-                        $row->cells[2]->text .= '<br /><input type="checkbox" name="user'.$user->id.'" /> ';
+                    if ($bulkoperations) {
+                        $row->cells[2]->text .= '<br /><input type="checkbox" class="usercheckbox" name="user'.$user->id.'" /> ';
                     }
                     $table->data = array($row);
                     echo html_writer::table($table);