Merge branch 'MDL-28593' of git://github.com/timhunt/moodle
authorSam Hemelryk <sam@moodle.com>
Mon, 8 Aug 2011 03:04:19 +0000 (11:04 +0800)
committerSam Hemelryk <sam@moodle.com>
Mon, 8 Aug 2011 03:04:19 +0000 (11:04 +0800)
119 files changed:
admin/blocks.php
admin/cli/install.php
admin/cli/install_database.php
admin/index.php
admin/settings/appearance.php
admin/settings/security.php
admin/settings/server.php
auth/db/auth.php
auth/ldap/auth.php
backup/moodle2/backup_stepslib.php
backup/moodle2/restore_stepslib.php
backup/util/dbops/restore_dbops.class.php
cohort/index.php
comment/lib.php
config-dist.php
course/format/topics/lib.php
course/format/weeks/lib.php
course/lib.php
enrol/cohort/addinstance.php
enrol/cohort/ajax.php
enrol/cohort/lib.php
filter/mediaplugin/lang/en/filter_mediaplugin.php
filter/mediaplugin/styles.css
install.php
install/css.php [new file with mode: 0644]
install/lang/bg/install.php
install/lang/fr/install.php
lang/en/admin.php
lang/en/question.php
lib/accesslib.php
lib/adminlib.php
lib/blocklib.php
lib/cronlib.php
lib/datalib.php
lib/db/access.php
lib/db/upgrade.php
lib/db/upgradelib.php
lib/deprecatedlib.php
lib/dml/pgsql_native_moodle_database.php
lib/externallib.php
lib/filebrowser/file_info_context_course.php
lib/filebrowser/file_info_context_module.php
lib/formslib.php
lib/grouplib.php
lib/installlib.php
lib/javascript-static.js
lib/moodlelib.php
lib/navigationlib.php
lib/outputrequirementslib.php
lib/pagelib.php
lib/pear/HTML/QuickForm.php
lib/pear/README_MOODLE.txt
lib/pluginlib.php
lib/sessionlib.php
lib/setuplib.php
lib/simpletest/testformslib.php [new file with mode: 0644]
local/qeupgradehelper/afterupgradelib.php
message/lib.php
mod/assignment/lang/en/assignment.php
mod/choice/lang/en/choice.php
mod/choice/mod_form.php
mod/choice/version.php
mod/quiz/db/upgrade.php
mod/quiz/edit.php
mod/quiz/editlib.php
mod/quiz/renderer.php
mod/quiz/report/overview/lang/en/quiz_overview.php
mod/quiz/report/statistics/report.php
mod/quiz/report/statistics/responseanalysis.php
mod/quiz/styles.css
mod/scorm/datamodels/scorm_13.js.php
mod/scorm/db/install.xml
mod/scorm/db/upgrade.php
mod/scorm/lang/en/scorm.php
mod/scorm/locallib.php
mod/scorm/mod_form.php
mod/scorm/module.js
mod/scorm/version.php
mod/scorm/view.php
mod/url/lang/en/url.php
mod/url/mod_form.php
pix/i/flagged.png
pix/i/unflagged.png
question/category.php
question/edit.php
question/editlib.php
question/engine/lib.php
question/engine/renderer.php
question/export.php
question/flags.js
question/format/aiken/format.php
question/import.php
question/question.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
repository/lib.php
repository/youtube/lib.php
theme/arialist/config.php
theme/base/style/question.css
theme/binarius/config.php
theme/boxxie/config.php
theme/brick/config.php
theme/canvas/config.php
theme/canvas/style/core.css
theme/formfactor/config.php
theme/fusion/config.php
theme/index.php
theme/leatherbound/config.php
theme/magazine/config.php
theme/nimble/config.php
theme/nonzero/config.php
theme/overlay/config.php
theme/serenity/config.php
theme/sky_high/config.php
theme/yui_combo.php
version.php

index 17b0350..b4fa841 100644 (file)
@@ -12,6 +12,8 @@
     $hide     = optional_param('hide', 0, PARAM_INT);
     $show     = optional_param('show', 0, PARAM_INT);
     $delete   = optional_param('delete', 0, PARAM_INT);
+    $unprotect = optional_param('unprotect', 0, PARAM_INT);
+    $protect = optional_param('protect', 0, PARAM_INT);
 
 /// Print headings
 
@@ -24,6 +26,9 @@
     $strcourses = get_string('blockinstances', 'admin');
     $strname = get_string('name');
     $strshowblockcourse = get_string('showblockcourse');
+    $strprotecthdr = get_string('blockprotect', 'admin'). $OUTPUT->help_icon('blockprotect','admin');
+    $strprotect = get_string('blockprotect', 'admin');
+    $strunprotect = get_string('blockunprotect', 'admin');
 
 /// If data submitted, then process and store.
 
         admin_get_root(true, false);  // settings not required - only pages
     }
 
+    if (!isset($CFG->undeletableblocktypes) || (!is_array($CFG->undeletableblocktypes) && !is_string($CFG->undeletableblocktypes))) {
+        $undeletableblocktypes = array('navigation', 'settings');
+    } else if (is_string($CFG->undeletableblocktypes)) {
+        $undeletableblocktypes = explode(',', $CFG->undeletableblocktypes);
+    } else {
+        $undeletableblocktypes = $CFG->undeletableblocktypes;
+    }
+
+    if (!empty($protect) && confirm_sesskey()) {
+        if (!$block = $DB->get_record('block', array('id'=>$protect))) {
+            print_error('blockdoesnotexist', 'error');
+        }
+        if (!in_array($block->name, $undeletableblocktypes)) {
+            $undeletableblocktypes[] = $block->name;
+            set_config('undeletableblocktypes', implode(',', $undeletableblocktypes));
+        }
+        admin_get_root(true, false);  // settings not required - only pages
+    }
+
+    if (!empty($unprotect) && confirm_sesskey()) {
+        if (!$block = $DB->get_record('block', array('id'=>$unprotect))) {
+            print_error('blockdoesnotexist', 'error');
+        }
+        if (in_array($block->name, $undeletableblocktypes)) {
+            $undeletableblocktypes = array_diff($undeletableblocktypes, array($block->name));
+            set_config('undeletableblocktypes', implode(',', $undeletableblocktypes));
+        }
+        admin_get_root(true, false);  // settings not required - only pages
+    }
+
     if (!empty($delete) && confirm_sesskey()) {
         echo $OUTPUT->header();
         echo $OUTPUT->heading($strmanageblocks);
 
     $table = new flexible_table('admin-blocks-compatible');
 
-    $table->define_columns(array('name', 'instances', 'version', 'hideshow', 'delete', 'settings'));
-    $table->define_headers(array($strname, $strcourses, $strversion, $strhide.'/'.$strshow, $strdelete, $strsettings));
+    $table->define_columns(array('name', 'instances', 'version', 'hideshow', 'undeletable', 'delete', 'settings'));
+    $table->define_headers(array($strname, $strcourses, $strversion, $strhide.'/'.$strshow, $strprotecthdr, $strdelete, $strsettings));
     $table->define_baseurl($CFG->wwwroot.'/'.$CFG->admin.'/blocks.php');
     $table->set_attribute('class', 'compatibleblockstable blockstable generaltable');
     $table->setup();
             $version = "$block->version ($plugin->version)";
         }
 
+        if (!$blockobject) {
+            // ignore
+            $undeletable = '';
+        } else if (in_array($blockname, $undeletableblocktypes)) {
+            $undeletable = '<a href="blocks.php?unprotect='.$blockid.'&amp;sesskey='.sesskey().'" title="'.$strunprotect.'">'.
+                       '<img src="'.$OUTPUT->pix_url('t/unlock') . '" class="icon" alt="'.$strunprotect.'" /></a>';
+        } else {
+            $undeletable = '<a href="blocks.php?protect='.$blockid.'&amp;sesskey='.sesskey().'" title="'.$strprotect.'">'.
+                       '<img src="'.$OUTPUT->pix_url('t/unlock_gray') . '" class="icon" alt="'.$strprotect.'" /></a>';
+        }
 
         $table->add_data(array(
             '<span'.$class.'>'.$strblockname.'</span>',
             $blocklist,
             '<span'.$class.'>'.$version.'</span>',
             $visible,
+            $undeletable,
             $delete,
             $settings
         ));
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 ac58928..44412ec 100644 (file)
@@ -46,6 +46,8 @@ Options:
 --adminuser=USERNAME  Username for the moodle admin account. Default is admin.
 --adminpass=PASSWORD  Password for the moodle admin account.
 --agree-license       Indicates agreement with software license.
+--fullname            Name of the site
+--shortname           Name of the site
 -h, --help            Print out this help
 
 Example:
@@ -53,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
@@ -66,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
@@ -93,6 +95,8 @@ list($options, $unrecognized) = cli_get_params(
         'lang'              => 'en',
         'adminuser'         => 'admin',
         'adminpass'         => '',
+        'fullname'          => '',
+        'shortname'         => '',
         'agree-license'     => false,
         'help'              => false
     ),
index 77c0404..0580d91 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;
 }
 
