Merge branch 'w31_MDL-27597_m22_catlike' of git://github.com/skodak/moodle
authorEloy Lafuente (stronk7) <stronk7@moodle.org>
Wed, 10 Aug 2011 00:34:51 +0000 (02:34 +0200)
committerEloy Lafuente (stronk7) <stronk7@moodle.org>
Wed, 10 Aug 2011 00:34:51 +0000 (02:34 +0200)
50 files changed:
admin/cli/install.php
admin/cli/install_database.php
admin/cron.php
admin/index.php
admin/settings/server.php
backup/moodle2/restore_stepslib.php
backup/util/helper/backup_cron_helper.class.php
blocks/rss_client/editfeed.php
calendar/preferences.php
cohort/index.php
install.php
lang/en/moodle.org.php
lang/en/moodle.php
lib/db/upgrade.php
lib/dml/moodle_database.php
lib/dml/pgsql_native_moodle_database.php
lib/filebrowser/file_info_context_course.php
lib/filebrowser/file_info_context_module.php
lib/grouplib.php
lib/javascript-static.js
lib/moodlelib.php
lib/sessionlib.php
lib/simpletest/portfolio_testclass.php
lib/simpletest/testrepositorylib.php
lib/weblib.php
mod/assignment/simpletest/test_assignment_portfolio_callers.php
mod/chat/simpletest/test_chat_portfolio_callers.php
mod/data/simpletest/test_data_portfolio_callers.php
mod/forum/simpletest/test_forum_portfolio_callers.php
mod/glossary/simpletest/test_glossary_portfolio_callers.php
mod/quiz/edit.php
mod/quiz/editlib.php
mod/quiz/lib.php
mod/quiz/report/statistics/responseanalysis.php
mod/quiz/review.php
mod/scorm/datamodels/scormlib.php
mod/scorm/db/upgrade.php
mod/scorm/lang/en/scorm.php
mod/scorm/rd.js [deleted file]
portfolio/boxnet/simpletest/testportfoliopluginboxnet.php
question/edit.php
question/editlib.php
question/type/edit_question_form.php
question/type/match/questiontype.php
question/type/multichoice/backup/moodle2/backup_qtype_multichoice_plugin.class.php
question/type/multichoice/questiontype.php
question/type/questionbase.php
question/type/questiontypebase.php
theme/formal_white/style/formal_white.css
theme/yui_combo.php