index dc2ba27..6b251fb 100644 (file)
@@ -91,6 +91,7 @@ if ($hassiteconfig) { // speedup for non-admins, add all caps used on this page
     $temp->add(new admin_setting_configcheckbox('navshowcategories', get_string('navshowcategories', 'admin'), get_string('confignavshowcategories', 'admin'), 1));
     $temp->add(new admin_setting_configcheckbox('navshowallcourses', get_string('navshowallcourses', 'admin'), get_string('confignavshowallcourses', 'admin'), 0));
     $temp->add(new admin_setting_configtext('navcourselimit',get_string('navcourselimit','admin'),get_string('confignavcourselimit', 'admin'),20,PARAM_INT));
+    $temp->add(new admin_setting_configcheckbox('navlinkcoursesections', get_string('navlinkcoursesections', 'admin'), get_string('navlinkcoursesections_help', 'admin'), 0));
 
     $ADMIN->add('appearance', $temp);
 
index b2b264c..b72333c 100644 (file)
@@ -72,6 +72,7 @@ if ($hassiteconfig) { // speedup for non-admins, add all caps used on this page
     $temp->add(new admin_setting_configcheckbox('disableuserimages', get_string('disableuserimages', 'admin'), get_string('configdisableuserimages', 'admin'), 0));
     $temp->add(new admin_setting_configcheckbox('emailchangeconfirmation', get_string('emailchangeconfirmation', 'admin'), get_string('configemailchangeconfirmation', 'admin'), 1));
     $temp->add(new admin_setting_configselect('rememberusername', get_string('rememberusername','admin'), get_string('rememberusername_desc','admin'), 2, array(1=>get_string('yes'), 0=>get_string('no'), 2=>get_string('optional'))));
+    $temp->add(new admin_setting_configcheckbox('strictformsrequired', get_string('strictformsrequired', 'admin'), get_string('configstrictformsrequired', 'admin'), 0));
     $ADMIN->add('security', $temp);
 
 
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 8f60cc3..931b4d2 100644 (file)
@@ -230,11 +230,11 @@ class auth_plugin_db extends auth_plugin_base {
             if (count($userlist)) {
                 list($notin_sql, $params) = $DB->get_in_or_equal($userlist, SQL_PARAMS_NAMED, 'u', false);
                 $params['authtype'] = $this->authtype;
-                $sql = "SELECT u.id, u.username, u.email, u.auth
+                $sql = "SELECT u.*
                           FROM {user} u
                          WHERE u.auth=:authtype AND u.deleted=0 AND u.username $notin_sql";
             } else {
-                $sql = "SELECT u.id, u.username, u.email, u.auth
+                $sql = "SELECT u.*
                           FROM {user} u
                          WHERE u.auth=:authtype AND u.deleted=0";
                 $params = array();
index 447b6a6..9f2f03c 100644 (file)
@@ -689,7 +689,7 @@ class auth_plugin_ldap extends auth_plugin_base {
         // Find users in DB that aren't in ldap -- to be removed!
         // this is still not as scalable (but how often do we mass delete?)
         if ($this->config->removeuser !== AUTH_REMOVEUSER_KEEP) {
-            $sql = 'SELECT u.id, u.username, u.email, u.auth
+            $sql = 'SELECT u.*
                       FROM {user} u
                       LEFT JOIN {tmp_extuser} e ON (u.username = e.username AND u.mnethostid = e.mnethostid)
                      WHERE u.auth = ?
index ffc310e..d1b5d24 100644 (file)
@@ -319,8 +319,9 @@ class backup_module_structure_step extends backup_structure_step {
         // attach format plugin structure to $module element, only one allowed
         $this->add_plugin_structure('format', $module, false);
 
-        // attach plagiarism plugin structure to $module element, only one allowed
-        $this->add_plugin_structure('plagiarism', $module, false);
+        // attach plagiarism plugin structure to $module element, there can be potentially
+        // many plagiarism plugins storing information about this course
+        $this->add_plugin_structure('plagiarism', $module, true);
 
         // Define the tree
         $module->add_child($availinfo);
@@ -421,8 +422,9 @@ class backup_course_structure_step extends backup_structure_step {
         // course reports can save course data if required
         $this->add_plugin_structure('coursereport', $course, true);
 
-        // attach plagiarism plugin structure to $course element, only one allowed
-        $this->add_plugin_structure('plagiarism', $course, false);
+        // attach plagiarism plugin structure to $course element, there can be potentially
+        // many plagiarism plugins storing information about this course
+        $this->add_plugin_structure('plagiarism', $course, true);
 
         // Build the tree
 
index db7740a..0b02c01 100644 (file)
@@ -2371,11 +2371,13 @@ class restore_create_categories_and_questions extends restore_structure_step {
 
         $category = new restore_path_element('question_category', '/question_categories/question_category');
         $question = new restore_path_element('question', '/question_categories/question_category/questions/question');
+        $hint = new restore_path_element('question_hint',
+                '/question_categories/question_category/questions/question/question_hints/question_hint');
 
         // Apply for 'qtype' plugins optional paths at question level
         $this->add_plugin_structure('qtype', $question);
 
-        return array($category, $question);
+        return array($category, $question, $hint);
     }
 
     protected function process_question_category($data) {
@@ -2484,11 +2486,11 @@ class restore_create_categories_and_questions extends restore_structure_step {
             // Adjust some columns
             $data->questionid = $newquestionid;
             // Insert record
-            $newitemid = $DB->insert_record('question_answers', $data);
+            $newitemid = $DB->insert_record('question_hints', $data);
 
-        // The question existed, we need to map the existing question_answers
+        // The question existed, we need to map the existing question_hints
         } else {
-            // Look in question_answers by answertext matching
+            // Look in question_hints by hint text matching
             $sql = 'SELECT id
                       FROM {question_hints}
                      WHERE questionid = ?
@@ -2496,7 +2498,7 @@ class restore_create_categories_and_questions extends restore_structure_step {
             $params = array($newquestionid, $data->hint);
             $newitemid = $DB->get_field_sql($sql, $params);
             // If we haven't found the newitemid, something has gone really wrong, question in DB
-            // is missing answers, exception
+            // is missing hints, exception
             if (!$newitemid) {
                 $info = new stdClass();
                 $info->filequestionid = $oldquestionid;
@@ -2505,7 +2507,7 @@ class restore_create_categories_and_questions extends restore_structure_step {
                 throw new restore_step_exception('error_question_hint_missing_in_db', $info);
             }
         }
-        // Create mapping (we'll use this intensively when restoring question_states. And also answerfeedback files)
+        // Create mapping (I'm not sure if this is really needed?)
         $this->set_mapping('question_hint', $oldid, $newitemid);
     }
 
@@ -2635,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 0b405c8..9f6f2f6 100644 (file)
@@ -1340,7 +1340,8 @@ abstract class restore_dbops {
         $course->sortorder = 0;
         $course->timecreated  = time();
         $course->timemodified = $course->timecreated;
-        $course->visible = $category->visible;
+        // forcing skeleton courses to be hidden instead of going by $category->visible , until MDL-27790 is resolved.
+        $course->visible = 0;
 
         $courseid = $DB->insert_record('course', $course);
 
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 184e320..2d90ba7 100644 (file)
@@ -126,15 +126,6 @@ class comment {
      * @var int
      */
     protected $totalcommentcount = null;
-    /**
-     * When set to true any user to the system is able to view comments.
-     *
-     * This can be set to true by a plugin by implementing a allow_anonymous_access callback.
-     * By default it is false except on the front page.
-     *
-     * @var bool
-     */
-    protected $allowanonymousaccess = false;
 
     /**#@+
      * static variable will be used by non-js comments UI
@@ -240,18 +231,6 @@ class comment {
         $this->comment_param->commentarea = $this->commentarea;
         $this->comment_param->itemid      = $this->itemid;
 
-        $this->allowanonymousaccess = false;
-        // By default everyone can view comments on the front page
-        if ($this->context->contextlevel == CONTEXT_COURSE && $this->context->instanceid == SITEID) {
-            $this->allowanonymousaccess = true;
-        } else if ($this->context->contextlevel == CONTEXT_MODULE && $this->courseid == SITEID) {
-            $this->allowanonymousaccess = true;
-        }
-        if (!empty($this->plugintype) && !empty($this->pluginname)) {
-            // Plugins can override this if they wish.
-            $this->allowanonymousaccess = plugin_callback($this->plugintype, $this->pluginname, 'comment', 'allow_anonymous_access', array($this), $this->allowanonymousaccess);
-        }
-
         // setup notoggle
         if (!empty($options->notoggle)) {
             $this->set_notoggle($options->notoggle);
@@ -361,13 +340,8 @@ class comment {
         $this->viewcap = has_capability('moodle/comment:view', $this->context);
         if (!empty($this->plugintype)) {
             $permissions = plugin_callback($this->plugintype, $this->pluginname, 'comment', 'permissions', array($this->comment_param), array('post'=>false, 'view'=>false));
-            if ($this->allowanonymousaccess) {
-                $this->postcap = $permissions['post'];
-                $this->viewcap = $permissions['view'];
-            } else {
-                $this->postcap = $this->postcap && $permissions['post'];
-                $this->viewcap = $this->viewcap && $permissions['view'];
-            }
+            $this->postcap = $this->postcap && $permissions['post'];
+            $this->viewcap = $this->viewcap && $permissions['view'];
         }
     }
 
index 61c4e20..4ca2b72 100644 (file)
@@ -208,11 +208,6 @@ $CFG->admin = 'admin';
 // These blocks are used when no other default setting is found.
 //      $CFG->defaultblocks = 'participants,activity_modules,search_forums,admin,course_list:news_items,calendar_upcoming,recent_activity';
 //
-// The blocks in this list will be protected from deletion, and this is primarily
-// used to protect the navigation and settings blocks which can be very hard to
-// get back if accidentally delete.
-//      $CFG->undeletableblocktypes = 'navigation,settings';
-//
 // You can specify a different class to be created for the $PAGE global, and to
 // compute which blocks appear on each page. However, I cannot think of any good
 // reason why you would need to change that. It just felt wrong to hard-code the
index c80b518..9bd94d4 100644 (file)
@@ -90,3 +90,14 @@ function callback_topics_ajax_support() {
     $ajaxsupport->testedbrowsers = array('MSIE' => 6.0, 'Gecko' => 20061111, 'Safari' => 531, 'Chrome' => 6.0);
     return $ajaxsupport;
 }
+
+/**
+ * Returns a URL to arrive directly at a section
+ *
+ * @param int $courseid The id of the course to get the link for
+ * @param int $sectionnum The section number to jump to
+ * @return moodle_url
+ */
+function callback_topics_get_section_url($courseid, $sectionnum) {
+    return new moodle_url('/course/view.php', array('id' => $courseid, 'topic' => $sectionnum));
+}
\ No newline at end of file
index e37454f..34fd501 100644 (file)
@@ -112,3 +112,14 @@ function callback_weeks_ajax_support() {
     $ajaxsupport->testedbrowsers = array('MSIE' => 6.0, 'Gecko' => 20061111, 'Safari' => 531, 'Chrome' => 6.0);
     return $ajaxsupport;
 }
+
+/**
+ * Returns a URL to arrive directly at a section
+ *
+ * @param int $courseid The id of the course to get the link for
+ * @param int $sectionnum The section number to jump to
+ * @return moodle_url
+ */
+function callback_weeks_get_section_url($courseid, $sectionnum) {
+    return new moodle_url('/course/view.php', array('id' => $courseid, 'week' => $sectionnum));
+}
index 968d68f..35be49b 100644 (file)
@@ -565,7 +565,7 @@ function print_log_csv($course, $user, $date, $order='l.time DESC', $modname,
     header("Pragma: public");
 
     echo get_string('savedat').userdate(time(), $strftimedatetime)."\n";
-    echo $text;
+    echo $text."\n";
 
     if (empty($logs['logs'])) {
         return true;
@@ -2472,7 +2472,7 @@ function print_course($course, $highlightterms = '') {
         $course->summaryformat = FORMAT_MOODLE;
     }
     echo highlight($highlightterms, format_text($course->summary, $course->summaryformat, $options,  $course->id));
-    if ((!isloggedin() || is_siteadmin()) && $icons = enrol_get_course_info_icons($course)) {
+    if ($icons = enrol_get_course_info_icons($course)) {
         echo html_writer::start_tag('div', array('class'=>'enrolmenticons'));
         foreach ($icons as $icon) {
             echo $OUTPUT->render($icon);
index d35e098..bafb716 100644 (file)
@@ -35,6 +35,7 @@ $context = get_context_instance(CONTEXT_COURSE, $course->id, MUST_EXIST);
 
 require_login($course);
 require_capability('moodle/course:enrolconfig', $context);
+require_capability('enrol/cohort:config', $context);
 
 $PAGE->set_url('/enrol/cohort/addinstance.php', array('id'=>$course->id));
 $PAGE->set_pagelayout('admin');
index 83888a8..ccb8412 100644 (file)
@@ -74,6 +74,7 @@ switch ($action) {
         break;
     case 'enrolcohort':
         require_capability('moodle/course:enrolconfig', $context);
+        require_capability('enrol/cohort:config', $context);
         $roleid = required_param('roleid', PARAM_INT);
         $cohortid = required_param('cohortid', PARAM_INT);
         
@@ -87,10 +88,16 @@ switch ($action) {
         enrol_cohort_sync($manager->get_course()->id);
         break;
     case 'enrolcohortusers':
-        require_capability('moodle/course:enrolconfig', $context);
+        require_capability('enrol/manual:enrol', $context);
         $roleid = required_param('roleid', PARAM_INT);
         $cohortid = required_param('cohortid', PARAM_INT);
         $result = enrol_cohort_enrol_all_users($manager, $cohortid, $roleid);
+
+        $roles = $manager->get_assignable_roles();
+        $cohorts = enrol_cohort_get_cohorts($manager);
+        if (!array_key_exists($cohortid, $cohorts) || !array_key_exists($roleid, $roles)) {
+            throw new enrol_ajax_exception('errorenrolcohort');
+        }
         if ($result === false) {
             throw new enrol_ajax_exception('errorenrolcohortusers');
         }
index aa0c320..d8cd4e1 100644 (file)
@@ -163,7 +163,7 @@ class enrol_cohort_plugin extends enrol_plugin {
         $button->strings_for_js('users', 'moodle');
 
         // No point showing this at all if the user cant manually enrol users
-        $hasmanualinstance = has_capability('enrol/manual:manage', $manager->get_context()) && $manager->has_instance('manual');
+        $hasmanualinstance = has_capability('enrol/manual:enrol', $manager->get_context()) && $manager->has_instance('manual');
 
         $modules = array('moodle-enrol_cohort-quickenrolment', 'moodle-enrol_cohort-quickenrolment-skin');
         $function = 'M.enrol_cohort.quickenrolment.init';
index de7e98e..94062fa 100644 (file)
@@ -28,7 +28,7 @@ $string['filtername'] = 'Multimedia plugins';
 $string['flashanimation'] = 'Flash animation';
 $string['flashanimation_help'] = 'Files with extension *.swf. For security reasons this filter is used only in trusted texts.';
 $string['flashvideo'] = 'Flash video';
-$string['flashvideo_help'] = 'Files with extension *.flv and *.f4v. Plays video clips using Flowplayer, requires Flash plugin and javascript. Uses HTML 5 video fallback if multiple sources psecified.';
+$string['flashvideo_help'] = 'Files with extension *.flv and *.f4v. Plays video clips using Flowplayer, requires Flash plugin and javascript. Uses HTML 5 video fallback if multiple sources specified.';
 $string['html5audio'] = 'HTML 5 audio';
 $string['html5audio_help'] = 'Audio files with extension *.ogg, *.aac and others. It is compatible with latest web browsers only, unfortunately there is no format that is supported by all browsers.
 Workaround is to specify fallbacks separated with # (ex: http://example.org/audio.aac#http://example.org/audio.aac#http://example.org/audio.mp3#), QuickTime player is used as a fallback for old browsers, fallback can be any audio type.';
index bb39c83..a1283ce 100644 (file)
@@ -11,4 +11,4 @@
  * see http://flowplayer.org/documentation/skinning/controlbar.html?skin=default for more color properties,
  * any property that ends with '...Color' is supported here.
  */
-.mp3flowplayer_backgroundColor {color: #000000};
+.mp3flowplayer_backgroundColor {color: #000000;}
index b615587..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;
     }
@@ -217,11 +229,6 @@ if (isset($_GET['help'])) {
     install_print_help_page($_GET['help']);
 }
 
-// send css?
-if (isset($_GET['css'])) {
-    install_css_styles();
-}
-
 //first time here? find out suitable dataroot
 if (is_null($CFG->dataroot)) {
     $CFG->dataroot = dirname(dirname(__FILE__)).DIRECTORY_SEPARATOR.'moodledata';
@@ -486,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
 
@@ -499,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) {
diff --git a/install/css.php b/install/css.php
new file mode 100644 (file)
index 0000000..16bfaba
--- /dev/null
@@ -0,0 +1,148 @@
+<?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/>.
+
+/**
+ * This script prints basic CSS for the installer
+ *
+ * @package    core
+ * @subpackage install
+ * @copyright  2011 Petr Skoda (http://skodak.org)
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+if (file_exists(dirname(dirname(__FILE__)).'/config.php')) {
+    // already installed
+    die;
+}
+
+// include only the necessary stuff from themes, keep this small otherwise IE will complain...
+$files = array(
+        'base/style/pagelayout.css',
+        'base/style/core.css',
+        'standard/style/core.css',
+        'standard/style/css3.css');
+
+
+$content = '';
+
+foreach($files as $file) {
+    $content .= file_get_contents(dirname(dirname(__FILE__)).'/theme/'.$file) . "\n";
+}
+
+$content .= "
+
+h2 {
+  text-align:center;
+}
+
+#installdiv {
+  width: 800px;
+  margin-left:auto;
+  margin-right:auto;
+}
+
+#installdiv dt {
+  font-weight: bold;
+}
+
+#installdiv dd {
+  padding-bottom: 0.5em;
+}
+
+.stage {
+  margin-top: 2em;
+  margin-bottom: 2em;
+  width: 100%;
+  padding:25px;
+}
+
+#installform {
+  width: 100%;
+}
+
+#nav_buttons input {
+  margin: 5px;
+}
+
+#envresult {
+  text-align:left;
+  width: auto;
+  margin-left:10em;
+}
+
+#envresult dd {
+  color: red;
+}
+
+.formrow {
+  clear:both;
+  text-align:left;
+  padding: 8px;
+}
+
+.formrow label.formlabel {
+  display:block;
+  float:left;
+  width: 260px;
+  margin-right:5px;
+  text-align:right;
+}
+
+.formrow .forminput {
+  display:block;
+  float:left;
+}
+
+fieldset {
+  text-align:center;
+  border:none;
+}
+
+.hint {
+  display:block;
+  clear:both;
+  padding-left: 265px;
+  color: red;
+}
+
+.configphp {
+  text-align:left;
+  background-color:white;
+  padding:1em;
+  width:95%;
+}
+
+.stage6 .stage {
+  font-weight: bold;
+  color: red;
+}
+
+";
+
+// fix used urls
+$content = str_replace('[[pix:theme|hgradient]]', '../theme/standard/pix/hgradient.jpg', $content);
+$content = str_replace('[[pix:theme|vgradient]]', '../theme/standard/pix/vgradient.jpg', $content);
+
+@header('Content-Disposition: inline; filename="css.php"');
+@header('Cache-Control: no-store, no-cache, must-revalidate');
+@header('Cache-Control: post-check=0, pre-check=0', false);
+@header('Pragma: no-cache');
+@header('Expires: Mon, 20 Aug 1969 09:23:00 GMT');
+@header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
+@header('Accept-Ranges: none');
+@header('Content-Type: text/css; charset=utf-8');
+
+echo $content;
index 450193b..0112203 100644 (file)
 $string['availablelangs'] = 'Списък на наличните езици';
 $string['chooselanguagehead'] = 'Изберете език';
 $string['chooselanguagesub'] = 'Моля, изберете език за инсталацията. Този език ще бъде, също така, език по подразбиране на сайта, но може да бъде променен и по-късно след инсталирането.';
+$string['databasehost'] = 'Хост на базата данни';
+$string['databasename'] = 'Потребителско име за базата данни';
+$string['databasetypehead'] = 'Избиране на драйвер за база данни';
 $string['dataroot'] = 'Директория за данни';
+$string['dbprefix'] = 'Представка на таблиците';
 $string['dirroot'] = 'Директория на Moodle';
 $string['installation'] = 'Инсталиране';
 $string['paths'] = 'Пътища';
 $string['pathshead'] = 'Потвърждаване на пътищата';
 $string['pathssubdataroot'] = 'Тази директория е място, където Moodle, записва качваните файлове. Тази директория трябва да е достъпна за четене И ЗА ЗАПИС от потребителя на интернет сървъра (обикновено \'nobody\' или \'apache\'), но не трябва да е достъпна пряко през Интернет. Инталаторът ще се опита да създаде директорията, ако тя не съществува.';
 $string['pathssubdirroot'] = 'Пълен път до директорията на Moodle.';
-$string['pathssubwwwroot'] = 'Пълен интернет адрес, на който ще се отваря Moodle. Не е възможно Moodle да се отваря чрез различни адреси. Ако Вашият сайт има няколко адреса трябва на всеки от другите адреси да направите HTML пренасочване към този. Ако Вашият сайт се отваря както глобално от Интернет, така и от локална мрежа, настройте DNS така че потребителите от локалната мрежа също да могат да ползват глобалния адрес. Ако адресът не е коректен, моля, променете адреса в браузъра си и започнете инсталирането с правилния адрес.';
+$string['pathssubwwwroot'] = 'Пълен интернет адрес, на който ще се отваря Moodle. Не е възможно Moodle да се отваря чрез различни адреси. Ако Вашият сайт има няколко адреса трябва на всеки от другите адреси да направите пренасочване към този. Ако Вашият сайт се отваря както глобално от Интернет, така и от локална мрежа, настройте DNS, така че потребителите от локалната мрежа също да могат да ползват глобалния адрес. Ако адресът не е коректен, моля, променете адреса в браузъра си и започнете инсталирането с правилния адрес.';
 $string['wwwroot'] = 'Уеб адрес';
index adcc85a..012f814 100644 (file)
@@ -45,11 +45,15 @@ $string['environmentsub2'] = 'Chaque version de Moodle nécessite une version mi
 $string['errorsinenvironment'] = 'Échec de la vérification de l\'environnement !';
 $string['installation'] = 'Installation';
 $string['langdownloaderror'] = 'La langue {$a} n\'a pas pu être téléchargée. La suite de l\'installation se déroulera en anglais. Vous pourrez télécharger et installer d\'autres langues à la fin de l\'installation';
-$string['memorylimithelp'] = '<p>La limite de mémoire de PHP sur votre serveur est actuellement de {$a}.</p><p>Cette valeur trop basse risque de générer des problèmes de manque de mémoire pour Moodle, notamment si vous utilisez beaucoup de modules et/ou si vous avez un grand nombre d\'utilisateurs.</p><p>Il est recommandé de configurer PHP avec une limite de mémoire aussi élevée que possible, par exemple 40 Mo. Vous pouvez obtenir cela de différentes façons :</p>
+$string['memorylimithelp'] = '<p>La limite de mémoire de PHP sur votre serveur est actuellement de {$a}.</p>
+<p>Cette valeur trop basse risque de générer des problèmes de manque de mémoire pour Moodle, notamment si vous utilisez beaucoup de modules et/ou si vous avez un grand nombre d\'utilisateurs.</p>
+<p>Il est recommandé de configurer PHP avec une limite de mémoire aussi élevée que possible, par exemple 40 Mo. Vous pouvez obtenir cela de différentes façons :</p>
 <ol>
 <li>si vous en avez la possibilité, recompilez PHP avec l\'option <em>--enable-memory-limit</em>. Cela permettra à Moodle de fixer lui-même sa limite de mémoire ;</li>
 <li>si vous avez accès à votre fichier « php.ini », vous pouvez attribuer au paramètre <b>memory_limit</b> une valeur comme 40M. Si vous n\'y avez pas accès, demandez à l\'administrateur de le faire pour vous ;</li>
-<li>sur certains serveurs, vous pouvez créer dans le dossier principal de Moodle un fichier « .htaccess » contenant cette ligne : <blockquote><div>php_value memory_limit 40M</div></blockquote><p>Cependant, sur certains serveurs, cela empêchera le fonctionnement correct de <b>tous</b> les fichiers PHP (vous verrez s\'afficher des erreurs lors de la consultation de pages). Dans ce cas, vous devrez supprimer le fichier « .htaccess ».</li>
+<li>sur certains serveurs, vous pouvez créer dans le dossier principal de Moodle un fichier « .htaccess » contenant cette ligne :
+<blockquote><div>php_value memory_limit 40M</div></blockquote>
+<p>Cependant, sur certains serveurs, cela empêchera le fonctionnement correct de <b>tous</b> les fichiers PHP (vous verrez s\'afficher des erreurs lors de la consultation de pages). Dans ce cas, vous devrez supprimer le fichier « .htaccess ».</p></li>
 </ol>';
 $string['paths'] = 'Chemins';
 $string['pathserrcreatedataroot'] = 'Le dossier de données ({$a->dataroot}) ne peut pas être créé par l\'installeur.';
@@ -67,7 +71,7 @@ $string['phpversion'] = 'Version de PHP';
 $string['phpversionhelp'] = '<p>Moodle nécessite au minimum la version 4.3.0 ou 5.1.0 (5.0.x a bon nombre de problèmes).</p><p>Vous utilisez actuellement la version {$a}.</p><p>Pour que Moodle fonctionne, vous devez mettre à jour PHP ou aller chez un hébergeur ayant une version récente de PHP.<br />(Si vous avez une version 5.0.x, vous pouvez aussi re-passer à la version 4.4.x)</p>';
 $string['welcomep10'] = '{$a->installername} ({$a->installerversion})';
 $string['welcomep20'] = 'Vous voyez cette page, car vous avez installé Moodle correctement et lancé le logiciel <b>{$a->packname} {$a->packversion}</b> sur votre ordinateur. Félicitations !';
-$string['welcomep30'] = 'Cette version du paquet <b>{$a->installername}</b> comprend des logiciels qui créent un environnement dans lequel <b>Moodle</b> va fonctionner, à savoir :';
+$string['welcomep30'] = 'Cette version de <b>{$a->installername}</b> comprend des logiciels qui créent un environnement dans lequel <b>Moodle</b> va fonctionner, à savoir :';
 $string['welcomep40'] = 'Ce paquet contient également <b>Moodle {$a->moodlerelease} ({$a->moodleversion})</b>.';
 $string['welcomep50'] = 'L\'utilisation de tous les logiciels de ce paquet est soumis à l\'acceptation de leurs licences respectives. Le paquet <b>{$a->installername}</b> est un <a href="http://www.opensource.org/docs/definition_plain.html">logiciel libre</a>. Il est distribué sous licence <a href="http://www.gnu.org/copyleft/gpl.html">GPL</a>.';
 $string['welcomep60'] = 'Les pages suivantes vous aideront pas à pas à configurer et mettre en place <b>Moodle</b> sur votre ordinateur. Il vous sera possible d\'accepter les réglages par défaut ou, facultativement, de les adapter à vos propres besoins.';
index cec064f..77021d9 100644 (file)
@@ -72,6 +72,9 @@ $string['badwordslist'] = 'Custom bad words list';
 $string['blockediplist'] = 'Blocked IP List';
 $string['blockinstances'] = 'Instances';
 $string['blockmultiple'] = 'Multiple';
+$string['blockprotect'] = 'Protect from delete';
+$string['blockprotect_help'] = 'Selected block instances will be protected from deletion from the site-wide context. This is primarily used to protect the navigation and settings blocks which can be very hard to get back if accidentally deleted.';
+$string['blockunprotect'] = 'Unprotect';
 $string['blocksettings'] = 'Manage blocks';
 $string['bloglevel'] = 'Blog visibility';
 $string['bloglevelupgrade'] = 'Blog visibility upgrade';
@@ -330,6 +333,7 @@ $string['configstatsmaxruntime3'] = 'Specify the maximum time allowed to calcula
 $string['configstatsruntimedays'] = 'Specify the maximum number of days processed in each stats execution. When stats are up-to-date, only one day will be processed, so adjust this value depending of your server load, reducing it if shorter cron executions are needed.';
 $string['configstatsruntimestart'] = 'What time should the cronjob that does the stats processing <b>start</b>? Please specify different times if there are multiple Moodles on one physical server.';
 $string['configstatsuserthreshold'] = 'This setting specifies the minimum number of enrolled users for a course to be included in statistics calculations.';
+$string['configstrictformsrequired'] = 'If enabled, users are prevented from entering a space or line break only in required fields in forms.';
 $string['configstripalltitletags'] = 'Uncheck this setting to allow HTML tags in activity and resource names.';
 $string['configsupportemail'] = 'This email address will be published to users of this site as the one to email when they need general help (for example, when new users create their own accounts).  If this email is left blank then no such helpful email address is supplied.';
 $string['configsupportname'] = 'This is the name of a person or other entity offering general help via the support email or web address.';
@@ -728,6 +732,8 @@ $string['mysql416bypassed'] = 'However, if your site is using iso-8859-1 (latin)
 $string['mysql416required'] = 'MySQL 4.1.16 is the minimum version required for Moodle 1.6 in order to guarantee that all data can be converted to UTF-8 in the future.';
 $string['navigationupgrade'] = 'This upgrade introduces two new navigation blocks that will replace these blocks: Administration, Courses, Activities and Participants.  If you had set any special permissions on those blocks you should check to make sure everything is behaving as you want it.';
 $string['navcourselimit'] = 'Course limit';
+$string['navlinkcoursesections'] = 'Link course sections';
+$string['navlinkcoursesections_help'] = 'If enabled course sections will be shown as links within the navigation.';
 $string['navshowallcourses'] = 'Show all courses';
 $string['navshowcategories'] = 'Show course categories';
 $string['neverdeleteruns'] = 'Never delete runs';
@@ -958,6 +964,7 @@ $string['stickyblockscourseview'] = 'Course page';
 $string['stickyblocksduplicatenotice'] = 'If any block you add here is already present in a particular page, it will result in a duplicate.<br />Only the pinned block will be non-editable, the duplicate will still be editable.';
 $string['stickyblocksmymoodle'] = 'My Moodle';
 $string['stickyblockspagetype'] = 'Page type to configure';
+$string['strictformsrequired'] = 'Strict validation of required fields';
 $string['stripalltitletags'] = 'Remove HTML tags from all activity names';
 $string['supportcontact'] = 'Support contact';
 $string['supportemail'] = 'Support email';
index 13e17ec..7a3e794 100644 (file)
@@ -65,8 +65,10 @@ $string['categoryinfo'] = 'Category info';
 $string['categorymove'] = 'The category \'{$a->name}\' contains {$a->count} questions (some of them may be old, hidden, questions that are still in use in some existing quizzes). Please choose another category to move them to.';
 $string['categorymoveto'] = 'Save in category';
 $string['categorynamecantbeblank'] = 'The category name cannot be blank.';
-$string['clicktoflag'] = 'Click to flag this question';
-$string['clicktounflag'] = 'Click to un-flag this question';
+$string['clickflag'] = 'Flag question';
+$string['clicktoflag'] = 'Flag this question for future reference';
+$string['clicktounflag'] = 'Remove flag';
+$string['clickunflag'] = 'Remove flag';
 $string['contexterror'] = 'You shouldn\'t have got here if you\'re not moving a category to another context.';
 $string['copy'] = 'Copy from {$a} and change links.';
 $string['created'] = 'Created';
@@ -298,8 +300,6 @@ $string['category'] = 'Category';
 $string['changeoptions'] = 'Change options';
 $string['check'] = 'Check';
 $string['clearwrongparts'] = 'Clear incorrect responses';
-$string['clicktoflag'] = 'Click to flag this question';
-$string['clicktounflag'] = 'Click to un-flag this question';
 $string['closepreview'] = 'Close preview';
 $string['combinedfeedback'] = 'Combined feedback';
 $string['commented'] = 'Commented: {$a}';
index f56aecb..03d6cf9 100644 (file)
@@ -569,9 +569,9 @@ function has_capability($capability, $context, $user = null, $doanything = true)
 
     // make sure there is a real user specified
     if ($user === null) {
-        $userid = !empty($USER->id) ? $USER->id : 0;
+        $userid = isset($USER->id) ? $USER->id : 0;
     } else {
-        $userid = !empty($user->id) ? $user->id : $user;
+        $userid = is_object($user) ? $user->id : $user;
     }
 
     // capability must exist
@@ -2841,9 +2841,9 @@ function is_guest($context, $user = null) {
 
     // make sure there is a real user specified
     if ($user === null) {
-        $userid = !empty($USER->id) ? $USER->id : 0;
+        $userid = isset($USER->id) ? $USER->id : 0;
     } else {
-        $userid = !empty($user->id) ? $user->id : $user;
+        $userid = is_object($user) ? $user->id : $user;
     }
 
     if (isguestuser($userid)) {
@@ -2914,9 +2914,9 @@ function is_enrolled($context, $user = null, $withcapability = '', $onlyactive =
 
     // make sure there is a real user specified
     if ($user === null) {
-        $userid = !empty($USER->id) ? $USER->id : 0;
+        $userid = isset($USER->id) ? $USER->id : 0;
     } else {
-        $userid = !empty($user->id) ? $user->id : $user;
+        $userid = is_object($user) ? $user->id : $user;
     }
 
     if (empty($userid)) {
@@ -3395,6 +3395,12 @@ function update_capabilities($component = 'moodle') {
     $storedcaps = array();
 
     $filecaps = load_capability_def($component);
+    foreach($filecaps as $capname=>$unused) {
+        if (!preg_match('|^[a-z]+/[a-z_0-9]+:[a-z_0-9]+$|', $capname)) {
+            debugging("Coding problem: Invalid capability name '$capname', use 'clonepermissionsfrom' field for migration.");
+        }
+    }
+
     $cachedcaps = get_cached_capabilities($component);
     if ($cachedcaps) {
         foreach ($cachedcaps as $cachedcap) {
@@ -4518,9 +4524,9 @@ function get_assignable_roles($context, $rolenamedisplay = ROLENAME_ALIAS, $with
 
     // make sure there is a real user specified
     if ($user === null) {
-        $userid = !empty($USER->id) ? $USER->id : 0;
+        $userid = isset($USER->id) ? $USER->id : 0;
     } else {
-        $userid = !empty($user->id) ? $user->id : $user;
+        $userid = is_object($user) ? $user->id : $user;
     }
 
     if (!has_capability('moodle/role:assign', $context, $userid)) {
index 4ce6885..cf21bcf 100644 (file)
@@ -7863,9 +7863,10 @@ class admin_setting_configmultiselect_modules extends admin_setting_configmultis
      * @param string $name setting name
      * @param string $visiblename localised setting name
      * @param string $description setting description
+     * @param array $defaultsetting a plain array of default module ids
      */
-    public function __construct($name, $visiblename, $description) {
-        parent::__construct($name, $visiblename, $description, array(), null);
+    public function __construct($name, $visiblename, $description, $defaultsetting = array()) {
+        parent::__construct($name, $visiblename, $description, $defaultsetting, null);
     }
 
     /**
index 4c816c2..d8a1987 100644 (file)
@@ -997,9 +997,11 @@ class block_manager {
         global $CFG;
 
         if (!isset($CFG->undeletableblocktypes) || (!is_array($CFG->undeletableblocktypes) && !is_string($CFG->undeletableblocktypes))) {
-            $CFG->undeletableblocktypes = array('navigation','settings');
+            $undeletableblocktypes = array('navigation','settings');
         } else if (is_string($CFG->undeletableblocktypes)) {
-            $CFG->undeletableblocktypes = explode(',', $CFG->undeletableblocktypes);
+            $undeletableblocktypes = explode(',', $CFG->undeletableblocktypes);
+        } else {
+            $undeletableblocktypes = $CFG->undeletableblocktypes;
         }
 
         $controls = array();
@@ -1037,7 +1039,9 @@ class block_manager {
         }
 
         if ($this->page->user_can_edit_blocks() && $block->user_can_edit() && $block->user_can_addto($this->page)) {
-            if (!in_array($block->instance->blockname, $CFG->undeletableblocktypes)) {
+            if (!in_array($block->instance->blockname, $undeletableblocktypes)
+                    || !in_array($block->instance->pagetypepattern, array('*', 'site-index'))
+                    || $block->instance->parentcontextid != SITEID) {
                 // Delete icon.
                 $controls[] = array('url' => $actionurl . '&bui_deleteid=' . $block->instance->id,
                         'icon' => 't/delete', 'caption' => get_string('delete'));
index 9ccfc30..dc944a4 100644 (file)
@@ -219,7 +219,7 @@ function cron_run() {
 
         if (!empty($CFG->deleteincompleteusers)) {
             $cuttime = $timenow - ($CFG->deleteincompleteusers * 3600);
-            $rs = $DB->get_recordset_sql ("SELECT id, username
+            $rs = $DB->get_recordset_sql ("SELECT *
                                              FROM {user}
                                             WHERE confirmed = 1 AND lastaccess > 0
                                                   AND lastaccess < ? AND deleted = 0
index f4ba832..8aa1f84 100644 (file)
@@ -1662,6 +1662,8 @@ function add_to_log($courseid, $module, $action, $url='', $info='', $cm=0, $user
     $info = $info;
     if (!empty($url)) { // could break doing html_entity_decode on an empty var.
         $url = html_entity_decode($url);
+    } else {
+        $url = '';
     }
 
     // Restrict length of log lines to the space actually available in the
index 544ed5c..bc42449 100644 (file)
@@ -428,7 +428,6 @@ $capabilities = array(
         'contextlevel' => CONTEXT_COURSE,
         'archetypes' => array(
             'editingteacher' => CAP_ALLOW,
-            'coursecreator' => CAP_ALLOW,
             'manager' => CAP_ALLOW,
         )
     ),
@@ -1349,7 +1348,6 @@ $capabilities = array(
             'student' => CAP_ALLOW,
             'teacher' => CAP_ALLOW,
             'editingteacher' => CAP_ALLOW,
-            'coursecreator' => CAP_ALLOW,
             'manager' => CAP_ALLOW
         )
     ),
@@ -1619,7 +1617,6 @@ $capabilities = array(
             'student' => CAP_ALLOW,
             'teacher' => CAP_ALLOW,
             'editingteacher' => CAP_ALLOW,
-            'coursecreator' => CAP_ALLOW
         )
     ),
 
@@ -1630,7 +1627,6 @@ $capabilities = array(
         'contextlevel' => CONTEXT_BLOCK,
         'archetypes' => array(
             'editingteacher' => CAP_ALLOW,
-            'coursecreator' => CAP_ALLOW
         )
     ),
 
@@ -1642,19 +1638,18 @@ $capabilities = array(
             'student' => CAP_ALLOW,
             'teacher' => CAP_ALLOW,
             'editingteacher' => CAP_ALLOW,
-            'coursecreator' => CAP_ALLOW
         )
     ),
     'moodle/comment:view' => array(
-
         'captype' => 'read',
         'contextlevel' => CONTEXT_COURSE,
         'archetypes' => array(
+            'frontpage' => CAP_ALLOW,
+            'guest' => CAP_ALLOW,
             'user' => CAP_ALLOW,
             'student' => CAP_ALLOW,
             'teacher' => CAP_ALLOW,
             'editingteacher' => CAP_ALLOW,
-            'coursecreator' => CAP_ALLOW,
             'manager' => CAP_ALLOW
         )
     ),
@@ -1668,7 +1663,6 @@ $capabilities = array(
             'student' => CAP_ALLOW,
             'teacher' => CAP_ALLOW,
             'editingteacher' => CAP_ALLOW,
-            'coursecreator' => CAP_ALLOW,
             'manager' => CAP_ALLOW
         )
     ),
@@ -1679,7 +1673,6 @@ $capabilities = array(
         'contextlevel' => CONTEXT_COURSE,
         'archetypes' => array(
             'editingteacher' => CAP_ALLOW,
-            'coursecreator' => CAP_ALLOW,
             'manager' => CAP_ALLOW
         )
     ),
@@ -1766,7 +1759,6 @@ $capabilities = array(
         'archetypes' => array(
             'teacher' => CAP_ALLOW,
             'editingteacher' => CAP_ALLOW,
-            'coursecreator' => CAP_ALLOW,
             'manager' => CAP_ALLOW
         )
     ),
@@ -1777,7 +1769,6 @@ $capabilities = array(
             'manager' => CAP_ALLOW,
             'teacher' => CAP_ALLOW,
             'editingteacher' => CAP_ALLOW,
-            'coursecreator' => CAP_ALLOW
         )
     ),
     'moodle/community:download' => array(
@@ -1786,7 +1777,6 @@ $capabilities = array(
         'archetypes' => array(
             'manager' => CAP_ALLOW,
             'editingteacher' => CAP_ALLOW,
-            'coursecreator' => CAP_ALLOW
         )
     )
 );
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 96ccc3d..84ce362 100644 (file)
@@ -314,7 +314,9 @@ function upgrade_migrate_files_course($context, $path, $delete) {
 
         if ($item->isFile()) {
             if (!$item->isReadable()) {
-                echo $OUTPUT->notification(" File not readable, skipping: ".$fullpathname.$item->getFilename());
+                $notification = "File not readable, skipping: ".$fullpathname.$item->getFilename();
+                echo $OUTPUT->notification($notification);
+                upgrade_log(UPGRADE_LOG_NOTICE, null, $notification);
                 continue;
             }
 
@@ -327,8 +329,31 @@ function upgrade_migrate_files_course($context, $path, $delete) {
             }
 
             if ($textlib->strlen($filepath) > 255) {
-                echo $OUTPUT->notification(" File path longer than 255 chars, skipping: ".$fullpathname.$item->getFilename());
-                continue;
+                // we need something unique and reproducible, sorry no shortening possible
+                $filepath = '/directory_over_255_chars/'.md5($filepath).'/';
+                $oldfile = $fullpathname.$item->getFilename();
+                $newfile = $filepath.$item->getFilename();
+                $notification = "File path longer than 255 chars '$oldfile', file path truncated to '$newfile'";
+                echo $OUTPUT->notification($notification);
+                upgrade_log(UPGRADE_LOG_NOTICE, null, $notification);
+            }
+
+            if ($textlib->strlen($filename) > 255) {
+                //try to shorten, but look for collisions
+                $oldfile = $fullpathname.$item->getFilename();
+                $parts = explode('.', $filename);
+                $ext = array_pop($parts);
+                $name = implode('.', $parts);
+                $name = $textlib->substr($name, 0, 254-$textlib->strlen($ext));
+                $newfilename = $name . '.' . $ext;
+                if (file_exists($fullpathname.$newfilename) or $fs->file_exists($context->id, $component, $filearea, '0', $filepath, $newfilename)) {
+                    $filename = 'file_name_over_255_chars'.md5($filename).$ext; // bad luck, file with shortened name exists
+                } else {
+                    $filename = $newfilename; // shortened name should not cause collisions
+                }
+                $notification = "File name longer than 255 chars '$oldfile', file name truncated to '$filename'";
+                echo $OUTPUT->notification($notification);
+                upgrade_log(UPGRADE_LOG_NOTICE, null, $notification);
             }
 
             if (!$fs->file_exists($context->id, $component, $filearea, '0', $filepath, $filename)) {
@@ -352,7 +377,7 @@ function upgrade_migrate_files_course($context, $path, $delete) {
                 continue;
             }
             $filepath = ($filepath.$dirname.'/');
-            if ($filepath !== '/backupdata/') {
+            if ($filepath !== '/backupdata/' and $textlib->strlen($filepath) <= 255) {
                 $fs->create_directory($context->id, $component, $filearea, 0, $filepath);
             }
 
index 845d0d1..d822bda 100644 (file)
@@ -1259,7 +1259,8 @@ function execute_sql($command, $feedback=true) {
     error('execute_sql() not available anymore');
 }
 /**
- * @deprecated
+ * @deprecated use $DB->record_exists_select() instead
+ * @see moodle_database::record_exists_select()
  * @param mixed $table
  * @param mixed $select
  * @return void Throws an error and does nothing
@@ -1268,7 +1269,8 @@ function record_exists_select($table, $select='') {
     error('record_exists_select() not available anymore');
 }
 /**
- * @deprecated
+ * @deprecated use $DB->record_exists_sql() instead
+ * @see moodle_database::record_exists_sql()
  * @param mixed $sql
  * @return void Throws an error and does nothing
  */
@@ -1276,7 +1278,8 @@ function record_exists_sql($sql) {
     error('record_exists_sql() not available anymore');
 }
 /**
- * @deprecated
+ * @deprecated use $DB->count_records_select() instead
+ * @see moodle_database::count_records_select()
  * @param mixed $table
  * @param mixed $select
  * @param mixed $countitem
@@ -1286,7 +1289,8 @@ function count_records_select($table, $select='', $countitem='COUNT(*)') {
     error('count_records_select() not available anymore');
 }
 /**
- * @deprecated
+ * @deprecated use $DB->count_records_sql() instead
+ * @see moodle_database::count_records_sql()
  * @param mixed $sql
  * @return void Throws an error and does nothing
  */
@@ -1294,7 +1298,8 @@ function count_records_sql($sql) {
     error('count_records_sql() not available anymore');
 }
 /**
- * @deprecated
+ * @deprecated use $DB->get_record_sql() instead
+ * @see moodle_database::get_record_sql()
  * @param mixed $sql
  * @param bool $expectmultiple
  * @param bool $nolimit
@@ -1304,7 +1309,8 @@ function get_record_sql($sql, $expectmultiple=false, $nolimit=false) {
     error('get_record_sql() not available anymore');
 }
 /**
- * @deprecated
+ * @deprecated use $DB->get_record_select() instead
+ * @see moodle_database::get_record_select()
  * @param mixed $table
  * @param mixed $select
  * @param mixed $fields
@@ -1314,7 +1320,8 @@ function get_record_select($table, $select='', $fields='*') {
     error('get_record_select() not available anymore');
 }
 /**
- * @deprecated
+ * @deprecated use $DB->get_recordset() instead
+ * @see moodle_database::get_recordset()
  * @param mixed $table
  * @param mixed $field
  * @param mixed $value
@@ -1328,7 +1335,8 @@ function get_recordset($table, $field='', $value='', $sort='', $fields='*', $lim
     error('get_recordset() not available anymore');
 }
 /**
- * @deprecated
+ * @deprecated use $DB->get_recordset_sql() instead
+ * @see moodle_database::get_recordset_sql()
  * @param mixed $sql
  * @param mixed $limitfrom
  * @param mixed $limitnum
@@ -1378,7 +1386,8 @@ function rs_close(&$rs) {
     error('rs_close() not available anymore');
 }
 /**
- * @deprecated
+ * @deprecated use $DB->get_records_select() instead
+ * @see moodle_database::get_records_select()
  * @param mixed $table
  * @param mixed $select
  * @param mixed $sort
@@ -1391,7 +1400,8 @@ function get_records_select($table, $select='', $sort='', $fields='*', $limitfro
     error('get_records_select() not available anymore');
 }
 /**
- * @deprecated
+ * @deprecated use $DB->get_field_select() instead
+ * @see moodle_database::get_field_select()
  * @param mixed $table
  * @param mixed $return
  * @param mixed $select
@@ -1401,7 +1411,8 @@ function get_field_select($table, $return, $select) {
     error('get_field_select() not available anymore');
 }
 /**
- * @deprecated
+ * @deprecated use $DB->get_field_sql() instead
+ * @see moodle_database::get_field_sql()
  * @param mixed $sql
  * @return void Throws an error and does nothing
  */
@@ -1409,7 +1420,8 @@ function get_field_sql($sql) {
     error('get_field_sql() not available anymore');
 }
 /**
- * @deprecated
+ * @deprecated use $DB->delete_records_select() instead
+ * @see moodle_database::delete_records_select()
  * @param mixed $sql
  * @param mixed $select
  * @return void Throws an error and does nothing
@@ -1495,7 +1507,8 @@ function execute_sql_arr($sqlarr, $continue=true, $feedback=true) {
     error('execute_sql_arr() removed');
 }
 /**
- * @deprecated
+ * @deprecated use $DB->get_records_list() instead
+ * @see moodle_database::get_records_list()
  * @param mixed $table
  * @param mixed $field
  * @param mixed $values
@@ -1509,7 +1522,8 @@ function get_records_list($table, $field='', $values='', $sort='', $fields='*',
     error('get_records_list() removed');
 }
 /**
- * @deprecated
+ * @deprecated use $DB->get_recordset_list() instead
+ * @see moodle_database::get_recordset_list()
  * @param mixed $table
  * @param mixed $field
  * @param mixed $values
@@ -1523,7 +1537,8 @@ function get_recordset_list($table, $field='', $values='', $sort='', $fields='*'
     error('get_recordset_list() removed');
 }
 /**
- * @deprecated
+ * @deprecated use $DB->get_records_menu() instead
+ * @see moodle_database::get_records_menu()
  * @param mixed $table
  * @param mixed $field
  * @param mixed $value
@@ -1537,7 +1552,8 @@ function get_records_menu($table, $field='', $value='', $sort='', $fields='*', $
     error('get_records_menu() removed');
 }
 /**
- * @deprecated
+ * @deprecated use $DB->get_records_select_menu() instead
+ * @see moodle_database::get_records_select_menu()
  * @param mixed $table
  * @param mixed $select
  * @param mixed $sort
@@ -1550,7 +1566,8 @@ function get_records_select_menu($table, $select='', $sort='', $fields='*', $lim
     error('get_records_select_menu() removed');
 }
 /**
- * @deprecated
+ * @deprecated use $DB->get_records_sql_menu() instead
+ * @see moodle_database::get_records_sql_menu()
  * @param mixed $sql
  * @param mixed $limitfrom
  * @param mixed $limitnum
@@ -1587,7 +1604,8 @@ function records_to_menu($records, $field1, $field2) {
     error('records_to_menu() removed');
 }
 /**
- * @deprecated
+ * @deprecated use $DB->set_field_select() instead
+ * @see moodle_database::set_field_select()
  * @param mixed $table
  * @param mixed $newfield
  * @param mixed $newvalue
@@ -1599,7 +1617,8 @@ function set_field_select($table, $newfield, $newvalue, $select, $localcall = fa
     error('set_field_select() removed');
 }
 /**
- * @deprecated
+ * @deprecated use $DB->get_fieldset_select() instead
+ * @see moodle_database::get_fieldset_select()
  * @param mixed $table
  * @param mixed $return
  * @param mixed $select
@@ -1609,7 +1628,8 @@ function get_fieldset_select($table, $return, $select) {
     error('get_fieldset_select() removed');
 }
 /**
- * @deprecated
+ * @deprecated use $DB->get_fieldset_sql() instead
+ * @see moodle_database::get_fieldset_sql()
  * @param mixed $sql
  * @return void Throws an error and does nothing
  */
@@ -1617,7 +1637,8 @@ function get_fieldset_sql($sql) {
     error('get_fieldset_sql() removed');
 }
 /**
- * @deprecated
+ * @deprecated use $DB->sql_like() instead
+ * @see moodle_database::sql_like()
  * @return void Throws an error and does nothing
  */
 function sql_ilike() {
@@ -1776,7 +1797,8 @@ function rollback_sql() {
     error('rollback_sql() not available anymore');
 }
 /**
- * @deprecated
+ * @deprecated use $DB->insert_record() instead
+ * @see moodle_database::insert_record()
  * @param mixed $table
  * @param mixed $dataobject
  * @param mixed $returnid
@@ -1787,7 +1809,8 @@ function insert_record($table, $dataobject, $returnid=true, $primarykey='id') {
     error('insert_record() not available anymore');
 }
 /**
- * @deprecated
+ * @deprecated use $DB->update_record() instead
+ * @see moodle_database::update_record()
  * @param mixed $table
  * @param mixed $dataobject
  * @return void Throws an error and does nothing
@@ -1796,7 +1819,8 @@ function update_record($table, $dataobject) {
     error('update_record() not available anymore');
 }
 /**
- * @deprecated
+ * @deprecated use $DB->get_records() instead
+ * @see moodle_database::get_records()
  * @param mixed $table
  * @param mixed $field
  * @param mixed $value
@@ -1811,7 +1835,8 @@ function get_records($table, $field='', $value='', $sort='', $fields='*', $limit
     error('get_records() not available anymore');
 }
 /**
- * @deprecated
+ * @deprecated use $DB->get_record() instead
+ * @see moodle_database::get_record()
  * @param mixed $table
  * @param mixed $field1
  * @param mixed $value1
@@ -1826,7 +1851,8 @@ function get_record($table, $field1, $value1, $field2='', $value2='', $field3=''
     error('get_record() not available anymore');
 }
 /**
- * @deprecated
+ * @deprecated use $DB->set_field() instead
+ * @see moodle_database::set_field()
  * @param mixed $table
  * @param mixed $newfield
  * @param mixed $newvalue
@@ -1842,7 +1868,8 @@ function set_field($table, $newfield, $newvalue, $field1, $value1, $field2='', $
     error('set_field() not available anymore');
 }
 /**
- * @deprecated
+ * @deprecated use $DB->count_records() instead
+ * @see moodle_database::count_records()
  * @param mixed $table
  * @param mixed $field1
  * @param mixed $value1
@@ -1856,7 +1883,8 @@ function count_records($table, $field1='', $value1='', $field2='', $value2='', $
     error('count_records() not available anymore');
 }
 /**
- * @deprecated
+ * @deprecated use $DB->record_exists() instead
+ * @see moodle_database::record_exists()
  * @param mixed $table
  * @param mixed $field1
  * @param mixed $value1
@@ -1870,7 +1898,8 @@ function record_exists($table, $field1='', $value1='', $field2='', $value2='', $
     error('record_exists() not available anymore');
 }
 /**
- * @deprecated
+ * @deprecated use $DB->delete_records() instead
+ * @see moodle_database::delete_records()
  * @param mixed $table
  * @param mixed $field1
  * @param mixed $value1
@@ -1884,7 +1913,8 @@ function delete_records($table, $field1='', $value1='', $field2='', $value2='',
     error('delete_records() not available anymore');
 }
 /**
- * @deprecated
+ * @deprecated use $DB->get_field() instead
+ * @see moodle_database::get_field()
  * @param mixed $table
  * @param mixed $return
  * @param mixed $field1
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 532dac1..0efc009 100644 (file)
@@ -89,6 +89,9 @@ function external_function_info($function, $strictness=MUST_EXIST) {
         if (isset($functions[$function->name]['description'])) {
             $function->description = $functions[$function->name]['description'];
         }
+        if (isset($functions[$function->name]['testclientpath'])) {
+            $function->testclientpath = $functions[$function->name]['testclientpath'];
+        }
     }
 
     return $function;
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 fbc6a50..1787b0f 100644 (file)
@@ -43,6 +43,7 @@ defined('MOODLE_INTERNAL') || die();
 require_once 'HTML/QuickForm.php';
 require_once 'HTML/QuickForm/DHTMLRulesTableless.php';
 require_once 'HTML/QuickForm/Renderer/Tableless.php';
+require_once 'HTML/QuickForm/Rule.php';
 
 require_once $CFG->libdir.'/filelib.php';
 
@@ -2344,6 +2345,57 @@ class MoodleQuickForm_Renderer extends HTML_QuickForm_Renderer_Tableless{
     }
 }
 
+/**
+ * Required elements validation
+ * This class overrides QuickForm validation since it allowed space or empty tag as a value
+ */
+class MoodleQuickForm_Rule_Required extends HTML_QuickForm_Rule {
+    /**
+     * Checks if an element is not empty.
+     * This is a server-side validation, it works for both text fields and editor fields
+     *
+     * @param     string    $value      Value to check
+     * @param     mixed     $options    Not used yet
+     * @return    boolean   true if value is not empty
+     */
+    function validate($value, $options = null) {
+        global $CFG;
+        if (is_array($value) && array_key_exists('text', $value)) {
+            $value = $value['text'];
+        }
+        $stripvalues = array(
+            '#</?(?!img|canvas|hr).*?>#im', // all tags except img, canvas and hr
+            '#(\xc2|\xa0|\s|&nbsp;)#', //any whitespaces actually
+        );
+        if (!empty($CFG->strictformsrequired)) {
+            $value = preg_replace($stripvalues, '', (string)$value);
+        }
+        if ((string)$value == '') {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * This function returns Javascript code used to build client-side validation.
+     * It checks if an element is not empty.
+     * Note, that QuickForm does not know how to work with editor text field and builds not correct
+     * JS code for validation. If client check is enabled for editor field it will not be validated
+     * on client side no matter what this function returns.
+     *
+     * @param     mixed     $options    Not used yet
+     * @return array
+     */
+    function getValidationScript($options = null) {
+        global $CFG;
+        if (!empty($CFG->strictformsrequired)) {
+            return array('', "{jsVar}.replace(/^\s+$/g, '') == ''");
+        } else {
+            return array('', "{jsVar} == ''");
+        }
+    }
+}
+
 /**
  * @global object $GLOBALS['_HTML_QuickForm_default_renderer']
  * @name $_HTML_QuickForm_default_renderer
@@ -2387,3 +2439,5 @@ MoodleQuickForm::registerElementType('text', "$CFG->libdir/form/text.php", 'Mood
 MoodleQuickForm::registerElementType('textarea', "$CFG->libdir/form/textarea.php", 'MoodleQuickForm_textarea');
 MoodleQuickForm::registerElementType('url', "$CFG->libdir/form/url.php", 'MoodleQuickForm_url');
 MoodleQuickForm::registerElementType('warning', "$CFG->libdir/form/warning.php", 'MoodleQuickForm_warning');
+
+MoodleQuickForm::registerRule('required', null, 'MoodleQuickForm_Rule_Required', "$CFG->libdir/formslib.php");
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 7b28f7c..a4ebab4 100644 (file)
@@ -243,7 +243,7 @@ function install_print_help_page($help) {
     echo '<html dir="'.(right_to_left() ? 'rtl' : 'ltr').'">
           <head>
           <link rel="shortcut icon" href="theme/standard/pix/favicon.ico" />
-          <link rel="stylesheet" type="text/css" href="'.$CFG->wwwroot.'/install.php?css=1" />
+          <link rel="stylesheet" type="text/css" href="'.$CFG->wwwroot.'/install/css.php" />
           <title>'.get_string('installation','install').'</title>
           <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
           <meta http-equiv="pragma" content="no-cache" />
@@ -290,20 +290,7 @@ function install_print_header($config, $stagename, $heading, $stagetext) {
           <head>
           <link rel="shortcut icon" href="theme/standard/pix/favicon.ico" />';
 
-    $sheets = array('pagelayout','core');
-    $csss = array();
-    foreach ($sheets as $sheet) {
-        $csss[] = $CFG->wwwroot.'/theme/base/style/'.$sheet.'.css';
-    }
-    $sheets = array('core', 'css3');
-    foreach ($sheets as $sheet) {
-        $csss[] = $CFG->wwwroot.'/theme/standard/style/'.$sheet.'.css';
-    }
-    foreach ($csss as $css) {
-        echo '<link rel="stylesheet" type="text/css" href="'.$css.'" />'."\n";
-    }
-
-    echo '<link rel="stylesheet" type="text/css" href="'.$CFG->wwwroot.'/install.php?css=1" />
+    echo '<link rel="stylesheet" type="text/css" href="'.$CFG->wwwroot.'/install/css.php" />
           <title>'.get_string('installation','install').' - Moodle '.$CFG->target_release.'</title>
           <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
           <meta http-equiv="pragma" content="no-cache" />
@@ -381,118 +368,6 @@ function install_print_footer($config, $reload=false) {
     echo '</div></body></html>';
 }
 
-
-/**
- * Prints css needed on installation page, tries to look like the rest of installation.
- * Does not return.
- *
- * @global object
- */
-function install_css_styles() {
-    global $CFG;
-
-    @header('Content-type: text/css');  // Correct MIME type
-    @header('Cache-Control: no-store, no-cache, must-revalidate');
-    @header('Cache-Control: post-check=0, pre-check=0', false);
-    @header('Pragma: no-cache');
-    @header('Expires: Mon, 20 Aug 1969 09:23:00 GMT');
-    @header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
-
-//TODO: add rtl support here, make it match new default theme MDL-21149
-
-    echo '
-
-h2 {
-  text-align:center;
-}
-
-#installdiv {
-  width: 800px;
-  margin-left:auto;
-  margin-right:auto;
-}
-
-#installdiv dt {
-  font-weight: bold;
-}
-
-#installdiv dd {
-  padding-bottom: 0.5em;
-}
-
-.stage {
-  margin-top: 2em;
-  margin-bottom: 2em;
-  width: 100%;
-  padding:25px;
-}
-
-#installform {
-  width: 100%;
-}
-
-#nav_buttons input {
-  margin: 5px;
-}
-
-#envresult {
-  text-align:left;
-  width: auto;
-  margin-left:10em;
-}
-
-#envresult dd {
-  color: red;
-}
-
-.formrow {
-  clear:both;
-  text-align:left;
-  padding: 8px;
-}
-
-.formrow label.formlabel {
-  display:block;
-  float:left;
-  width: 260px;
-  margin-right:5px;
-  text-align:right;
-}
-
-.formrow .forminput {
-  display:block;
-  float:left;
-}
-
-fieldset {
-  text-align:center;
-  border:none;
-}
-
-.hint {
-  display:block;
-  clear:both;
-  padding-left: 265px;
-  color: red;
-}
-
-.configphp {
-  text-align:left;
-  background-color:white;
-  padding:1em;
-  width:95%;
-}
-
-.stage6 .stage {
-  font-weight: bold;
-  color: red;
-}
-
-';
-
-    die;
-}
-
 /**
  * Install Moodle DB,
  * config.php must exist, there must not be any tables in db yet.
index f6f9561..2d6476a 100644 (file)
@@ -924,7 +924,7 @@ function filterByParent(elCollection, parentFinder) {
     var filteredCollection = [];
     for (var i = 0; i < elCollection.length; ++i) {
         var findParent = parentFinder(elCollection[i]);
-        if (findParent.nodeName.toUpperCase != 'BODY') {
+        if (findParent.nodeName.toUpperCase() != 'BODY') {
             filteredCollection.push(elCollection[i]);
         }
     }
index 47e5a7b..e797bf6 100644 (file)
@@ -3462,7 +3462,7 @@ function truncate_userinfo($info) {
  *
  * Any plugin that needs to purge user data should register the 'user_deleted' event.
  *
- * @param object $user User object before delete
+ * @param stdClass $user full user object before delete
  * @return boolean always true
  */
 function delete_user($user) {
@@ -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 c76963b..e2aab50 100644 (file)
@@ -1635,9 +1635,20 @@ class global_navigation extends navigation_node {
 
         $namingfunction = 'callback_'.$courseformat.'_get_section_name';
         $namingfunctionexists = (function_exists($namingfunction));
-        $activesection = course_get_display($course->id);
+
         $viewhiddensections = has_capability('moodle/course:viewhiddensections', $this->page->context);
 
+        $urlfunction = 'callback_'.$courseformat.'_get_section_url';
+        if (empty($CFG->navlinkcoursesections) || !function_exists($urlfunction)) {
+            $urlfunction = null;
+        }
+
+        $keyfunction = 'callback_'.$courseformat.'_request_key';
+        $key = course_get_display($course->id);
+        if (defined('AJAX_SCRIPT') && AJAX_SCRIPT == '0' && function_exists($keyfunction) && $this->page->url->compare(new moodle_url('/course/view.php'), URL_MATCH_BASE)) {
+            $key = optional_param($keyfunction(), $key, PARAM_INT);
+        }
+
         $navigationsections = array();
         foreach ($sections as $sectionid => $section) {
             $section = clone($section);
@@ -1652,13 +1663,16 @@ class global_navigation extends navigation_node {
                 } else {
                     $sectionname = get_string('section').' '.$section->section;
                 }
-                //$url = new moodle_url('/course/view.php', array('id'=>$course->id));
+
                 $url = null;
+                if (!empty($urlfunction)) {
+                    $url = $urlfunction($course->id, $section->section);
+                }
                 $sectionnode = $coursenode->add($sectionname, $url, navigation_node::TYPE_SECTION, null, $section->id);
                 $sectionnode->nodetype = navigation_node::NODETYPE_BRANCH;
                 $sectionnode->hidden = (!$section->visible);
-                if ($this->page->context->contextlevel != CONTEXT_MODULE && $section->hasactivites && ($sectionnode->isactive || ($activesection && $section->section == $activesection))) {
-                    $sectionnode->force_open();
+                if ($key != '0' && $section->section != '0' && $section->section == $key && $this->page->context->contextlevel != CONTEXT_MODULE && $section->hasactivites) {
+                    $sectionnode->make_active();
                     $this->load_section_activities($sectionnode, $section->section, $activities);
                 }
                 $section->sectionnode = $sectionnode;
@@ -1824,6 +1838,9 @@ class global_navigation extends navigation_node {
         if ($iscurrentuser && !$forceforcontext) {
             // If it's the current user the information will go under the profile root node
             $usernode = $this->rootnodes['myprofile'];
+            $course = get_site();
+            $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id);
+            $issitecourse = true;
         } else {
             if (!$issitecourse) {
                 // Not the current user so add it to the participants node for the current course
index bdd635f..6c7d0e4 100644 (file)
@@ -719,7 +719,7 @@ class page_requirements_manager {
             // Set Y's config.gallery to the version
             $jscode = 'Y.config.gallery='.json_encode($galleryversion).';';
         }
-        $jscode .= 'Y.use('.join(',', array_map('json_encode', $modules)).',function() {'.js_writer::function_call($function, $arguments).'})';
+        $jscode .= 'Y.use('.join(',', array_map('json_encode', $modules)).',function() {'.js_writer::function_call($function, $arguments).'});';
         if ($ondomready) {
             $jscode = "Y.on('domready', function() { $jscode });";
         }
index bc5192f..f01e74c 100644 (file)
@@ -544,7 +544,7 @@ class moodle_page {
      * @return bool
      */
     protected function magic_get_legacythemeinuse() {
-        debugging('$PAGE->legacythemeinuse is a deprecated property - please use $PAGE->devicetypeinuse and check if it is equal to legacy.', DEVELOPER_DEBUG);
+        debugging('$PAGE->legacythemeinuse is a deprecated property - please use $PAGE->devicetypeinuse and check if it is equal to legacy.', DEBUG_DEVELOPER);
         return ($this->devicetypeinuse == 'legacy');
     }
 
index fe6c3f6..e9e4a7e 100644 (file)
@@ -1502,13 +1502,6 @@ class HTML_QuickForm extends HTML_Common {
                         $values[] = $this->getSubmitValue($elName);
                     }
                     $result = $registry->validate($rule['type'], $values, $rule['format'], true);
-                } else if ($rule['type'] === 'required' and $this->getElement($target)->_type === 'editor') {
-                    //horrible horrible hack
-                    if (!isset($submitValue['text']) or $submitValue['text'] === '') {
-                        $result = false;
-                    } else {
-                        $result = true;
-                    }
                 } elseif (is_array($submitValue) && !isset($rule['howmany'])) {
                     $result = $registry->validate($rule['type'], $submitValue, $rule['format'], true);
                 } else {
index 8fa59f4..00eeff5 100644 (file)
@@ -22,8 +22,6 @@ and documented for Moodle at:
 
 4/ MDL-20876 - replaced deprecated split() with explode() or str_split() where appropriate
 
-5/ hardcoded editor element required rule validation
-
 Such modifications should be carefully each time the Excel PEAR package is updated
 to a new release within Moodle.
 
index 500ad75..80d6088 100644 (file)
@@ -354,6 +354,10 @@ class plugin_manager {
                 'wikimedia', 'youtube'
             ),
 
+            'scormreport' => array(
+                'basic'
+            ),
+
             'theme' => array(
                 'afterburner', 'anomaly', 'arialist', 'base', 'binarius',
                 'boxxie', 'brick', 'canvas', 'formal_white', 'formfactor',
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 aeae850..d0bce1f 100644 (file)
@@ -501,6 +501,12 @@ function get_exception_info($ex) {
         }
     }
 
+    // when printing an error the continue button should never link offsite
+    if (stripos($link, $CFG->wwwroot) === false &&
+        stripos($link, $CFG->httpswwwroot) === false) {
+        $link = $CFG->wwwroot.'/';
+    }
+
     $info = new stdClass();
     $info->message     = $message;
     $info->errorcode   = $errorcode;
@@ -701,7 +707,9 @@ function initialise_fullme() {
     // Used in load balancing scenarios.
     // Do not abuse this to try to solve lan/wan access problems!!!!!
     if (empty($CFG->reverseproxy)) {
-        if (($rurl['host'] != $wwwroot['host']) or
+        if (empty($rurl['host'])) {
+            // missing host in request header, probably not a real browser, let's ignore them
+        } else if (($rurl['host'] !== $wwwroot['host']) or
                 (!empty($wwwroot['port']) and $rurl['port'] != $wwwroot['port'])) {
             // Explain the problem and redirect them to the right URL
             if (!defined('NO_MOODLE_COOKIES')) {
@@ -713,7 +721,7 @@ function initialise_fullme() {
 
     // hopefully this will stop all those "clever" admins trying to set up moodle
     // with two different addresses in intranet and Internet
-    if (!empty($CFG->reverseproxy) && $rurl['host'] == $wwwroot['host']) {
+    if (!empty($CFG->reverseproxy) && $rurl['host'] === $wwwroot['host']) {
         print_error('reverseproxyabused', 'error');
     }
 
@@ -759,7 +767,11 @@ function initialise_fullme_cli() {
  */
 function setup_get_remote_url() {
     $rurl = array();
-    list($rurl['host']) = explode(':', $_SERVER['HTTP_HOST']);
+    if (isset($_SERVER['HTTP_HOST'])) {
+        list($rurl['host']) = explode(':', $_SERVER['HTTP_HOST']);
+    } else {
+        $rurl['host'] = null;
+    }
     $rurl['port'] = $_SERVER['SERVER_PORT'];
     $rurl['path'] = $_SERVER['SCRIPT_NAME']; // Script path without slash arguments
     $rurl['scheme'] = (empty($_SERVER['HTTPS']) or $_SERVER['HTTPS'] === 'off' or $_SERVER['HTTPS'] === 'Off' or $_SERVER['HTTPS'] === 'OFF') ? 'http' : 'https';
diff --git a/lib/simpletest/testformslib.php b/lib/simpletest/testformslib.php
new file mode 100644 (file)
index 0000000..0330895
--- /dev/null
@@ -0,0 +1,119 @@
+<?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/>.
+
+
+/**
+ * Unit tests for /lib/formslib.php.
+ *
+ * @package   file
+ * @copyright 2011 Sam Hemelryk
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+if (!defined('MOODLE_INTERNAL')) {
+    die('Direct access to this script is forbidden.');    ///  It must be included from a Moodle page
+}
+require_once($CFG->libdir . '/formslib.php');
+
+class formslib_test extends UnitTestCase {
+
+    public function test_require_rule() {
+        global $CFG;
+
+        $strictformsrequired = false;
+        if (!empty($CFG->strictformsrequired)) {
+            $strictformsrequired = $CFG->strictformsrequired;
+        }
+
+        $rule = new MoodleQuickForm_Rule_Required();
+
+        // First run the tests with strictformsrequired off
+        $CFG->strictformsrequired = false;
+        // Passes
+        $this->assertTrue($rule->validate('Something'));
+        $this->assertTrue($rule->validate("Something\nmore"));
+        $this->assertTrue($rule->validate("\nmore"));
+        $this->assertTrue($rule->validate(" more "));
+        $this->assertTrue($rule->validate("0"));
+        $this->assertTrue($rule->validate(0));
+        $this->assertTrue($rule->validate(true));
+        $this->assertTrue($rule->validate(' '));
+        $this->assertTrue($rule->validate('      '));
+        $this->assertTrue($rule->validate("\t"));
+        $this->assertTrue($rule->validate("\n"));
+        $this->assertTrue($rule->validate("\r"));
+        $this->assertTrue($rule->validate("\r\n"));
+        $this->assertTrue($rule->validate(" \t  \n  \r "));
+        $this->assertTrue($rule->validate('<p></p>'));
+        $this->assertTrue($rule->validate('<p> </p>'));
+        $this->assertTrue($rule->validate('<p>x</p>'));
+        $this->assertTrue($rule->validate('<img src="smile.jpg" alt="smile" />'));
+        $this->assertTrue($rule->validate('<img src="smile.jpg" alt="smile"/>'));
+        $this->assertTrue($rule->validate('<img src="smile.jpg" alt="smile"></img>'));
+        $this->assertTrue($rule->validate('<hr />'));
+        $this->assertTrue($rule->validate('<hr/>'));
+        $this->assertTrue($rule->validate('<hr>'));
+        $this->assertTrue($rule->validate('<hr></hr>'));
+        $this->assertTrue($rule->validate('<br />'));
+        $this->assertTrue($rule->validate('<br/>'));
+        $this->assertTrue($rule->validate('<br>'));
+        $this->assertTrue($rule->validate('&nbsp;'));
+        // Fails
+        $this->assertFalse($rule->validate(''));
+        $this->assertFalse($rule->validate(false));
+        $this->assertFalse($rule->validate(null));
+
+        // Now run the same tests with it on to make sure things work as expected
+        $CFG->strictformsrequired = true;
+        // Passes
+        $this->assertTrue($rule->validate('Something'));
+        $this->assertTrue($rule->validate("Something\nmore"));
+        $this->assertTrue($rule->validate("\nmore"));
+        $this->assertTrue($rule->validate(" more "));
+        $this->assertTrue($rule->validate("0"));
+        $this->assertTrue($rule->validate(0));
+        $this->assertTrue($rule->validate(true));
+        $this->assertTrue($rule->validate('<p>x</p>'));
+        $this->assertTrue($rule->validate('<img src="smile.jpg" alt="smile" />'));
+        $this->assertTrue($rule->validate('<img src="smile.jpg" alt="smile"/>'));
+        $this->assertTrue($rule->validate('<img src="smile.jpg" alt="smile"></img>'));
+        $this->assertTrue($rule->validate('<hr />'));
+        $this->assertTrue($rule->validate('<hr/>'));
+        $this->assertTrue($rule->validate('<hr>'));
+        $this->assertTrue($rule->validate('<hr></hr>'));
+        // Fails
+        $this->assertFalse($rule->validate(' '));
+        $this->assertFalse($rule->validate('      '));
+        $this->assertFalse($rule->validate("\t"));
+        $this->assertFalse($rule->validate("\n"));
+        $this->assertFalse($rule->validate("\r"));
+        $this->assertFalse($rule->validate("\r\n"));
+        $this->assertFalse($rule->validate(" \t  \n  \r "));
+        $this->assertFalse($rule->validate('<p></p>'));
+        $this->assertFalse($rule->validate('<p> </p>'));
+        $this->assertFalse($rule->validate('<br />'));
+        $this->assertFalse($rule->validate('<br/>'));
+        $this->assertFalse($rule->validate('<br>'));
+        $this->assertFalse($rule->validate('&nbsp;'));
+        $this->assertFalse($rule->validate(''));
+        $this->assertFalse($rule->validate(false));
+        $this->assertFalse($rule->validate(null));
+
+        $CFG->strictformsrequired = $strictformsrequired;
+    }
+
+}
\ No newline at end of file
index e1ac513..f6dce5d 100644 (file)
@@ -60,7 +60,7 @@ class local_qeupgradehelper_attempt_upgrader extends question_engine_attempt_upg
         gc_collect_cycles(); // This was really helpful in PHP 5.2. Perhaps remove.
         $a = new stdClass();
         $a->done = $done;
-        $a->todo = $outof;
+        $a->outof = $outof;
         $this->progressbar->update($done, $outof,
                 get_string('resettingquizattemptsprogress', 'local_qeupgradehelper', $a));
     }
index 9de50e0..1d4013f 100644 (file)
@@ -1000,14 +1000,14 @@ function message_get_contact($contactid) {
  *
  * @param mixed $frm submitted form data
  * @param bool $showicontext show text next to action icons?
- * @param object $user1 the current user
+ * @param object $currentuser the current user
  * @return void
  */
-function message_print_search_results($frm, $showicontext=false, $user1=null) {
+function message_print_search_results($frm, $showicontext=false, $currentuser=null) {
     global $USER, $DB, $OUTPUT;
 
-    if (empty($user1)) {
-        $user1 = $USER;
+    if (empty($currentuser)) {
+        $currentuser = $USER;
     }
 
     echo html_writer::start_tag('div', array('class' => 'mdl-left'));
@@ -1227,14 +1227,17 @@ function message_print_search_results($frm, $showicontext=false, $user1=null) {
                 echo message_get_fragment($message->fullmessage, $keywords);
                 echo html_writer::start_tag('div', array('class' => 'link'));
 
-                //find the user involved that isn't the current user
-                $user2id = null;
-                if ($user1->id == $message->useridto) {
-                    $user2id = $message->useridfrom;
+                //If the user clicks the context link display message sender on the left
+                //EXCEPT if the current user is in the conversation. Current user == always on the left
+                $leftsideuserid = $rightsideuserid = null;
+                if ($currentuser->id == $message->useridto) {
+                    $leftsideuserid = $message->useridto;
+                    $rightsideuserid = $message->useridfrom;
                 } else {
-                    $user2id = $message->useridto;
+                    $leftsideuserid = $message->useridfrom;
+                    $rightsideuserid = $message->useridto;
                 }
-                message_history_link($user1->id, $user2id, false,
+                message_history_link($leftsideuserid, $rightsideuserid, false,
                                      $messagesearchstring, 'm'.$message->id, $strcontext);
                 echo html_writer::end_tag('div');
                 echo html_writer::end_tag('td');
@@ -1393,7 +1396,7 @@ function message_contact_link($userid, $linktype='add', $return=false, $script=n
  * echo or return a link to take the user to the full message history between themselves and another user
  *
  * @staticvar type $strmessagehistory
- * @param int $userid1 the ID of the current user
+ * @param int $userid1 the ID of the user displayed on the left (usually the current user)
  * @param int $userid2 the ID of the other user
  * @param bool $return true to return the link as a string. False to echo the link.
  * @param string $keywords any keywords to highlight in the message history
@@ -1403,7 +1406,6 @@ function message_contact_link($userid, $linktype='add', $return=false, $script=n
  */
 function message_history_link($userid1, $userid2, $return=false, $keywords='', $position='', $linktext='') {
     global $OUTPUT;
-
     static $strmessagehistory;
 
     if (empty($strmessagehistory)) {
@@ -1437,7 +1439,7 @@ function message_history_link($userid1, $userid2, $return=false, $keywords='', $
             'scrollbars' => true,
             'resizable' => true);
 
-    $link = new moodle_url('/message/index.php?history='.MESSAGE_HISTORY_ALL."&user=$userid1&id=$userid2$keywords$position");
+    $link = new moodle_url('/message/index.php?history='.MESSAGE_HISTORY_ALL."&user1=$userid1&user2=$userid2$keywords$position");
     $action = null;
     $str = $OUTPUT->action_link($link, $fulllink, $action, array('title' => $strmessagehistory));
 
index b7f559e..e9a9031 100644 (file)
@@ -98,7 +98,7 @@ $string['errornosubmissions'] = 'There are no submissions to download';
 $string['existingfiledeleted'] = 'Existing file has been deleted: {$a}';
 $string['failedupdatefeedback'] = 'Failed to update submission feedback for user {$a}';
 $string['feedback'] = 'Feedback';
-$string['feedbackfromteacher'] = 'Feedback from the {$a}';
+$string['feedbackfromteacher'] = 'Feedback from {$a}';
 $string['feedbackupdated'] = 'Submissions feedback updated for {$a} people';
 $string['finalize'] = 'Prevent submission updates';
 $string['finalizeerror'] = 'An error occurred and that submission could not be finalised';
index 9387422..c069dc1 100644 (file)
@@ -31,7 +31,7 @@ $string['displayhorizontal'] = 'Display horizontally';
 $string['displaymode'] = 'Display mode';
 $string['displayvertical'] = 'Display vertically';
 $string['expired'] = 'Sorry, this activity closed on {$a} and is no longer available';
-$string['fillinatleastoneoption'] = 'You need to provide at least two possible answers.';
+$string['atleastoneoption'] = 'You need to provide at least one possible answer.';
 $string['full'] = '(Full)';
 $string['havetologin'] = 'You have to log in before you can submit your choice';
 $string['choice'] = 'Choice';
index 1f65611..349d79b 100644 (file)
@@ -127,11 +127,7 @@ class mod_choice_mod_form extends moodleform_mod {
         }
 
         if ($choices < 1) {
-           $errors['option[0]'] = get_string('fillinatleastoneoption', 'choice');
-        }
-
-        if ($choices < 2) {
-           $errors['option[1]'] = get_string('fillinatleastoneoption', 'choice');
+           $errors['option[0]'] = get_string('atleastoneoption', 'choice');
         }
 
         return $errors;
index 792bdcb..a31312f 100644 (file)
@@ -5,7 +5,7 @@
 //  This fragment is called by /admin/index.php
 ////////////////////////////////////////////////////////////////////////////////
 
-$module->version  = 2010101300;
+$module->version  = 2010101301;
 $module->requires = 2010080300;  // Requires this Moodle version
 $module->cron     = 0;
 
index 7830630..6319c9f 100644 (file)
@@ -567,16 +567,16 @@ function xmldb_quiz_upgrade($oldversion) {
                 $pbar = new progress_bar('q15upgrade');
                 $pbar->create();
                 $a = new stdClass();
-                $a->todo = count($oldattempts);
+                $a->outof = count($oldattempts);
                 $a->done = 0;
-                $pbar->update($a->done, $a->todo,
+                $pbar->update($a->done, $a->outof,
                         get_string('upgradingveryoldquizattempts', 'quiz', $a));
 
                 foreach ($oldattempts as $oldattempt) {
                     quiz_upgrade_very_old_question_sessions($oldattempt);
 
                     $a->done += 1;
-                    $pbar->update($a->done, $a->todo,
+                    $pbar->update($a->done, $a->outof,
                             get_string('upgradingveryoldquizattempts', 'quiz', $a));
                 }
             }
index 5207b4b..df4668a 100644 (file)
@@ -141,7 +141,6 @@ if ($quiz_reordertool > -1) {
 $quizhasattempts = quiz_has_attempts($quiz->id);
 
 $PAGE->set_url($thispageurl);
-$PAGE->set_pagelayout('admin');
 
 $pagetitle = get_string('editingquiz', 'quiz');
 if ($quiz_reordertool) {
index 21ad231..43dffcc 100644 (file)
@@ -534,23 +534,20 @@ function quiz_print_question_list($quiz, $pageurl, $allowdelete, $reordertool,
                     $reordercheckboxlabel = '<label for="s' . $question->id . '">';
                     $reordercheckboxlabelclose = '</label>';
                 }
-                if (!$quiz->shufflequestions) {
-                    // Print and increment question number
-                    $questioncountstring = '';
-                    if ($questioncount>999 || ($reordertool && $questioncount>99)) {
-                        $questioncountstring =
-                                "$reordercheckboxlabel<small>$questioncount</small>" .
-                                $reordercheckboxlabelclose . $reordercheckbox;
+                if ($question->length == 0) {
+                    $qnodisplay = get_string('infoshort', 'quiz');
+                } else if ($quiz->shufflequestions) {
+                    $qnodisplay = '?';
+                } else {
+                    if ($qno > 999 || ($reordertool && $qno > 99)) {
+                        $qnodisplay = html_writer::tag('small', $qno);
                     } else {
-                        $questioncountstring = $reordercheckboxlabel . $questioncount .
-                                $reordercheckboxlabelclose . $reordercheckbox;
+                        $qnodisplay = $qno;
                     }
-                    echo $questioncountstring;
                     $qno += $question->length;
-                } else {
-                    echo "$reordercheckboxlabel ? $reordercheckboxlabelclose" .
-                            " $reordercheckbox";
                 }
+                echo $reordercheckboxlabel . $qnodisplay . $reordercheckboxlabelclose .
+                        $reordercheckbox;
 
                 ?>
         </div>
index e321322..49d2cb3 100644 (file)
@@ -52,7 +52,7 @@ class mod_quiz_renderer extends plugin_renderer_base {
         $output .= $this->review_summary_table($summarydata, $page);
         $output .= $this->review_form($page, $showall, $displayoptions,
                 $this->questions($attemptobj, true, $slots, $page, $showall, $displayoptions),
-                $attemptobj, $showall);
+                $attemptobj);
 
         $output .= $this->review_next_navigation($attemptobj, $page, $lastpage);
         $output .= $this->footer();
@@ -194,8 +194,7 @@ class mod_quiz_renderer extends plugin_renderer_base {
      * @param quiz_attempt $attemptobj instance of quiz_attempt
      * @param bool $showall if true display attempt on one page
      */
-    public function review_form($summarydata, $page, $displayoptions, $content, $attemptobj,
-                                $showall) {
+    public function review_form($page, $showall, $displayoptions, $content, $attemptobj) {
         if ($displayoptions->flags != question_display_options::EDITABLE) {
             return $content;
         }
@@ -611,7 +610,7 @@ class mod_quiz_renderer extends plugin_renderer_base {
         $output .= $this->view_information($course, $quiz, $cm, $context, $messages);
         $guestno = html_writer::tag('p', get_string('guestsno', 'quiz'));
         $liketologin = html_writer::tag('p', get_string('liketologin'));
-        $output .= $this->confirm($guestno.'\n\n'.$liketologin.'\n', get_login_url(),
+        $output .= $this->confirm($guestno."\n\n".$liketologin."\n", get_login_url(),
                 get_referer(false));
         return $output;
     }
@@ -632,7 +631,7 @@ class mod_quiz_renderer extends plugin_renderer_base {
         $youneedtoenrol = html_writer::tag('p', get_string('youneedtoenrol', 'quiz'));
         $button = html_writer::tag('p',
                 $this->continue_button($CFG->wwwroot . '/course/view.php?id=' . $course->id));
-        $output .= $this->box($youneedtoenrol.'\n\n'.$button.'\n', 'generalbox', 'notice');
+        $output .= $this->box($youneedtoenrol."\n\n".$button."\n", 'generalbox', 'notice');
         return $output;
     }
 
@@ -868,7 +867,7 @@ class mod_quiz_renderer extends plugin_renderer_base {
         if ($viewobj->mygradeoverridden) {
 
             $resultinfo .= html_writer::tag('p', get_string('overriddennotice', 'grades'),
-                    array('class' => 'overriddennotice')).'\n';
+                    array('class' => 'overriddennotice'))."\n";
         }
         if ($viewobj->gradebookfeedback) {
             $resultinfo .= $this->heading(get_string('comment', 'quiz'), 3, 'main');
@@ -879,7 +878,7 @@ class mod_quiz_renderer extends plugin_renderer_base {
             $resultinfo .= $this->heading(get_string('overallfeedback', 'quiz'), 3, 'main');
             $resultinfo .= html_writer::tag('p',
                     quiz_feedback_for_grade($viewobj->mygrade, $quiz, $context),
-                    array('class' => 'quizgradefeedback')).'\n';
+                    array('class' => 'quizgradefeedback'))."\n";
         }
 
         if ($resultinfo) {
index 367ec4e..70af921 100644 (file)
@@ -26,7 +26,6 @@
 $string['allattempts'] = 'Show all attempts';
 $string['allattemptscontributetograde'] = 'All attempts contribute to final grade for user.';
 $string['allstudents'] = 'Show all {$a}';
-$string['attemptprogress'] = 'Attempt {$a->done} of {$a->todo}';
 $string['attemptsonly'] = 'Show {$a} with attempts only';
 $string['attemptsprepage'] = 'Attempts shown per page';
 $string['deleteselected'] = 'Delete selected attempts';
@@ -56,7 +55,6 @@ $string['pluginname'] = 'Grades';
 $string['preferencespage'] = 'Preferences just for this page';
 $string['preferencessave'] = 'Show report';
 $string['preferencesuser'] = 'Your preferences for this report';
-$string['qprogress'] = 'Question {$a->done} of {$a->todo}';
 $string['regrade'] = 'Regrade';
 $string['regradeall'] = 'Regrade all';
 $string['regradealldry'] = 'Dry run a full regrade';
index 2c8f534..d7875e3 100644 (file)
@@ -209,7 +209,7 @@ class quiz_statistics_report extends quiz_default_report {
             // Back to overview link.
             echo $OUTPUT->box('<a href="' . $reporturl->out() . '">' .
                     get_string('backtoquizreport', 'quiz_statistics') . '</a>',
-                    'boxaligncenter generalbox boxwidthnormal mdl-align');
+                    'backtomainstats boxaligncenter generalbox boxwidthnormal mdl-align');
 
         } else if ($qid) {
             // Report on an individual sub-question indexed questionid.
@@ -313,7 +313,7 @@ class quiz_statistics_report extends quiz_default_report {
 
         echo $OUTPUT->box(format_text($question->questiontext, $question->questiontextformat,
                 array('overflowdiv' => true)) . $actions,
-                'boxaligncenter generalbox boxwidthnormal mdl-align');
+                'questiontext boxaligncenter generalbox boxwidthnormal mdl-align');
 
         echo $OUTPUT->heading(get_string('questionstatistics', 'quiz_statistics'));
         echo html_writer::table($questionstatstable);
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 be2d4ea..60d83d4 100644 (file)
@@ -374,6 +374,7 @@ bank window's title is prominent enough*/
 .ie6#page-mod-quiz-edit div.question div.content .questionname {width:20%;}
 .ie6#page-mod-quiz-edit .editq div.question div.content .randomquestioncategory a{width:40%;}
 .ie6#page-mod-quiz-edit .reorder .questioncontentcontainer .randomquestioncategory label{width: 35%;}
+.qnum label {padding-right: 0.25em;}
 
 /** settings.php */
 #adminquizreviewoptions {margin-bottom: 0.5em;}
index b03d9b3..9b5d487 100644 (file)
@@ -205,7 +205,7 @@ function SCORMapi1_3() {
         'cmi.learner_preference.delivery_speed':{'defaultvalue':'1', 'format':CMIDecimal, 'range':speed_range, 'mod':'rw'},
         'cmi.learner_preference.audio_captioning':{'defaultvalue':'0', 'format':CMISInteger, 'range':text_range, 'mod':'rw'},
         'cmi.location':{'defaultvalue':<?php echo isset($userdata->{'cmi.location'})?'\''.$userdata->{'cmi.location'}.'\'':'null' ?>, 'format':CMIString1000, 'mod':'rw'},
-        'cmi.max_time_allowed':{'defaultvalue':<?php echo isset($userdata->maxtimeallowed)?'\''.$userdata->maxtimeallowed.'\'':'null' ?>, 'mod':'r'},
+        'cmi.max_time_allowed':{'defaultvalue':<?php echo isset($userdata->attemptAbsoluteDurationLimit)?'\''.$userdata->attemptAbsoluteDurationLimit.'\'':'null' ?>, 'mod':'r'},
         'cmi.mode':{'defaultvalue':'<?php echo $userdata->mode ?>', 'mod':'r'},
         'cmi.objectives._children':{'defaultvalue':objectives_children, 'mod':'r'},
         'cmi.objectives._count':{'mod':'r', 'defaultvalue':'0'},
index ab1d6e1..ca356ba 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8" ?>
-<XMLDB PATH="mod/scorm/db" VERSION="20090420" COMMENT="XMLDB file for Moodle mod/scorm"
+<XMLDB PATH="mod/scorm/db" VERSION="20110731" COMMENT="XMLDB file for Moodle mod/scorm"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:noNamespaceSchemaLocation="../../../lib/xmldb/xmldb.xsd"
 >
         <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" NEXT="scoid"/>
         <FIELD NAME="scoid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="id" NEXT="primaryobj"/>
         <FIELD NAME="primaryobj" TYPE="int" LENGTH="1" NOTNULL="true" UNSIGNED="false" DEFAULT="0" SEQUENCE="false" PREVIOUS="scoid" NEXT="objectiveid"/>
-        <FIELD NAME="objectiveid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="primaryobj" NEXT="satisfiedbymeasure"/>
+        <FIELD NAME="objectiveid" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" PREVIOUS="primaryobj" NEXT="satisfiedbymeasure"/>
         <FIELD NAME="satisfiedbymeasure" TYPE="int" LENGTH="1" NOTNULL="true" UNSIGNED="false" DEFAULT="1" SEQUENCE="false" PREVIOUS="objectiveid" NEXT="minnormalizedmeasure"/>
         <FIELD NAME="minnormalizedmeasure" TYPE="float" LENGTH="11" NOTNULL="true" UNSIGNED="true" DEFAULT="0.0000" SEQUENCE="false" DECIMALS="4" PREVIOUS="satisfiedbymeasure"/>
       </FIELDS>
       </KEYS>
     </TABLE>
   </TABLES>
-</XMLDB>
+</XMLDB>
\ No newline at end of file
index 31d5b55..c5ce688 100644 (file)
@@ -546,6 +546,14 @@ 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');
+        $field = new xmldb_field('objectiveid', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, 'primaryobj');
+        $dbman->change_field_type($table, $field);
+        upgrade_mod_savepoint(true, 2011073100, 'scorm');
+    }
 
     return true;
 }
index d51aef3..2fcb0ec 100644 (file)
@@ -261,6 +261,8 @@ $string['started'] = 'Started on';
 $string['status'] = 'Status';
 $string['statusbar'] = 'Show the status bar';
 $string['student_response'] = 'Response';
+$string['subplugintype_scormreport'] = 'Report';
+$string['subplugintype_scormreport_plural'] = 'Reports';
 $string['suspended'] = 'Suspended';
 $string['syntax'] = 'Syntax error';
 $string['tag_error'] = 'Unknown tag ({$a->tag}) with this content: {$a->value}';
@@ -298,4 +300,3 @@ Handling of Multiple Attempts
 $string['whatgradedesc'] = 'This preference sets the default attempts grading';
 $string['width'] = 'Width';
 $string['window'] = 'Window';
-$string['zlibwarning'] = 'Warning: PHP Zlib compression has been enabled on this site, some users may experience issues loading SCORM objects in certain web browsers.';
index 982329f..51248fd 100644 (file)
@@ -678,6 +678,10 @@ function scorm_course_format_display($user, $course) {
         if (! $cm = get_coursemodule_from_instance('scorm', $scorm->id, $course->id)) {
             print_error('invalidcoursemodule');
         }
+        $contextmodule = get_context_instance(CONTEXT_MODULE, $cm->id);
+        if ((has_capability('mod/scorm:skipview', $contextmodule))) {
+            scorm_simple_play($scorm, $user, $contextmodule);
+        }
         $colspan = '';
         $headertext = '<table width="100%"><tr><td class="title">'.get_string('name').': <b>'.format_string($scorm->name).'</b>';
         if (has_capability('moodle/course:manageactivities', $context)) {
@@ -832,12 +836,11 @@ function scorm_simple_play($scorm, $user, $context) {
         }
         if ($scorm->skipview >= 1) {
             $sco = current($scoes);
-            if (scorm_get_tracks($sco->id, $user->id) === false) {
-                header('Location: player.php?a='.$scorm->id.'&scoid='.$sco->id.'&currentorg='.$orgidentifier);
-                $result = true;
-            } else if ($scorm->skipview == 2) {
-                header('Location: player.php?a='.$scorm->id.'&scoid='.$sco->id.'&currentorg='.$orgidentifier);
-                $result = true;
+            $url = new moodle_url('/mod/scorm/player.php', array('a' => $scorm->id,
+                                                                'currentorg'=>$orgidentifier,
+                                                                'scoid'=>$sco->id));
+            if ($scorm->skipview == 2 || scorm_get_tracks($sco->id, $user->id) === false) {
+                redirect($url);
             }
         }
     }
index 4bf5192..ebf10af 100644 (file)
@@ -32,10 +32,6 @@ class mod_scorm_mod_form extends moodleform_mod {
         if (!$CFG->slasharguments) {
             $mform->addElement('static', '', '', $OUTPUT->notification(get_string('slashargs', 'scorm'), 'notifyproblem'));
         }
-        $zlib = ini_get('zlib.output_compression'); //check for zlib compression - if used, throw error because of IE bug. - SEE MDL-16185
-        if (isset($zlib) && $zlib) {
-            $mform->addElement('static', '', '', $OUTPUT->notification(get_string('zlibwarning', 'scorm'), 'notifyproblem'));
-        }
         //-------------------------------------------------------------------------------
         $mform->addElement('header', 'general', get_string('general', 'form'));
 
index f523509..8467dfd 100644 (file)
@@ -183,6 +183,16 @@ M.mod_scorm.init = function(Y, hide_nav, hide_toc, toc_title, window_name, launc
             }
 
             scorm_layout_widget.setStyle('height', '100%');
+            var center = scorm_layout_widget.getUnitByPosition('center');
+            center.setStyle('height', '100%');
+
+            // calculate the rough new height
+            newheight = YAHOO.util.Dom.getViewportHeight() *.82;
+            if (newheight < 600) {
+                newheight = 600;
+            }
+            scorm_layout_widget.set('height', newheight);
+
             scorm_layout_widget.render();
             scorm_resize_frame();
 
index ed58a07..14ccce0 100644 (file)
@@ -23,6 +23,6 @@
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
-$module->version  = 2011060500;   // The (date) version of this module
+$module->version  = 2011073100;   // The (date) version of this module
 $module->requires = 2010080300;   // The version of Moodle that is required
 $module->cron     = 300;            // How often should cron check this module (seconds)?
index 7e6490d..42c5c58 100644 (file)
@@ -71,8 +71,8 @@ $pagetitle = strip_tags($course->shortname.': '.format_string($scorm->name));
 
 add_to_log($course->id, 'scorm', 'pre-view', 'view.php?id='.$cm->id, "$scorm->id", $cm->id);
 
-if ((has_capability('mod/scorm:skipview', $contextmodule)) && scorm_simple_play($scorm, $USER, $contextmodule)) {
-    exit;
+if ((has_capability('mod/scorm:skipview', $contextmodule))) {
+    scorm_simple_play($scorm, $USER, $contextmodule);
 }
 
 //
index 318af1b..be6867d 100644 (file)
@@ -50,8 +50,9 @@ $string['modulenameplural'] = 'URLs';
 $string['neverseen'] = 'Never seen';
 $string['optionsheader'] = 'Options';
 $string['page-mod-url-x'] = 'Any URL module page';
-$string['parameterinfo'] = 'parameter=variable';
+$string['parameterinfo'] = '&amp;parameter=variable';
 $string['parametersheader'] = 'Parameters';
+$string['parametersheader_help'] = 'Some internal Moodle variables may be automatically appended to the URL. Type your name for the parameter into each text box(es) and then select the required matching variable.';
 $string['pluginadministration'] = 'URL module administration';
 $string['pluginname'] = 'URL';
 $string['popupheight'] = 'Popup height (in pixels)';
index ec15312..da6a720 100644 (file)
@@ -108,7 +108,8 @@ class mod_url_mod_form extends moodleform_mod {
 
         //-------------------------------------------------------
         $mform->addElement('header', 'parameterssection', get_string('parametersheader', 'url'));
-
+        $mform->addElement('static', 'parametersinfo', '', get_string('parametersheader_help', 'url'));
+        $mform->setAdvanced('parametersinfo');
 
         if (empty($this->current->parameters)) {
             $parcount = 5;
index 287b41c..5840c2c 100644 (file)
Binary files a/pix/i/flagged.png and b/pix/i/flagged.png differ
index 35935fe..6962ce5 100644 (file)
Binary files a/pix/i/unflagged.png and b/pix/i/unflagged.png differ
index 8b43360..5ad3de9 100644 (file)
@@ -54,7 +54,6 @@ foreach ((array)$param as $key=>$value) {
     }
 }
 $PAGE->set_url($url);
-$PAGE->set_pagelayout('standard');
 
 $qcobject = new question_category_object($pagevars['cpage'], $thispageurl, $contexts->having_one_edit_tab_cap('categories'), $param->edit, $pagevars['cat'], $param->delete,
                             $contexts->having_cap('moodle/question:add'));
index 5373a89..c52b4a4 100644 (file)
@@ -50,7 +50,6 @@ if (($cmid = optional_param('cmid', 0, PARAM_INT)) !== 0) {
     $url->param('cmid', $cmid);
 }
 $PAGE->set_url($url);
-$PAGE->set_pagelayout('standard');
 
 list($thispageurl, $contexts, $cmid, $cm, $module, $pagevars) =
         question_edit_setup('questions', '/question/edit.php');
index d7c082a..27f74a6 100644 (file)
@@ -1605,6 +1605,8 @@ function question_edit_setup($edittab, $baseurl, $requirecmid = false, $requirec
         $contexts = null;
     }
 
+    $PAGE->set_pagelayout('admin');
+
     $pagevars['qpage'] = optional_param('qpage', -1, PARAM_INT);
 
     //pass 'cat' from page to page and when 'category' comes from a drop down menu
index 0461297..1d53552 100644 (file)
@@ -632,20 +632,26 @@ abstract class question_flags {
             'requires' => array('base', 'dom', 'event-delegate', 'io-base'),
         );
         $actionurl = $CFG->wwwroot . '/question/toggleflag.php';
+        $flagtext = array(
+            0 => get_string('clickflag', 'question'),
+            1 => get_string('clickunflag', 'question')
+        );
         $flagattributes = array(
             0 => array(
                 'src' => $OUTPUT->pix_url('i/unflagged') . '',
                 'title' => get_string('clicktoflag', 'question'),
                 'alt' => get_string('notflagged', 'question'),
+              //  'text' => get_string('clickflag', 'question'),
             ),
             1 => array(
                 'src' => $OUTPUT->pix_url('i/flagged') . '',
                 'title' => get_string('clicktounflag', 'question'),
                 'alt' => get_string('flagged', 'question'),
+               // 'text' => get_string('clickunflag', 'question'),
             ),
         );
         $PAGE->requires->js_init_call('M.core_question_flags.init',
-                array($actionurl, $flagattributes), false, $module);
+                array($actionurl, $flagattributes, $flagtext), false, $module);
         $done = true;
     }
 }
index 910bda9..66597f6 100644 (file)
@@ -243,16 +243,25 @@ class core_question_renderer extends plugin_renderer_base {
      * @return string the img tag.
      */
     protected function get_flag_html($flagged, $id = '') {
+        if ($flagged) {
+            $icon = 'i/flagged';
+            $alt = get_string('flagged', 'question');
+        } else {
+            $icon = 'i/unflagged';
+            $alt = get_string('notflagged', 'question');
+        }
+        $attributes = array(
+            'src' => $this->pix_url($icon),
+            'alt' => $alt,
+        );
         if ($id) {
-            $id = 'id="' . $id . '" ';
+            $attributes['id'] = $id;
         }
+        $img = html_writer::empty_tag('img', $attributes);
         if ($flagged) {
-            $img = 'flagged';
-        } else {
-            $img = 'unflagged';
+            $img .= ' ' . get_string('flagged', 'question');
         }
-        return '<img ' . $id . 'src="' . $this->pix_url('/i/' . $img) .
-                '" alt="' . get_string('flagthisquestion', 'question') . '" />';
+        return $img;
     }
 
     protected function edit_question_link(question_attempt $qa,
index dec240a..172afa5 100644 (file)
@@ -28,8 +28,6 @@ require_once(dirname(__FILE__) . '/../config.php');
 require_once($CFG->dirroot . '/question/editlib.php');
 require_once($CFG->dirroot . '/question/export_form.php');
 
-$PAGE->set_pagelayout('standard');
-
 list($thispageurl, $contexts, $cmid, $cm, $module, $pagevars) =
         question_edit_setup('export', '/question/export.php');
 
index 25edaa5..aa8dac1 100644 (file)
 M.core_question_flags = {
     flagattributes: null,
     actionurl: null,
+    flagtext: null,
     listeners: [],
 
-    init: function(Y, actionurl, flagattributes) {
+    init: function(Y, actionurl, flagattributes, flagtext) {
         M.core_question_flags.flagattributes = flagattributes;
         M.core_question_flags.actionurl = actionurl;
+        M.core_question_flags.flagtext = flagtext;
 
         Y.all('div.questionflag').each(function(flagdiv, i) {
             var checkbox = flagdiv.one('input[type=checkbox]');
@@ -40,36 +42,43 @@ M.core_question_flags = {
                 return;
             }
 
-            var input = Y.Node.create('<input type="hidden" />');
+            var input = Y.Node.create('<input type="hidden" class="questionflagvalue" />');
             input.set('id', checkbox.get('id'));
             input.set('name', checkbox.get('name'));
             input.set('value', checkbox.get('checked') ? 1 : 0);
 
             // Create an image input to replace the img tag.
             var image = Y.Node.create('<input type="image" class="questionflagimage" />');
-            M.core_question_flags.update_flag(input, image);
+            var flagtext = Y.Node.create('<span class="questionflagtext">.</span>');
+            M.core_question_flags.update_flag(input, image, flagtext);
 
             checkbox.remove();
             flagdiv.one('label').remove();
             flagdiv.append(input);
             flagdiv.append(image);
+            flagdiv.append(flagtext);
         });
 
         Y.delegate('click', function(e) {
-            var input = this.previous('input');
+            var input = this.one('input.questionflagvalue');
             input.set('value', 1 - input.get('value'));
-            M.core_question_flags.update_flag(input, this);
-            var postdata = this.previous('input.questionflagpostdata').get('value') +
+            M.core_question_flags.update_flag(input, this.one('input.questionflagimage'),
+                    this.one('span.questionflagtext'));
+            var postdata = this.one('input.questionflagpostdata').get('value') +
                     input.get('value');
 
             e.halt();
             Y.io(M.core_question_flags.actionurl , {method: 'POST', 'data': postdata});
             M.core_question_flags.fire_listeners(postdata);
-        }, document.body, 'input.questionflagimage');
+        }, document.body, 'div.questionflag');
     },
 
-    update_flag: function(input, image) {
-        image.setAttrs(M.core_question_flags.flagattributes[input.get('value')]);
+    update_flag: function(input, image, flagtext) {
+        var value = input.get('value');
+        image.setAttrs(M.core_question_flags.flagattributes[value]);
+        flagtext.replaceChild(flagtext.create(M.core_question_flags.flagtext[value]),
+                flagtext.get('firstChild'));
+        flagtext.set('title', M.core_question_flags.flagattributes[value].title);
     },
 
     add_listener: function(listener) {
index f5f2c58..d9db4bb 100644 (file)
@@ -96,8 +96,8 @@ class qformat_aiken extends qformat_default {
                 } else {
                     // Must be the first line of a new question, since no recognised prefix.
                     $question->qtype = MULTICHOICE;
-                    $question->name = htmlspecialchars(substr($nowline, 0, 50));
-                    $question->questiontext = htmlspecialchars($nowline);
+                    $question->name = shorten_text(s($nowline), 50);
+                    $question->questiontext = s($nowline);
                     $question->single = 1;
                     $question->feedback[] = '';
                 }
index 444d32f..0001e1a 100644 (file)
@@ -42,8 +42,6 @@ if (!$category = $DB->get_record("question_categories", array('id' => $catid)))
     print_error('nocategory', 'question');
 }
 
-$PAGE->set_pagelayout('standard');
-
 $categorycontext = get_context_instance_by_id($category->contextid);
 $category->context = $categorycontext;
 //this page can be called without courseid or cmid in which case
index 1a7ec15..896a3d1 100644 (file)
@@ -103,7 +103,6 @@ if ($cmid){
     $thiscontext = get_context_instance(CONTEXT_MODULE, $cmid);
 } elseif ($courseid) {
     require_login($courseid, false);
-    $PAGE->set_pagelayout('course');
     $thiscontext = get_context_instance(CONTEXT_COURSE, $courseid);
     $module = null;
     $cm = null;
@@ -111,6 +110,7 @@ if ($cmid){
     print_error('missingcourseorcmid', 'question');
 }
 $contexts = new question_edit_contexts($thiscontext);
+$PAGE->set_pagelayout('admin');
 
 if (optional_param('addcancel', false, PARAM_BOOL)) {
     redirect($returnurl);
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 3a1eb34..5216e1f 100644 (file)
@@ -1657,6 +1657,18 @@ abstract class repository {
         }
     }
 
+    /**
+     * Validate Admin Settings Moodle form
+     * @param object $mform Moodle form (passed by reference)
+     * @param array array of ("fieldname"=>value) of submitted data
+     * @param array array of ("fieldname"=>errormessage) of errors
+     * @return array array of errors
+     */
+    public static function type_form_validation($mform, $data, $errors) {
+        return $errors;
+    }
+
+
     /**
      * Edit/Create Instance Settings Moodle form
      * @param object $mform Moodle form (passed by reference)
@@ -1941,6 +1953,21 @@ final class repository_type_form extends moodleform {
 
         $this->add_action_buttons(true, get_string('save','repository'));
     }
+
+    public function validation($data) {
+        $errors = array();
+        $plugin = $this->_customdata['plugin'];
+        $instance = (isset($this->_customdata['instance'])
+                && is_subclass_of($this->_customdata['instance'], 'repository'))
+            ? $this->_customdata['instance'] : null;
+        if (!$instance) {
+            $errors = repository::static_function($plugin, 'type_form_validation', $this, $data, $errors);
+        } else {
+            $errors = $instance->type_form_validation($this, $data, $errors);
+        }
+
+        return $errors;
+    }
 }
 
 /**
index a845f16..67166df 100644 (file)
@@ -57,7 +57,7 @@ class repository_youtube extends repository {
         foreach ($xml->entry as $entry) {
             $media = $entry->children('http://search.yahoo.com/mrss/');
             $title = $media->group->title;
-            $attrs = $media->group->thumbnail->attributes();
+            $attrs = $media->group->thumbnail[2]->attributes();
             $thumbnail = $attrs['url'];
             $arr = explode('/', $entry->id);
             $id = $arr[count($arr)-1];
index 90b2a46..a469b5a 100644 (file)
@@ -249,7 +249,7 @@ $THEME->rarrow      = '&rang;';
 // include.
 ////////////////////////////////////////////////////
 
-// $THEME->renderfactory
+// $THEME->rendererfactory
 
 ////////////////////////////////////////////////////
 // Sets a custom render factory to use with the
index 2a0ce67..95d8e7d 100644 (file)
@@ -38,15 +38,17 @@ body.jsenabled #qtypechoicecontainer {display: block;}
 .que {clear: left;text-align: left;margin: 0 auto 1.8em auto;}
 .dir-rtl .que {text-align: right;}
 
-.que .info {float: left;width: 6em;padding:0.5em;margin-bottom: 1.8em;background: #eee;}
+.que .info {float: left;width: 7em;padding:0.5em;margin-bottom: 1.8em;background: #eee;}
 .que h2.no {margin: 0;font-size: 0.8em;line-height: 1;}
 .que span.qno {font-size: 1.5em;font-weight:bold;}
-.que .state,
-.que .grade,
-.que .editquestion {font-size: 0.8em; margin-top: 0.7em;}
-.que .info .questionflag {margin-top: 1em;margin-right: 1em;text-align: center;}
+.que .info * {font-size: 0.8em;}
+.que .info .state,
+.que .info .grade,
+.que .info .editquestion,
+.que .info .questionflag {margin-top: 0.7em;}
+.que .info .questionflag {cursor:pointer;}
 
-.que .content {margin: 0 0 0 7.5em;}
+.que .content {margin: 0 0 0 8.5em;}
 
 .que .formulation,
 .que .outcome,
index 3681c80..2084061 100644 (file)
@@ -244,7 +244,7 @@ $THEME->layouts = array(
 // include.
 ////////////////////////////////////////////////////
 
-// $THEME->renderfactory
+// $THEME->rendererfactory
 
 ////////////////////////////////////////////////////
 // Sets a custom render factory to use with the
index b01ffbb..7aff519 100644 (file)
@@ -218,7 +218,7 @@ $THEME->layouts = array(
 // include.
 ////////////////////////////////////////////////////
 
-// $THEME->renderfactory
+// $THEME->rendererfactory
 
 ////////////////////////////////////////////////////
 // Sets a custom render factory to use with the
index cd37b57..3729356 100644 (file)
@@ -240,7 +240,7 @@ $THEME->layouts = array(
 // include.
 ////////////////////////////////////////////////////
 
-// $THEME->renderfactory
+// $THEME->rendererfactory
 
 ////////////////////////////////////////////////////
 // Sets a custom render factory to use with the
index 3ad01b0..1fdd596 100644 (file)
@@ -259,7 +259,7 @@ $THEME->hidefromselector = true;
 // include.
 ////////////////////////////////////////////////////
 
-// $THEME->renderfactory
+// $THEME->rendererfactory
 
 ////////////////////////////////////////////////////
 // Sets a custom render factory to use with the
index 1efd840..0431db1 100644 (file)
@@ -200,7 +200,7 @@ input[type="radio"] {
 
 .maincalendar .calendarmonth th,
 .minicalendar th {
-    background: url([[pix:theme|gradient-sb]]) repeat-x 0 0;
+    background: none;
 }
 
 .maincalendar .calendar-controls {
index 0ff150d..25814bd 100644 (file)
@@ -224,7 +224,7 @@ $THEME->layouts = array(
 // include.
 ////////////////////////////////////////////////////
 
-// $THEME->renderfactory
+// $THEME->rendererfactory
 
 ////////////////////////////////////////////////////
 // Sets a custom render factory to use with the
index 0298ace..8c2c89c 100644 (file)
@@ -245,7 +245,7 @@ $THEME->rarrow    = '&rang;';
 // include.
 ////////////////////////////////////////////////////
 
-// $THEME->renderfactory
+// $THEME->rendererfactory
 
 ////////////////////////////////////////////////////
 // Sets a custom render factory to use with the
index 0c5f4ea..2a40a92 100644 (file)
@@ -68,7 +68,7 @@ if ($reset and confirm_sesskey()) {
     echo $output->box_start();
     echo format_text(get_string('choosereadme', 'theme_'.$theme->name), FORMAT_MOODLE);
     echo $output->box_end();
-    echo $output->continue_button($CFG->wwwroot . '/' . $CFG->admin . '/index.php');
+    echo $output->continue_button($CFG->wwwroot . '/theme/index.php');
     echo $output->footer();
     exit;
 }
index e85ce86..823f923 100644 (file)
@@ -233,7 +233,7 @@ $THEME->layouts = array(
 // include.
 ////////////////////////////////////////////////////
 
-// $THEME->renderfactory
+// $THEME->rendererfactory
 
 ////////////////////////////////////////////////////
 // Sets a custom render factory to use with the
index ce7de8d..99b27cf 100644 (file)
@@ -199,7 +199,7 @@ $THEME->layouts = array(
 // include.
 ////////////////////////////////////////////////////
 
-// $THEME->renderfactory
+// $THEME->rendererfactory
 //$THEME->rendererfactory = 'theme_simplespace_renderer_factory';
 ////////////////////////////////////////////////////
 // Sets a custom render factory to use with the
index 680c7dd..a7fb9e3 100644 (file)
@@ -245,7 +245,7 @@ $THEME->rarrow    = '&rang;';
 // include.
 ////////////////////////////////////////////////////
 
-// $THEME->renderfactory
+// $THEME->rendererfactory
 
 ////////////////////////////////////////////////////
 // Sets a custom render factory to use with the
index c7f5929..c5c6ace 100644 (file)
@@ -244,7 +244,7 @@ $THEME->csspostprocess = 'nonzero_process_css';
 // include.
 ////////////////////////////////////////////////////
 
-// $THEME->renderfactory
+// $THEME->rendererfactory
 
 ////////////////////////////////////////////////////
 // Sets a custom render factory to use with the
index 8c76447..84d80a4 100644 (file)
@@ -239,7 +239,7 @@ $THEME->csspostprocess = 'overlay_process_css';
 // include.
 ////////////////////////////////////////////////////
 
-// $THEME->renderfactory
+// $THEME->rendererfactory
 
 ////////////////////////////////////////////////////
 // Sets a custom render factory to use with the
index e4c16af..d1825f2 100644 (file)
@@ -105,7 +105,7 @@ $THEME->editor_sheets = array('editor');
 // include.
 ////////////////////////////////////////////////////
 
-// $THEME->renderfactory
+// $THEME->rendererfactory
 
 ////////////////////////////////////////////////////
 // Sets a custom render factory to use with the
index bf51f90..8bcfe17 100644 (file)
@@ -243,7 +243,7 @@ $THEME->csspostprocess = 'sky_high_process_css';
 // include.
 ////////////////////////////////////////////////////
 
-// $THEME->renderfactory
+// $THEME->rendererfactory
 
 ////////////////////////////////////////////////////
 // Sets a custom render factory to use with the
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.');
     }
 }
index 9da3d69..7f0d18e 100644 (file)
@@ -31,10 +31,10 @@ defined('MOODLE_INTERNAL') || die();
 
 
 
-$version  = 2011071900.00;              // YYYYMMDD      = weekly release date of this DEV branch
+$version  = 2011080300.00;              // YYYYMMDD      = weekly release date of this DEV branch
                                         //         RR    = release increments - 00 in DEV branches
                                         //           .XX = incremental changes
 
-$release  = '2.2dev (Build: 20110719)'; // Human-friendly version name
+$release  = '2.2dev (Build: 20110803)'; // Human-friendly version name
 
 $maturity = MATURITY_ALPHA;             // this version's maturity level