index 1c37f54..0dd5102 100644 (file)
@@ -115,12 +115,12 @@ if (function_exists('date_default_timezone_set') and function_exists('date_defau
 define('MOODLE_INTERNAL', true);
 
 // Check that PHP is of a sufficient version
-if (version_compare(phpversion(), "5.2.8") < 0) {
+if (version_compare(phpversion(), "5.3.2") < 0) {
     $phpversion = phpversion();
     // do NOT localise - lang strings would not work here and we CAN NOT move it after installib
-    echo "Sorry, Moodle 2.0 requires PHP 5.2.8 or later (currently using version $phpversion).\n";
-    echo "Please upgrade your server software or install latest Moodle 1.9.x instead.";
-    die;
+    fwrite(STDERR, "Moodle 2.1 or later requires at least PHP 5.3.2 (currently using version $phpversion).\n");
+    fwrite(STDERR, "Please upgrade your server software or install older Moodle version.\n");
+    exit(1);
 }
 
 // set up configuration
index 9e55c9c..44412ec 100644 (file)
@@ -55,12 +55,12 @@ Example:
 ";
 
 // Check that PHP is of a sufficient version
-if (version_compare(phpversion(), "5.2.8") < 0) {
+if (version_compare(phpversion(), "5.3.2") < 0) {
     $phpversion = phpversion();
     // do NOT localise - lang strings would not work here and we CAN NOT move it after installib
-    fwrite(STDERR, "Sorry, Moodle 2.0 requires PHP 5.2.8 or later (currently using version $phpversion).\n");
-    fwrite(STDERR, "Please upgrade your server software or install latest Moodle 1.9.x instead.\n");
-    die(1);
+    fwrite(STDERR, "Moodle 2.1 or later requires at least PHP 5.3.2 (currently using version $phpversion).\n");
+    fwrite(STDERR, "Please upgrade your server software or install older Moodle version.\n");
+    exit(1);
 }
 
 // Nothing to do if config.php does not exist
@@ -68,7 +68,7 @@ $configfile = dirname(dirname(dirname(__FILE__))).'/config.php';
 if (!file_exists($configfile)) {
     fwrite(STDERR, 'config.php does not exist, can not continue'); // do not localize
     fwrite(STDERR, "\n");
-    die(1);
+    exit(1);
 }
 
 // Include necessary libs
index e131e9b..5b473a3 100644 (file)
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
+
+if (defined('STDIN')) {
+    fwrite(STDERR, "ERROR: This script no longer supports CLI, please use admin/cli/cron.php instead\n");
+    exit(1);
+}
+
 // This is a fake CLI script, it is a really ugly hack which emulates
 // CLI via web interface, please do not use this hack elsewhere
 define('CLI_SCRIPT', true);
index 77c0404..2329248 100644 (file)
@@ -30,11 +30,23 @@ if (!file_exists('../config.php')) {
 }
 
 // Check that PHP is of a sufficient version as soon as possible
-if (version_compare(phpversion(), '5.2.0') < 0) {
+if (version_compare(phpversion(), '5.3.2') < 0) {
     $phpversion = phpversion();
     // do NOT localise - lang strings would not work here and we CAN NOT move it to later place
-    echo "Sorry, Moodle 2.0 requires PHP 5.2.8 or later (currently using version $phpversion). ";
-    echo "Please upgrade your server software or use latest Moodle 1.9.x instead.";
+    echo "Moodle 2.1 or later requires at least PHP 5.3.2 (currently using version $phpversion).<br />";
+    echo "Please upgrade your server software or install older Moodle version.";
+    die;
+}
+
+// make sure iconv is available and actually works
+if (!function_exists('iconv')) {
+    // this should not happen, this must be very borked install
+    echo 'Moodle requires the iconv PHP extension. Please install or enable the iconv extension.';
+    die();
+}
+if (iconv('UTF-8', 'UTF-8//IGNORE', 'abc') !== 'abc') {
+    // known to be broken in mid-2011 MAMP installations
+    echo 'Broken iconv PHP extension detected, installation/upgrade can not continue.';
     die;
 }
 
@@ -121,7 +133,7 @@ if (!core_tables_exist()) {
         echo $OUTPUT->box($copyrightnotice, 'copyrightnotice');
         echo '<br />';
         $continue = new single_button(new moodle_url('/admin/index.php', array('lang'=>$CFG->lang, 'agreelicense'=>1)), get_string('continue'), 'get');
-        echo $OUTPUT->confirm(get_string('doyouagree'), $continue, "http://docs.moodle.org/en/License");
+        echo $OUTPUT->confirm(get_string('doyouagree'), $continue, "http://docs.moodle.org/dev/License");
         echo $OUTPUT->footer();
         die;
     }
@@ -455,8 +467,8 @@ if (!empty($CFG->maintenance_enabled)) {
 $copyrighttext = '<a href="http://moodle.org/">Moodle</a> '.
                  '<a href="http://docs.moodle.org/dev/Releases" title="'.$CFG->version.'">'.$CFG->release.'</a><br />'.
                  'Copyright &copy; 1999 onwards, Martin Dougiamas<br />'.
-                 'and <a href="http://docs.moodle.org/en/Credits">many other contributors</a>.<br />'.
-                 '<a href="http://docs.moodle.org/en/License">GNU Public License</a>';
+                 'and <a href="http://docs.moodle.org/dev/Credits">many other contributors</a>.<br />'.
+                 '<a href="http://docs.moodle.org/dev/License">GNU Public License</a>';
 echo $OUTPUT->box($copyrighttext, 'copyright');
 //////////////////////////////////////////////////////////////////////////////////////////////////
 
index e8d7ea7..0348cd3 100644 (file)
@@ -48,8 +48,8 @@ $temp->add(new admin_setting_configselect('sessiontimeout', get_string('sessiont
                                                                                                                                                       900 => get_string('numminutes', '', 15),
                                                                                                                                                       300 => get_string('numminutes', '', 5))));
 $temp->add(new admin_setting_configtext('sessioncookie', get_string('sessioncookie', 'admin'), get_string('configsessioncookie', 'admin'), '', PARAM_ALPHANUM));
-$temp->add(new admin_setting_configtext('sessioncookiepath', get_string('sessioncookiepath', 'admin'), get_string('configsessioncookiepath', 'admin'), '/', PARAM_LOCALURL));
-$temp->add(new admin_setting_configtext('sessioncookiedomain', get_string('sessioncookiedomain', 'admin'), get_string('configsessioncookiedomain', 'admin'), '', PARAM_TEXT, 50));
+$temp->add(new admin_setting_configtext('sessioncookiepath', get_string('sessioncookiepath', 'admin'), get_string('configsessioncookiepath', 'admin'), '', PARAM_RAW));
+$temp->add(new admin_setting_configtext('sessioncookiedomain', get_string('sessioncookiedomain', 'admin'), get_string('configsessioncookiedomain', 'admin'), '', PARAM_RAW, 50));
 $ADMIN->add('server', $temp);
 
 
index 643c478..0b02c01 100644 (file)
@@ -2637,6 +2637,12 @@ class restore_create_question_files extends restore_execution_step {
                                               $oldctxid, $this->task->get_userid(), 'question_answer', null, $newctxid, true);
             restore_dbops::send_files_to_pool($this->get_basepath(), $this->get_restoreid(), 'question', 'hint',
                                               $oldctxid, $this->task->get_userid(), 'question_hint', null, $newctxid, true);
+            restore_dbops::send_files_to_pool($this->get_basepath(), $this->get_restoreid(), 'question', 'correctfeedback',
+                                              $oldctxid, $this->task->get_userid(), 'question_created', $question->itemid, $newctxid, true);
+            restore_dbops::send_files_to_pool($this->get_basepath(), $this->get_restoreid(), 'question', 'partiallycorrectfeedback',
+                                              $oldctxid, $this->task->get_userid(), 'question_created', $question->itemid, $newctxid, true);
+            restore_dbops::send_files_to_pool($this->get_basepath(), $this->get_restoreid(), 'question', 'incorrectfeedback',
+                                              $oldctxid, $this->task->get_userid(), 'question_created', $question->itemid, $newctxid, true);
             // Add qtype dependent files
             $components = backup_qtype_plugin::get_components_and_fileareas($question->qtype);
             foreach ($components as $component => $fileareas) {
index ea07094..be15523 100644 (file)
@@ -312,7 +312,7 @@ abstract class backup_cron_automated_helper {
 
             $settings = array(
                 'users' => 'backup_auto_users',
-                'role_assignments' => 'backup_auto_users',
+                'role_assignments' => 'backup_auto_role_assignments',
                 'user_files' => 'backup_auto_user_files',
                 'activities' => 'backup_auto_activities',
                 'blocks' => 'backup_auto_blocks',
index 38eeb48..5711917 100644 (file)
@@ -140,7 +140,9 @@ class feed_edit_form extends moodleform {
                 return $url;
             }
 
-            return $rss->subscribe_url();
+            // return URL without quoting..
+            $discoveredurl = new moodle_url($rss->subscribe_url());
+            return $discoveredurl->out(false);
     }
 }
 
index a36c9f3..165466d 100644 (file)
@@ -9,7 +9,7 @@ require_once($CFG->dirroot.'/calendar/preferences_form.php');
 $courseid = required_param('course', PARAM_INT);
 $course = $DB->get_record('course', array('id' => $courseid), '*', MUST_EXIST);
 
-$PAGE->set_url('/calendar/preferences.php', array('id' => $courseid));
+$PAGE->set_url(new moodle_url('/calendar/preferences.php', array('course' => $courseid)));
 $PAGE->set_pagelayout('standard');
 
 require_login($course);
@@ -37,10 +37,13 @@ $prefs->maxevents  = get_user_preferences('calendar_maxevents', $defaultmaxevent
 $prefs->lookahead  = get_user_preferences('calendar_lookahead', $defaultlookahead);
 $prefs->persistflt = get_user_preferences('calendar_persistflt', 0);
 
-$form = new calendar_preferences_form();
+$form = new calendar_preferences_form($PAGE->url);
 $form->set_data($prefs);
 
-if ($data = $form->get_data() && confirm_sesskey()) {
+if ($form->is_cancelled()) {
+    redirect($viewurl);
+} else if ($form->is_submitted() && $form->is_validated() && confirm_sesskey()) {
+    $data = $form->get_data();
     if ($data->timeformat != CALENDAR_TF_12 && $data->timeformat != CALENDAR_TF_24) {
         $data->timeformat = '';
     }
@@ -68,7 +71,7 @@ if ($data = $form->get_data() && confirm_sesskey()) {
 $strcalendar = get_string('calendar', 'calendar');
 $strpreferences = get_string('calendarpreferences', 'calendar');
 
-$PAGE->navbar->add($strpreferences, new moodle_url('/calendar/view.php'));
+$PAGE->navbar->add($strpreferences);
 $PAGE->set_pagelayout('admin');
 $PAGE->set_title("$course->shortname: $strcalendar: $strpreferences");
 $PAGE->set_heading($course->fullname);
index 0324c5a..62c4729 100644 (file)
@@ -47,6 +47,7 @@ if ($context->contextlevel == CONTEXT_COURSECAT) {
 }
 
 $manager = has_capability('moodle/cohort:manage', $context);
+$canassign = has_capability('moodle/cohort:assign', $context);
 if (!$manager) {
     require_capability('moodle/cohort:view', $context);
 }
@@ -84,18 +85,17 @@ foreach($cohorts as $cohort) {
         $line[] = get_string('pluginname', $cohort->component);
     }
 
-    if ($manager) {
-        if (empty($cohort->component)) {
-            $buttons = html_writer::link(new moodle_url('/cohort/edit.php', array('id'=>$cohort->id, 'delete'=>1)), html_writer::empty_tag('img', array('src'=>$OUTPUT->pix_url('t/delete'), 'alt'=>get_string('delete'), 'class'=>'iconsmall')));
-            $buttons .= ' ' . html_writer::link(new moodle_url('/cohort/edit.php', array('id'=>$cohort->id)), html_writer::empty_tag('img', array('src'=>$OUTPUT->pix_url('t/edit'), 'alt'=>get_string('edit'), 'class'=>'iconsmall')));
-            $buttons .= ' ' . html_writer::link(new moodle_url('/cohort/assign.php', array('id'=>$cohort->id)), html_writer::empty_tag('img', array('src'=>$OUTPUT->pix_url('i/users'), 'alt'=>get_string('assign', 'core_cohort'), 'class'=>'iconsmall')));
-        } else {
-            $buttons = '';
+    $buttons = array();
+    if (empty($cohort->component)) {
+        if ($manager) {
+            $buttons[] = html_writer::link(new moodle_url('/cohort/edit.php', array('id'=>$cohort->id, 'delete'=>1)), html_writer::empty_tag('img', array('src'=>$OUTPUT->pix_url('t/delete'), 'alt'=>get_string('delete'), 'class'=>'iconsmall')));
+            $buttons[] =  html_writer::link(new moodle_url('/cohort/edit.php', array('id'=>$cohort->id)), html_writer::empty_tag('img', array('src'=>$OUTPUT->pix_url('t/edit'), 'alt'=>get_string('edit'), 'class'=>'iconsmall')));
+        }
+        if ($manager or $canassign) {
+            $buttons[] = html_writer::link(new moodle_url('/cohort/assign.php', array('id'=>$cohort->id)), html_writer::empty_tag('img', array('src'=>$OUTPUT->pix_url('i/users'), 'alt'=>get_string('assign', 'core_cohort'), 'class'=>'iconsmall')));
         }
-    } else {
-        $buttons = '';
     }
-    $line[] = $buttons;
+    $line[] = implode(' ', $buttons);
 
     $data[] = $line;
 }
index 3ff618b..14b0665 100644 (file)
@@ -62,8 +62,20 @@ if (function_exists('date_default_timezone_set') and function_exists('date_defau
 if (version_compare(phpversion(), "5.2.0") < 0) {
     $phpversion = phpversion();
     // do NOT localise - lang strings would not work here and we CAN not move it after installib
-    echo "Sorry, Moodle 2.0 requires PHP 5.2.8 or later (currently using version $phpversion).<br />";
-    echo "Please upgrade your server software or install latest Moodle 1.9.x instead.";
+    echo "Moodle 2.1 or later requires at least PHP 5.3.2 (currently using version $phpversion).<br />";
+    echo "Please upgrade your server software or install older Moodle version.";
+    die;
+}
+
+// make sure iconv is available and actually works
+if (!function_exists('iconv')) {
+    // this should not happen, this must be very borked install
+    echo 'Moodle requires the iconv PHP extension. Please install or enable the iconv extension.';
+    die();
+}
+if (iconv('UTF-8', 'UTF-8//IGNORE', 'abc') !== 'abc') {
+    // known to be broken in mid-2011 MAMP installations
+    echo 'Broken iconv PHP extension detected, installation can not continue.';
     die;
 }
 
@@ -169,7 +181,7 @@ $memlimit = @ini_get('memory_limit');
 if (!empty($memlimit) and $memlimit != -1) {
     if (get_real_size($memlimit) < get_real_size($minrequiredmemory)) {
         // do NOT localise - lang strings would not work here and we CAN not move it to later place
-        echo "Sorry, Moodle 2.0 requires at least {$minrequiredmemory}B of PHP memory.<br />";
+        echo "Moodle requires at least {$minrequiredmemory}B of PHP memory.<br />";
         echo "Please contact server administrator to fix PHP.ini memory settings.";
         die;
     }
@@ -481,7 +493,7 @@ if ($config->stage == INSTALL_DATABASETYPE) {
 
 
 if ($config->stage == INSTALL_ENVIRONMENT or $config->stage == INSTALL_PATHS) {
-    $version_fail = (version_compare(phpversion(), "5.2.8") < 0);
+    $version_fail = (version_compare(phpversion(), "5.3.2") < 0);
     $curl_fail    = ($lang !== 'en' and !extension_loaded('curl')); // needed for lang pack download
     $zip_fail     = ($lang !== 'en' and !extension_loaded('zip'));  // needed for lang pack download
 
@@ -494,7 +506,7 @@ if ($config->stage == INSTALL_ENVIRONMENT or $config->stage == INSTALL_PATHS) {
 
         echo '<div id="envresult"><dl>';
         if ($version_fail) {
-            $a = (object)array('needed'=>'5.2.8', 'current'=>phpversion());
+            $a = (object)array('needed'=>'5.3.2', 'current'=>phpversion());
             echo '<dt>'.get_string('phpversion', 'install').'</dt><dd>'.get_string('environmentrequireversion', 'admin', $a).'</dd>';
         }
         if ($curl_fail) {
index ab06c92..a5526ce 100644 (file)
@@ -76,7 +76,7 @@ $string['downloadcore'] = 'Our main method of distribution is via these standard
 $string['downloadcoretitle'] = 'Standard Moodle packages';
 $string['downloadcvs'] = 'Another way to get the core source code is by using CVS to connect directly to one of our mirrors of the code repository used by Moodle developers.  This makes upgrading very easy, even if you have made local changes to the source code.';
 $string['downloadcvstitle'] = 'Moodle via CVS';
-$string['downloadintro'] = 'Moodle is open source under the <a href="http://docs.moodle.org/en/License">GPL licence</a>.  Everything we produce is available for you to download and use for free.';
+$string['downloadintro'] = 'Moodle is open source under the <a href="http://docs.moodle.org/dev/License">GPL licence</a>.  Everything we produce is available for you to download and use for free.';
 $string['downloadlang'] = 'In current versions of Moodle, adding support for new languages has been automated from the administration menu within your site.  However, for some older versions of Moodle, new language packs need to be downloaded manually.';
 $string['downloadlangtitle'] = 'Language packs';
 $string['downloadlogotitle'] = 'Moodle logos';
index 50f5ebc..07bb2e9 100644 (file)
@@ -735,7 +735,7 @@ but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
 See the Moodle License information page for full details:
-http://docs.moodle.org/en/License';
+http://docs.moodle.org/dev/License';
 $string['gpllicense'] = 'GPL license';
 $string['gpl3'] = 'Copyright (C) 1999 onwards Martin Dougiamas (http://moodle.com)
 
@@ -749,7 +749,7 @@ but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
 See the Moodle License information page for full details:
-http://docs.moodle.org/en/License';
+http://docs.moodle.org/dev/License';
 $string['grade'] = 'Grade';
 $string['grades'] = 'Grades';
 $string['group'] = 'Group';
index 1935084..b80caa2 100644 (file)
@@ -2121,7 +2121,7 @@ WHERE gradeitemid IS NOT NULL AND grademax IS NOT NULL");
                 $instanceids[] = $blockinstance->id;
                 // If we have more than 1000 block instances now remove all block positions
                 // and empty the array
-                if (count($contextids) > 1000) {
+                if (count($instanceids) > 1000) {
                     $instanceidstring = join(',',$instanceids);
                     $DB->delete_records_select('block_positions', 'blockinstanceid IN ('.$instanceidstring.')');
                     $instanceids = array();
@@ -2131,8 +2131,10 @@ WHERE gradeitemid IS NOT NULL AND grademax IS NOT NULL");
 
         upgrade_cleanup_unwanted_block_contexts($contextids);
 
-        $instanceidstring = join(',',$instanceids);
-        $DB->delete_records_select('block_positions', 'blockinstanceid IN ('.$instanceidstring.')');
+        if ($instanceids) {
+            $instanceidstring = join(',',$instanceids);
+            $DB->delete_records_select('block_positions', 'blockinstanceid IN ('.$instanceidstring.')');
+        }
 
         unset($allblockinstances);
         unset($contextids);
index 83885c3..db88a9e 100644 (file)
@@ -502,19 +502,24 @@ abstract class moodle_database {
         $where = array();
         $params = array();
 
-        $columns = $this->get_columns($table);
-        foreach ($conditions as $key=>$value) {
-            if (!isset($columns[$key])) {
-                $a = new stdClass();
-                $a->fieldname = $key;
-                $a->tablename = $table;
-                throw new dml_exception('ddlfieldnotexist', $a);
-            }
-            $column = $columns[$key];
-            if ($column->meta_type == 'X') {
-                //ok so the column is a text column. sorry no text columns in the where clause conditions
-                throw new dml_exception('textconditionsnotallowed', $conditions);
+        if (debugging()) {
+            $columns = $this->get_columns($table);
+            foreach ($conditions as $key=>$value) {
+                if (!isset($columns[$key])) {
+                    $a = new stdClass();
+                    $a->fieldname = $key;
+                    $a->tablename = $table;
+                    throw new dml_exception('ddlfieldnotexist', $a);
+                }
+                $column = $columns[$key];
+                if ($column->meta_type == 'X') {
+                    //ok so the column is a text column. sorry no text columns in the where clause conditions
+                    throw new dml_exception('textconditionsnotallowed', $conditions);
+                }
             }
+        }
+
+        foreach ($conditions as $key=>$value) {
             if (is_int($key)) {
                 throw new dml_exception('invalidnumkey');
             }
index 4f82eda..9fa697f 100644 (file)
@@ -277,12 +277,12 @@ class pgsql_native_moodle_database extends moodle_database {
             return $this->tables;
         }
         $this->tables = array();
-        $prefix = str_replace('_', '\\\\_', $this->prefix);
+        $prefix = str_replace('_', '|_', $this->prefix);
         // Get them from information_schema instead of catalog as far as
         // we want to get only own session temp objects (catalog returns all)
         $sql = "SELECT table_name
                   FROM information_schema.tables
-                 WHERE table_name LIKE '$prefix%'
+                 WHERE table_name LIKE '$prefix%' ESCAPE '|'
                    AND table_type IN ('BASE TABLE', 'LOCAL TEMPORARY')";
         $this->query_start($sql, null, SQL_QUERY_AUX);
         $result = pg_query($this->pgsql, $sql);
index df8b0c4..14f5283 100644 (file)
@@ -53,10 +53,20 @@ class file_info_context_course extends file_info {
      * @param $filename
      */
     public function get_file_info($component, $filearea, $itemid, $filepath, $filename) {
+        // try to emulate require_login() tests here
+        if (!isloggedin()) {
+            return null;
+        }
+
         if (!$this->course->visible and !has_capability('moodle/course:viewhiddencourses', $this->context)) {
             return null;
         }
 
+        if (!is_viewing($this->context) and !is_enrolled($this->context)) {
+            // no peaking here if not enrolled or inspector
+            return null;
+        }
+
         if (empty($component)) {
             return $this;
         }
index e72e315..a8149c6 100644 (file)
@@ -75,11 +75,28 @@ class file_info_context_module extends file_info {
      * @param $filename
      */
     public function get_file_info($component, $filearea, $itemid, $filepath, $filename) {
-        if (!is_enrolled($this->context) and !is_viewing($this->context)) {
+        // try to emulate require_login() tests here
+        if (!isloggedin()) {
+            return null;
+        }
+
+        $coursecontext = get_course_context($this->context);
+        if (!$this->course->visible and !has_capability('moodle/course:viewhiddencourses', $coursecontext)) {
+            return null;
+        }
+
+        if (!is_viewing($this->context) and !is_enrolled($this->context)) {
             // no peaking here if not enrolled or inspector
             return null;
         }
 
+        $modinfo = get_fast_modinfo($this->course);
+        $cminfo = $modinfo->get_cm($this->cm->id);
+        if (!$cminfo->uservisible) {
+            // activity hidden sorry
+            return null;
+        }
+
         if (empty($component)) {
             return $this;
         }
index 120de12..708d242 100644 (file)
@@ -717,7 +717,7 @@ function groups_course_module_visible($cm, $userid=null) {
  * @return void
  */
 function _group_verify_activegroup($courseid, $groupmode, $groupingid, array $allowedgroups) {
-    global $SESSION;
+    global $SESSION, $USER;
 
     // init activegroup array if necessary
     if (!isset($SESSION->activegroup)) {
@@ -742,7 +742,11 @@ function _group_verify_activegroup($courseid, $groupmode, $groupingid, array $al
             $SESSION->activegroup[$courseid][$groupmode][$groupingid] = 0; // all groups by default if user has accessallgroups
 
         } else if ($allowedgroups) {
-            $firstgroup = reset($allowedgroups);
+            if ($groupmode != SEPARATEGROUPS and $mygroups = groups_get_all_groups($courseid, $USER->id, $groupingid)) {
+                $firstgroup = reset($mygroups);
+            } else {
+                $firstgroup = reset($allowedgroups);
+            }
             $SESSION->activegroup[$courseid][$groupmode][$groupingid] = $firstgroup->id;
 
         } else {
index 2d6476a..536c141 100644 (file)
@@ -361,21 +361,29 @@ M.util.init_select_autosubmit = function(Y, formid, selectid, nothing) {
             // Make sure we have the form
             if (form) {
                 // Create a function to handle our change event
-                var processchange = function(e, lastindex) {
-                    if ((nothing===false || select.get('value') != nothing) && lastindex != select.get('selectedIndex')) {
+                var processchange = function(e, paramobject) {
+                    if ((nothing===false || select.get('value') != nothing) && paramobject.lastindex != select.get('selectedIndex')) {
+                        //prevent event bubbling and detach handlers to prevent multiple submissions caused by double clicking
+                        e.halt();
+                        paramobject.eventkeypress.detach();
+                        paramobject.eventblur.detach();
+                        paramobject.eventchangeorblur.detach();
+
                         this.submit();
                     }
                 };
                 // Attach the change event to the keypress, blur, and click actions.
                 // We don't use the change event because IE fires it on every arrow up/down
                 // event.... usability
-                Y.on('key', processchange, select, 'press:13', form, select.get('selectedIndex'));
-                select.on('blur', processchange, form, select.get('selectedIndex'));
+                var paramobject = new Object();
+                paramobject.lastindex = select.get('selectedIndex');
+                paramobject.eventkeypress = Y.on('key', processchange, select, 'press:13', form, paramobject);
+                paramobject.eventblur = select.on('blur', processchange, form, paramobject);
                 //little hack for chrome that need onChange event instead of onClick - see MDL-23224
                 if (Y.UA.webkit) {
-                    select.on('change', processchange, form, select.get('selectedIndex'));
+                    paramobject.eventchangeorblur = select.on('change', processchange, form, paramobject);
                 } else {
-                    select.on('click', processchange, form, select.get('selectedIndex'));
+                    paramobject.eventchangeorblur = select.on('click', processchange, form, paramobject);
                 }
             }
         }
index 6cf7236..e797bf6 100644 (file)
@@ -3509,6 +3509,9 @@ function delete_user($user) {
     // last course access not necessary either
     $DB->delete_records('user_lastaccess', array('userid'=>$user->id));
 
+    // force logout - may fail if file based sessions used, sorry
+    session_kill_user($user->id);
+
     // now do a final accesslib cleanup - removes all role assignments in user context and context itself
     delete_context(CONTEXT_USER, $user->id);
 
index becd7d7..53f0315 100644 (file)
@@ -279,11 +279,40 @@ abstract class session_stub implements moodle_session {
         if (!isset($CFG->sessioncookie)) {
             $CFG->sessioncookie = '';
         }
+
+        // make sure cookie domain makes sense for this wwwroot
         if (!isset($CFG->sessioncookiedomain)) {
             $CFG->sessioncookiedomain = '';
+        } else if ($CFG->sessioncookiedomain !== '') {
+            $host = parse_url($CFG->wwwroot, PHP_URL_HOST);
+            if ($CFG->sessioncookiedomain !== $host) {
+                if (substr($CFG->sessioncookiedomain, 0, 1) === '.') {
+                    if (!preg_match('|^.*'.preg_quote($CFG->sessioncookiedomain, '|').'$|', $host)) {
+                        // invalid domain - it must be end part of host
+                        $CFG->sessioncookiedomain = '';
+                    }
+                } else {
+                    if (!preg_match('|^.*\.'.preg_quote($CFG->sessioncookiedomain, '|').'$|', $host)) {
+                        // invalid domain - it must be end part of host
+                        $CFG->sessioncookiedomain = '';
+                    }
+                }
+            }
         }
+
+        // make sure the cookiepath is valid for this wwwroot or autodetect if not specified
         if (!isset($CFG->sessioncookiepath)) {
-            $CFG->sessioncookiepath = '/';
+            $CFG->sessioncookiepath = '';
+        }
+        if ($CFG->sessioncookiepath !== '/') {
+            $path = parse_url($CFG->wwwroot, PHP_URL_PATH).'/';
+            if ($CFG->sessioncookiepath === '') {
+                $CFG->sessioncookiepath = $path;
+            } else {
+                if (strpos($path, $CFG->sessioncookiepath) !== 0 or substr($CFG->sessioncookiepath, -1) !== '/') {
+                    $CFG->sessioncookiepath = $path;
+                }
+            }
         }
 
         //discard session ID from POST, GET and globals to tighten security,
index e02e7e5..9100c19 100644 (file)
@@ -38,7 +38,6 @@ if (!defined('MOODLE_INTERNAL')) {
 require_once("$CFG->libdir/portfoliolib.php");
 require_once("$CFG->libdir/portfolio/exporter.php");
 require_once("$CFG->libdir/portfolio/plugin.php");
-require_once("$CFG->dirroot/$CFG->admin/generator.php");
 
 class portfolio_plugin_test extends portfolio_plugin_push_base {
     public function expected_time($callertime){
index d4a44d1..4a23924 100644 (file)
@@ -36,7 +36,6 @@ if (!defined('MOODLE_INTERNAL')) {
 }
 
 require_once("$CFG->dirroot/repository/lib.php");
-require_once("$CFG->dirroot/$CFG->admin/generator.php");
 
 // Generate a mock class for each plugin subclass present
 $repository_plugins = get_list_of_plugins('repository');
index 1232659..d314ef2 100644 (file)
@@ -1528,7 +1528,7 @@ function purify_html($text, $options = array()) {
         $config->set('Core.ConvertDocumentToFragment', true);
         $config->set('Core.Encoding', 'UTF-8');
         $config->set('HTML.Doctype', 'XHTML 1.0 Transitional');
-        $config->set('URI.AllowedSchemes', array('http'=>true, 'https'=>true, 'ftp'=>true, 'irc'=>true, 'nntp'=>true, 'news'=>true, 'rtsp'=>true, 'teamspeak'=>true, 'gopher'=>true, 'mms'=>true));
+        $config->set('URI.AllowedSchemes', array('http'=>true, 'https'=>true, 'ftp'=>true, 'irc'=>true, 'nntp'=>true, 'news'=>true, 'rtsp'=>true, 'teamspeak'=>true, 'gopher'=>true, 'mms'=>true, 'mailto'=>true));
         $config->set('Attr.AllowedFrameTargets', array('_blank'));
 
         if (!empty($CFG->allowobjectembed)) {
index 05b0e1e..f9ce0fa 100644 (file)
@@ -1,7 +1,6 @@
 <?php
 require_once("$CFG->libdir/simpletest/portfolio_testclass.php");
 require_once("$CFG->dirroot/mod/assignment/lib.php");
-require_once("$CFG->dirroot/$CFG->admin/generator.php");
 require_once("$CFG->dirroot/mod/assignment/locallib.php");
 
 Mock::generate('assignment_portfolio_caller', 'mock_caller');
index c8f1696..1069a43 100644 (file)
@@ -1,7 +1,6 @@
 <?php
 require_once("$CFG->libdir/simpletest/portfolio_testclass.php");
 require_once("$CFG->dirroot/mod/chat/lib.php");
-require_once("$CFG->dirroot/$CFG->admin/generator.php");
 
 /*
  * TODO: The portfolio unit tests were obselete and did not work.
index 626ef7f..4ea08e4 100644 (file)
@@ -1,7 +1,6 @@
 <?php
 require_once("$CFG->libdir/simpletest/portfolio_testclass.php");
 require_once("$CFG->dirroot/mod/data/lib.php");
-require_once("$CFG->dirroot/$CFG->admin/generator.php");
 require_once("$CFG->dirroot/mod/data/locallib.php");
 
 /*
index d6d6da0..503ef15 100644 (file)
@@ -26,7 +26,6 @@
 
 require_once("$CFG->libdir/simpletest/portfolio_testclass.php");
 require_once("$CFG->dirroot/mod/forum/lib.php");
-require_once("$CFG->dirroot/$CFG->admin/generator.php");
 
 /*
  * TODO: The portfolio unit tests were obselete and did not work.
index 066260b..78ac42a 100644 (file)
@@ -2,7 +2,6 @@
 require_once("$CFG->libdir/simpletest/portfolio_testclass.php");
 require_once("$CFG->dirroot/mod/glossary/lib.php");
 require_once("$CFG->dirroot/mod/glossary/locallib.php");
-require_once("$CFG->dirroot/$CFG->admin/generator.php");
 
 /*
  * TODO: The portfolio unit tests were obselete and did not work.
index df4668a..15a9d8f 100644 (file)
@@ -453,8 +453,7 @@ echo '<div id="module" class="module">';
 echo '<div class="bd">';
 $questionbank->display('editq',
         $pagevars['qpage'],
-        $pagevars['qperpage'], $pagevars['qsortorder'],
-        $pagevars['qsortorderdecoded'],
+        $pagevars['qperpage'],
         $pagevars['cat'], $pagevars['recurse'], $pagevars['showhidden'],
         $pagevars['showquestiontext']);
 echo '</div>';
index 43dffcc..3914e84 100644 (file)
@@ -1129,8 +1129,8 @@ class quiz_question_bank_view extends question_bank_view {
         return new moodle_url('/mod/quiz/edit.php', $params);
     }
 
-    public function display($tabname, $page, $perpage, $sortorder,
-            $sortorderdecoded, $cat, $recurse, $showhidden, $showquestiontext) {
+    public function display($tabname, $page, $perpage, $cat,
+            $recurse, $showhidden, $showquestiontext) {
         global $OUTPUT;
         if ($this->process_actions_needing_ui()) {
             return;
@@ -1150,7 +1150,7 @@ class quiz_question_bank_view extends question_bank_view {
         // continues with list of questions
         $this->display_question_list($this->contexts->having_one_edit_tab_cap($tabname),
                 $this->baseurl, $cat, $this->cm, $recurse, $page,
-                $perpage, $showhidden, $sortorder, $sortorderdecoded, $showquestiontext,
+                $perpage, $showhidden, $showquestiontext,
                 $this->contexts->having_cap('moodle/question:add'));
 
         $this->display_options($recurse, $showhidden, $showquestiontext);
index cde3701..a81aa5e 100644 (file)
@@ -588,6 +588,7 @@ function quiz_upgrade_grades() {
  */
 function quiz_grade_item_update($quiz, $grades = null) {
     global $CFG, $OUTPUT;
+    require_once($CFG->dirroot . '/mod/quiz/locallib.php');
     require_once($CFG->libdir.'/gradelib.php');
 
     if (array_key_exists('cmidnumber', $quiz)) { // may not be always present
index 3aa9022..1c030f4 100644 (file)
@@ -98,12 +98,18 @@ class quiz_statistics_response_analyser {
 
     /**
      * @return bool whether this analysis has a response class more than one
-     *      different acutal response.
+     *      different acutal response, or if the actual response is different from
+     *      the model response.
      */
     public function has_actual_responses() {
         foreach ($this->responseclasses as $subpartid => $partclasses) {
-            foreach ($partclasses as $responseclassid => $notused) {
-                if (count($this->responses[$subpartid][$responseclassid]) > 1) {
+            foreach ($partclasses as $responseclassid => $modelresponse) {
+                $numresponses = count($this->responses[$subpartid][$responseclassid]);
+                if ($numresponses > 1) {
+                    return true;
+                }
+                $actualresponse = key($this->responses[$subpartid][$responseclassid]);
+                if ($numresponses == 1 && $actualresponse != $modelresponse->responseclass) {
                     return true;
                 }
             }
index 9d3c4ab..cd36bd9 100644 (file)
@@ -173,7 +173,7 @@ if ($attempt->timefinish) {
     );
     $summarydata['timetaken'] = array(
         'title'   => get_string('timetaken', 'quiz'),
-        'content' => format_time($timetaken),
+        'content' => $timetaken,
     );
 }
 
index 8bee8d8..1d9dd02 100644 (file)
@@ -17,7 +17,7 @@
 function scorm_get_resources($blocks) {
     $resources = array();
     foreach ($blocks as $block) {
-        if ($block['name'] == 'RESOURCES') {
+        if ($block['name'] == 'RESOURCES' && isset($block['children'])) {
             foreach ($block['children'] as $resource) {
                 if ($resource['name'] == 'RESOURCE') {
                     $resources[addslashes_js($resource['attrs']['IDENTIFIER'])] = $resource['attrs'];
@@ -29,12 +29,14 @@ function scorm_get_resources($blocks) {
 }
 
 function scorm_get_manifest($blocks, $scoes) {
+    global $OUTPUT;
     static $parents = array();
     static $resources;
 
     static $manifest;
     static $organization;
 
+    $manifestresourcesnotfound = array();
     if (count($blocks) > 0) {
         foreach ($blocks as $block) {
             switch ($block['name']) {
@@ -130,11 +132,16 @@ function scorm_get_manifest($blocks, $scoes) {
                         if (isset($resources[$idref]['XML:BASE'])) {
                             $base = $resources[$idref]['XML:BASE'];
                         }
-                        $scoes->elements[$manifest][$organization][$identifier]->launch = $base.$resources[$idref]['HREF'];
-                        if (empty($resources[$idref]['ADLCP:SCORMTYPE'])) {
-                            $resources[$idref]['ADLCP:SCORMTYPE'] = 'asset';
+                        if (!isset($resources[$idref])) {
+                            $manifestresourcesnotfound[] = $idref;
+                            $scoes->elements[$manifest][$organization][$identifier]->launch = '';
+                        } else {
+                            $scoes->elements[$manifest][$organization][$identifier]->launch = $base.$resources[$idref]['HREF'];
+                            if (empty($resources[$idref]['ADLCP:SCORMTYPE'])) {
+                                $resources[$idref]['ADLCP:SCORMTYPE'] = 'asset';
+                            }
+                            $scoes->elements[$manifest][$organization][$identifier]->scormtype = $resources[$idref]['ADLCP:SCORMTYPE'];
                         }
-                        $scoes->elements[$manifest][$organization][$identifier]->scormtype = $resources[$idref]['ADLCP:SCORMTYPE'];
                     }
 
                     $parent = new stdClass();
@@ -473,6 +480,13 @@ function scorm_get_manifest($blocks, $scoes) {
             }
         }
     }
+    if (!empty($manifestresourcesnotfound)) {
+        //throw warning to user to let them know manifest contains references to resources that don't appear to exist.
+        if (!defined('DEBUGGING_PRINTED')) { //prevent redirect and display warning
+            define('DEBUGGING_PRINTED', 1);
+        }
+        echo $OUTPUT->notification(get_string('invalidmanifestresource', 'scorm').' '. implode(', ',$manifestresourcesnotfound));
+    }
     return $scoes;
 }
 
index c5ce688..b7a307c 100644 (file)
@@ -546,7 +546,7 @@ function xmldb_scorm_upgrade($oldversion) {
         unset_config('updatetime', 'scorm');
         upgrade_mod_savepoint(true, 2011021402, 'scorm');
     }
-    
+
     if ($oldversion < 2011073100) {
         // change field type of objectiveid
         $table = new xmldb_table('scorm_seq_objective');
index 2fcb0ec..b972a29 100644 (file)
@@ -146,6 +146,7 @@ $string['incomplete'] = 'Incomplete';
 $string['info'] = 'Info';
 $string['interactions'] = 'Interactions';
 $string['invalidactivity'] = 'Scorm activity is incorrect';
+$string['invalidmanifestresource'] = 'WARNING: The following resources were referenced in your manifest but couldn\'t be found:';
 $string['last'] = 'Last accessed on';
 $string['lastaccess'] = 'Last access';
 $string['lastattempt'] = 'Last attempt';
diff --git a/mod/scorm/rd.js b/mod/scorm/rd.js
deleted file mode 100644 (file)
index f24a121..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-<!--
-function attach_resize_event() {
-    YAHOO.util.Event.addListener(window, 'resize', scorm_resize);
-}
-
-var prev='';
-var next='';
-function scorm_set_prev(url) {
-    prev = url;
-}
-function scorm_set_next(url) {
-    next = url;
-}
-
-function scorm_get_element_style(obj, prop, cssProp) {
-    var ret = '';
-
-    if (obj.currentStyle) {
-        ret = obj.currentStyle[prop];
-    } else if (document.defaultView && document.defaultView.getComputedStyle) {
-        var compStyle = document.defaultView.getComputedStyle(obj, null);
-        ret = compStyle.getPropertyValue(cssProp);
-    }
-
-    if (ret == 'auto') ret = '0';
-    return ret;
-}
-
-function scorm_resize () {
-    var cwidth = scormplayerdata.cwidth;
-    var cheight = scormplayerdata.cheight;
-    var winwidth = 0, winheight = 0;
-    if( typeof( window.innerWidth ) == 'number' ) {
-        //Non-IE
-        winwidth = window.innerWidth;
-        winheight = window.innerHeight;
-    } else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
-        //IE 6+ in 'standards compliant mode'
-        winwidth = document.documentElement.clientWidth;
-        winheight = document.documentElement.clientHeight;
-    } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
-        //IE 4 compatible
-        winwidth = document.body.clientWidth;
-        winheight = document.body.clientHeight;
-    }
-
-    var header = document.getElementById('header');
-    var content = document.getElementById('region-content');
-    var headerheight = 0;
-    if (content) {
-        headerheight = content.offsetTop;
-    }
-
-    var footer = document.getElementById('footer');
-    var imsnavbar = document.getElementById('tochead');
-    var scormtop = document.getElementById('scormtop');
-    var footerheight = 0;
-    var imsnavheight = 0;
-    var scormtopheight = 0;
-    if (footer) {
-        footerheight = footer.offsetHeight + parseInt(scorm_get_element_style(footer, 'marginTop', 'margin-top')) + parseInt(scorm_get_element_style(footer, 'marginBottom', 'margin-bottom'));
-    }
-    if (imsnavbar) {
-        imsnavheight = imsnavbar.offsetHeight;
-    }
-    if (scormtop) {
-        scormtopheight = scormtop.offsetHeight;
-    }
-
-    var topmargin = parseInt(scorm_get_element_style(document.getElementsByTagName('body')[0], 'marginTop', 'margin-top'));
-    var bottommargin = parseInt(scorm_get_element_style(document.getElementsByTagName('body')[0], 'marginBottom', 'margin-bottom'));
-
-    var totalheight = headerheight +
-                        footerheight +
-                        scormtopheight+
-                        topmargin +
-                        bottommargin+10; // +10 to save a minor vertical scroll always present!
-
-    var totalheighttoc = totalheight+imsnavheight;
-    // override total height with configured height if it is defined
-    if (cheight > 0) {
-      winheight = cheight;
-    }
-    var finalheighttoc = winheight - totalheighttoc;
-    if (finalheighttoc <= 0) {
-        finalheighttoc = winheight;
-    }
-    var finalheight = winheight - totalheight;
-    if (finalheight <= 0) {
-        finalheight = winheight;
-    }
-    var toctree = document.getElementById('toctree');
-    if (toctree != null){
-        var toctreeHeight = toctree.offsetHeight;
-        document.getElementById('toctree').style.height = finalheighttoc + 'px';
-        var scoframe2 = document.getElementById('scoframe1');
-        document.getElementById('scormobject').style.height = finalheight + 'px';
-    }else{
-        document.getElementById('scormobject').style.height = finalheight + 'px';
-        document.getElementById('scormpage').style.height = finalheight + 'px';
-    }
-
-    // resize the content container too to move the footer below the SCORM content
-    var contenti3 = document.getElementById('content-i3');
-    if (contenti3) {
-        contenti3.style.height = (winheight - totalheight + 30) + 'px';
-    } else {
-       document.getElementById('region-main-box').style.height = (finalheight + 30) + 'px';
-    }
-     // resize the content container too to move the footer below the SCORM content
-    var contenti3 = document.getElementById('content-i3');
-    if (contenti3) {
-        contenti3.style.height = (finalheight + 30) + 'px';
-    } else {
-        document.getElementById('region-main-box').style.height = (finalheight + 30) + 'px';
-    }
-}
--->
index f3099de..20600d1 100644 (file)
@@ -1,7 +1,6 @@
 <?php
 require_once("$CFG->libdir/simpletest/testportfoliolib.php");
 require_once("$CFG->dirroot/portfolio/boxnet/lib.php");
-require_once("$CFG->dirroot/$CFG->admin/generator.php");
 
 /*
  * TODO: The portfolio unit tests were obselete and did not work.
index c52b4a4..5359fe7 100644 (file)
@@ -65,9 +65,9 @@ $PAGE->set_heading($COURSE->fullname);
 echo $OUTPUT->header();
 
 echo '<div class="questionbankwindow boxwidthwide boxaligncenter">';
-$questionbank->display('questions', $pagevars['qpage'],
-        $pagevars['qperpage'], $pagevars['qsortorder'], $pagevars['qsortorderdecoded'],
-        $pagevars['cat'], $pagevars['recurse'], $pagevars['showhidden'], $pagevars['showquestiontext']);
+$questionbank->display('questions', $pagevars['qpage'], $pagevars['qperpage'],
+        $pagevars['cat'], $pagevars['recurse'], $pagevars['showhidden'],
+        $pagevars['showquestiontext']);
 echo "</div>\n";
 
 echo $OUTPUT->footer();
index 27f74a6..59811a8 100644 (file)
@@ -155,7 +155,6 @@ abstract class question_bank_column_base {
 
     /**
      * Output the column header cell.
-     * @param int $currentsort 0 for none. 1 for normal sort, -1 for reverse sort.
      */
     public function display_header() {
         echo '<th class="header ' . $this->get_classes() . '" scope="col">';
@@ -1168,8 +1167,8 @@ class question_bank_view {
      * category      Chooses the category
      * displayoptions Sets display options
      */
-    public function display($tabname, $page, $perpage, $sortorder,
-            $sortorderdecoded, $cat, $recurse, $showhidden, $showquestiontext){
+    public function display($tabname, $page, $perpage, $cat,
+            $recurse, $showhidden, $showquestiontext) {
         global $PAGE, $OUTPUT;
 
         if ($this->process_actions_needing_ui()) {
@@ -1191,8 +1190,9 @@ class question_bank_view {
         $this->print_category_info($category);
 
         // continues with list of questions
-        $this->display_question_list($this->contexts->having_one_edit_tab_cap($tabname), $this->baseurl, $cat, $this->cm,
-                $recurse, $page, $perpage, $showhidden, $sortorder, $sortorderdecoded, $showquestiontext,
+        $this->display_question_list($this->contexts->having_one_edit_tab_cap($tabname),
+                $this->baseurl, $cat, $this->cm,
+                $recurse, $page, $perpage, $showhidden, $showquestiontext,
                 $this->contexts->having_cap('moodle/question:add'));
     }
 
@@ -1297,7 +1297,6 @@ class question_bank_view {
     */
     protected function display_question_list($contexts, $pageurl, $categoryandcontext,
             $cm = null, $recurse=1, $page=0, $perpage=100, $showhidden=false,
-            $sortorder='typename', $sortorderdecoded='qtype, name ASC',
             $showquestiontext = false, $addcontexts = array()) {
         global $CFG, $DB, $OUTPUT;
 
@@ -1639,17 +1638,12 @@ function question_edit_setup($edittab, $baseurl, $requirecmid = false, $requirec
         $pagevars['qperpage'] = DEFAULT_QUESTIONS_PER_PAGE;
     }
 
-    $sortoptions = array('alpha' => 'name, qtype ASC',
-                          'typealpha' => 'qtype, name ASC',
-                          'age' => 'id ASC');
-
-    if ($sortorder = optional_param('qsortorder', '', PARAM_ALPHA)) {
-        $pagevars['qsortorderdecoded'] = $sortoptions[$sortorder];
-        $pagevars['qsortorder'] = $sortorder;
-        $thispageurl->param('qsortorder', $sortorder);
-    } else {
-        $pagevars['qsortorderdecoded'] = $sortoptions['typealpha'];
-        $pagevars['qsortorder'] = 'typealpha';
+    for ($i = 1; $i <= question_bank_view::MAX_SORTS; $i++) {
+        $param = 'qbs' . $i;
+        if (!$sort = optional_param($param, '', PARAM_ALPHAEXT)) {
+            break;
+        }
+        $thispageurl->param($param, $sort);
     }
 
     $defaultcategory = question_make_default_categories($contexts->all());
index b08e7fb..757099b 100644 (file)
@@ -355,7 +355,7 @@ abstract class question_edit_form extends moodleform {
         $mform = $this->_form;
 
         $repeated = array();
-        $repeated[] = $mform->createElement('header', 'answerhdr', get_string('hintn', 'question'));
+        $repeated[] = $mform->createElement('header', 'hinthdr', get_string('hintn', 'question'));
         $repeated[] = $mform->createElement('editor', 'hint', get_string('hinttext', 'question'),
                 array('rows' => 5), $this->editoroptions);
         $repeatedoptions['hint']['type'] = PARAM_RAW;
index 8828030..36f08b5 100644 (file)
@@ -206,6 +206,8 @@ class qtype_match extends question_type {
             $fs->move_area_files_to_new_context($oldcontextid,
                     $newcontextid, 'qtype_match', 'subquestion', $subquestionid);
         }
+
+        $this->move_files_in_combined_feedback($questionid, $oldcontextid, $newcontextid);
     }
 
     protected function delete_files($questionid, $contextid) {
@@ -220,11 +222,6 @@ class qtype_match extends question_type {
             $fs->delete_area_files($contextid, 'qtype_match', 'subquestion', $subquestionid);
         }
 
-        $fs->delete_area_files($contextid, 'qtype_multichoice',
-                'correctfeedback', $questionid);
-        $fs->delete_area_files($contextid, 'qtype_multichoice',
-                'partiallycorrectfeedback', $questionid);
-        $fs->delete_area_files($contextid, 'qtype_multichoice',
-                'incorrectfeedback', $questionid);
+        $this->delete_files_in_combined_feedback($questionid, $contextid);
     }
 }
index b4d20db..70724e0 100644 (file)
@@ -69,17 +69,4 @@ class backup_qtype_multichoice_plugin extends backup_qtype_plugin {
 
         return $plugin;
     }
-
-    /**
-     * Returns one array with filearea => mappingname elements for the qtype
-     *
-     * Used by {@link get_components_and_fileareas} to know about all the qtype
-     * files to be processed both in backup and restore.
-     */
-    public static function get_qtype_fileareas() {
-        return array(
-            'correctfeedback' => 'question_created',
-            'partiallycorrectfeedback' => 'question_created',
-            'incorrectfeedback' => 'question_created');
-    }
 }
index f7b46ad..240bc4c 100644 (file)
@@ -231,30 +231,14 @@ class qtype_multichoice extends question_type {
     }
 
     public function move_files($questionid, $oldcontextid, $newcontextid) {
-        $fs = get_file_storage();
-
         parent::move_files($questionid, $oldcontextid, $newcontextid);
         $this->move_files_in_answers($questionid, $oldcontextid, $newcontextid, true);
-
-        $fs->move_area_files_to_new_context($oldcontextid,
-                $newcontextid, 'qtype_multichoice', 'correctfeedback', $questionid);
-        $fs->move_area_files_to_new_context($oldcontextid,
-                $newcontextid, 'qtype_multichoice', 'partiallycorrectfeedback', $questionid);
-        $fs->move_area_files_to_new_context($oldcontextid,
-                $newcontextid, 'qtype_multichoice', 'incorrectfeedback', $questionid);
+        $this->move_files_in_combined_feedback($questionid, $oldcontextid, $newcontextid);
     }
 
     protected function delete_files($questionid, $contextid) {
-        $fs = get_file_storage();
-
         parent::delete_files($questionid, $contextid);
         $this->delete_files_in_answers($questionid, $contextid, true);
-
-        $fs->delete_area_files($contextid,
-                'qtype_multichoice', 'correctfeedback', $questionid);
-        $fs->delete_area_files($contextid,
-                'qtype_multichoice', 'partiallycorrectfeedback', $questionid);
-        $fs->delete_area_files($contextid,
-                'qtype_multichoice', 'incorrectfeedback', $questionid);
+        $this->delete_files_in_combined_feedback($questionid, $contextid);
     }
 }
index f45bf40..edd9266 100644 (file)
@@ -454,7 +454,7 @@ class question_classified_response {
     }
 
     public static function no_response() {
-        return new question_classified_response(null, null, null);
+        return new question_classified_response(null, get_string('noresponse', 'question'), null);
     }
 }
 
index 7576669..d127c6e 100644 (file)
@@ -1107,6 +1107,28 @@ class question_type {
         }
     }
 
+    /**
+     * Move all the files belonging to this question's answers when the question
+     * is moved from one context to another.
+     * @param int $questionid the question being moved.
+     * @param int $oldcontextid the context it is moving from.
+     * @param int $newcontextid the context it is moving to.
+     * @param bool $answerstoo whether there is an 'answer' question area,
+     *      as well as an 'answerfeedback' one. Default false.
+     */
+    protected function move_files_in_combined_feedback($questionid, $oldcontextid,
+            $newcontextid) {
+        global $DB;
+        $fs = get_file_storage();
+
+        $fs->move_area_files_to_new_context($oldcontextid,
+                $newcontextid, 'question', 'correctfeedback', $questionid);
+        $fs->move_area_files_to_new_context($oldcontextid,
+                $newcontextid, 'question', 'partiallycorrectfeedback', $questionid);
+        $fs->move_area_files_to_new_context($oldcontextid,
+                $newcontextid, 'question', 'incorrectfeedback', $questionid);
+    }
+
     /**
      * Delete all the files belonging to this question.
      * @param int $questionid the question being deleted.
@@ -1139,6 +1161,25 @@ class question_type {
         }
     }
 
+    /**
+     * Delete all the files belonging to this question's answers.
+     * @param int $questionid the question being deleted.
+     * @param int $contextid the context the question is in.
+     * @param bool $answerstoo whether there is an 'answer' question area,
+     *      as well as an 'answerfeedback' one. Default false.
+     */
+    protected function delete_files_in_combined_feedback($questionid, $contextid) {
+        global $DB;
+        $fs = get_file_storage();
+
+        $fs->delete_area_files($contextid,
+                'question', 'correctfeedback', $questionid);
+        $fs->delete_area_files($contextid,
+                'question', 'partiallycorrectfeedback', $questionid);
+        $fs->delete_area_files($contextid,
+                'question', 'incorrectfeedback', $questionid);
+    }
+
     public function import_file($context, $component, $filearea, $itemid, $file) {
         $fs = get_file_storage();
         $record = new stdClass();
index 30ed13d..b458b4e 100644 (file)
@@ -79,6 +79,24 @@ h1.headerheading {margin:14px 11px 8px 11px;float:left;font-size:200%;}
 #page-enrol-instances .generalbox {border:none;}
 #page-enrol-instances .select.menujump {margin-left:0.5em;}
 
+/* environmenttable */
+.environmenttable .error {
+    background-color: red;
+}
+
+.environmenttable .warn {
+    background-color: yellow;
+}
+
+.environmenttable .ok {
+    background-color: lime;
+}
+
+/* adminsettings */
+#adminsettings .form-overridden {
+    background-color: yellow;
+}
+
 /* tables */
 .editcourse th,
 .editcourse td,
index 464638a..85c63b0 100644 (file)
@@ -161,23 +161,27 @@ function combo_send_uncached($content, $mimetype) {
     die;
 }
 
-function combo_not_found() {
+function combo_not_found($message = '') {
     header('HTTP/1.0 404 not found');
-    die('Combo resource not found, sorry.');
+    if ($message) {
+        echo $message;
+    } else {
+        echo 'Combo resource not found, sorry.';
+    }
+    die;
 }
 
 function combo_params() {
-    if (!empty($_SERVER['REQUEST_URI'])) {
-        $parts = explode('?', $_SERVER['REQUEST_URI']);
-        if (count($parts) != 2) {
-            return '';
-        }
+    // note: buggy or misconfigured IIS does return the query string in REQUEST_URL
+    if (isset($_SERVER['REQUEST_URI']) and strpos($_SERVER['REQUEST_URI'], '?') !== false) {
+        $parts = explode('?', $_SERVER['REQUEST_URI'], 2);
         return $parts[1];
 
-    } else if (!empty($_SERVER['QUERY_STRING'])) {
+    } else if (isset($_SERVER['QUERY_STRING'])) {
         return $_SERVER['QUERY_STRING'];
 
     } else {
-        return '';
+        // unsupported server, sorry!
+        combo_not_found('Unsupported server - query string can not be determined, try disabling YUI combo loading in admin settings.');
     }
 }