Merge branch 'MDL-30532' of git://github.com/timhunt/moodle
authorSam Hemelryk <sam@moodle.com>
Mon, 12 Dec 2011 22:15:27 +0000 (11:15 +1300)
committerSam Hemelryk <sam@moodle.com>
Mon, 12 Dec 2011 22:15:27 +0000 (11:15 +1300)
26 files changed:
admin/tool/health/index.php
backup/controller/backup_controller.class.php
backup/controller/restore_controller.class.php
backup/moodle2/restore_stepslib.php
backup/util/plan/backup_plan.class.php
course/user.php
enrol/database/lib.php
enrol/ldap/lib.php
enrol/ldap/settings.php
grade/report/grader/lib.php
grade/report/grader/styles.css
lib/db/upgrade.php
lib/moodlelib.php
lib/navigationlib.php
lib/outputcomponents.php
lib/outputrequirementslib.php
lib/pagelib.php
lib/questionlib.php
lib/setup.php
lib/setuplib.php
mod/glossary/import_form.php
mod/lti/locallib.php
notes/index.php
question/category_class.php
user/lib.php
version.php

index bb63e3c..cc17830 100644 (file)
 
     ob_start(); //for whitespace test
     require('../../../config.php');
-
-    // extra whitespace test - intentionally breaks cookieless mode
-    $extraws = '';
-    while (ob_get_level()) {
-        $extraws .= ob_get_contents();
-        ob_end_clean();
-    }
+    $extraws = ob_get_clean();
 
     require_once($CFG->libdir.'/adminlib.php');
 
index 1bab62b..d6d7bd1 100644 (file)
@@ -293,6 +293,14 @@ class backup_controller extends backup implements loggable {
         // Basic/initial prevention against time/memory limits
         set_time_limit(1 * 60 * 60); // 1 hour for 1 course initially granted
         raise_memory_limit(MEMORY_EXTRA);
+        // If this is not a course backup, inform the plan we are not
+        // including all the activities for sure. This will affect any
+        // task/step executed conditionally to stop including information
+        // for section and activity backup. MDL-28180.
+        if ($this->get_type() !== backup::TYPE_1COURSE) {
+            $this->log('notifying plan about excluded activities by type', backup::LOG_DEBUG);
+            $this->plan->set_excluding_activities();
+        }
         return $this->plan->execute();
     }
 
index 50ec102..680e6e9 100644 (file)
@@ -299,6 +299,14 @@ class restore_controller extends backup implements loggable {
         // Basic/initial prevention against time/memory limits
         set_time_limit(1 * 60 * 60); // 1 hour for 1 course initially granted
         raise_memory_limit(MEMORY_EXTRA);
+        // If this is not a course restore, inform the plan we are not
+        // including all the activities for sure. This will affect any
+        // task/step executed conditionally to stop processing information
+        // for section and activity restore. MDL-28180.
+        if ($this->get_type() !== backup::TYPE_1COURSE) {
+            $this->log('notifying plan about excluded activities by type', backup::LOG_DEBUG);
+            $this->plan->set_excluding_activities();
+        }
         return $this->plan->execute();
     }
 
index f83b7c3..14d130a 100644 (file)
@@ -1805,15 +1805,20 @@ class restore_course_completion_structure_step extends restore_structure_step {
 
         $data->course = $this->get_courseid();
 
-        $params = array(
-            'course' => $data->course,
-            'criteriatype' => $data->criteriatype,
-            'method' => $data->method,
-            'value' => $data->value,
-        );
-        $DB->insert_record('course_completion_aggr_methd', $params);
+        // Only create the course_completion_aggr_methd records if
+        // the target course has not them defined. MDL-28180
+        if (!$DB->record_exists('course_completion_aggr_methd', array(
+                    'course' => $data->course,
+                    'criteriatype' => $data->criteriatype))) {
+            $params = array(
+                'course' => $data->course,
+                'criteriatype' => $data->criteriatype,
+                'method' => $data->method,
+                'value' => $data->value,
+            );
+            $DB->insert_record('course_completion_aggr_methd', $params);
+        }
     }
-
 }
 
 
index f21385c..bf217fd 100644 (file)
@@ -44,6 +44,7 @@ class backup_plan extends base_plan implements loggable {
         }
         $this->controller = $controller;
         $this->basepath   = $CFG->tempdir . '/backup/' . $controller->get_backupid();
+        $this->excludingdactivities = false;
         parent::__construct('backup_plan');
     }
 
index c7b9e30..7f7535e 100644 (file)
@@ -55,6 +55,8 @@ if ($mode === 'coursecompletions' or $mode === 'coursecompletion') {
 $coursecontext   = get_context_instance(CONTEXT_COURSE, $course->id);
 $personalcontext = get_context_instance(CONTEXT_USER, $user->id);
 
+$PAGE->set_url('/course/user.php', array('id'=>$id, 'user'=>$user->id, 'mode'=>$mode));
+
 require_login();
 $PAGE->set_pagelayout('admin');
 if (has_capability('moodle/user:viewuseractivitiesreport', $personalcontext) and !is_enrolled($coursecontext)) {
index 33ddad4..08b86f9 100644 (file)
@@ -639,22 +639,44 @@ class enrol_database_plugin extends enrol_plugin {
         if ($createcourses) {
             require_once("$CFG->dirroot/course/lib.php");
 
-            $template        = $this->get_config('templatecourse');
+            $templatecourse = $this->get_config('templatecourse');
             $defaultcategory = $this->get_config('defaultcategory');
 
-            if ($template) {
-                if ($template = $DB->get_record('course', array('shortname'=>$template))) {
+            $template = false;
+            if ($templatecourse) {
+                if ($template = $DB->get_record('course', array('shortname'=>$templatecourse))) {
                     unset($template->id);
                     unset($template->fullname);
                     unset($template->shortname);
                     unset($template->idnumber);
                 } else {
-                    $template = new stdClass();
+                    if ($verbose) {
+                        mtrace("  can not find template for new course!");
+                    }
                 }
-            } else {
+            }
+            if (!$template) {
+                $courseconfig = get_config('moodlecourse');
                 $template = new stdClass();
+                $template->summary        = '';
+                $template->summaryformat  = FORMAT_HTML;
+                $template->format         = $courseconfig->format;
+                $template->numsections    = $courseconfig->numsections;
+                $template->hiddensections = $courseconfig->hiddensections;
+                $template->newsitems      = $courseconfig->newsitems;
+                $template->showgrades     = $courseconfig->showgrades;
+                $template->showreports    = $courseconfig->showreports;
+                $template->maxbytes       = $courseconfig->maxbytes;
+                $template->groupmode      = $courseconfig->groupmode;
+                $template->groupmodeforce = $courseconfig->groupmodeforce;
+                $template->visible        = $courseconfig->visible;
+                $template->lang           = $courseconfig->lang;
+                $template->groupmodeforce = $courseconfig->groupmodeforce;
             }
             if (!$DB->record_exists('course_categories', array('id'=>$defaultcategory))) {
+                if ($verbose) {
+                    mtrace("  default course category does not exist!");
+                }
                 $categories = $DB->get_records('course_categories', array(), 'sortorder', 'id', 0, 1);
                 $first = reset($categories);
                 $defaultcategory = $first->id;
index 90c0830..730ec5a 100644 (file)
@@ -885,16 +885,34 @@ class enrol_ldap_plugin extends enrol_plugin {
         require_once("$CFG->dirroot/course/lib.php");
 
         // Override defaults with template course
-        $course = new stdClass();
+        $template = false;
         if ($this->get_config('template')) {
-            if($template = $DB->get_record('course', array('shortname'=>$this->get_config('template')))) {
+            if ($template = $DB->get_record('course', array('shortname'=>$this->get_config('template')))) {
                 unset($template->id); // So we are clear to reinsert the record
                 unset($template->fullname);
                 unset($template->shortname);
                 unset($template->idnumber);
-                $course = $template;
             }
         }
+        if (!$template) {
+            $courseconfig = get_config('moodlecourse');
+            $template = new stdClass();
+            $template->summary        = '';
+            $template->summaryformat  = FORMAT_HTML;
+            $template->format         = $courseconfig->format;
+            $template->numsections    = $courseconfig->numsections;
+            $template->hiddensections = $courseconfig->hiddensections;
+            $template->newsitems      = $courseconfig->newsitems;
+            $template->showgrades     = $courseconfig->showgrades;
+            $template->showreports    = $courseconfig->showreports;
+            $template->maxbytes       = $courseconfig->maxbytes;
+            $template->groupmode      = $courseconfig->groupmode;
+            $template->groupmodeforce = $courseconfig->groupmodeforce;
+            $template->visible        = $courseconfig->visible;
+            $template->lang           = $courseconfig->lang;
+            $template->groupmodeforce = $courseconfig->groupmodeforce;
+        }
+        $course = $template;
 
         $course->category = $this->get_config('category');
         if (!$DB->record_exists('course_categories', array('id'=>$this->get_config('category')))) {
index edd0217..fbc8c35 100644 (file)
@@ -56,7 +56,7 @@ if ($ADMIN->fulltree) {
         //--- role mapping settings ---
         $settings->add(new admin_setting_heading('enrol_ldap_roles', get_string('roles', 'enrol_ldap'), ''));
         if (!during_initial_install()) {
-            $settings->add(new admin_setting_ldap_rolemapping('enrol_ldap/role_mapping', get_string ('role_mapping_key', 'enrol_ldap', $role->name), get_string ('role_mapping', 'enrol_ldap'), ''));
+            $settings->add(new admin_setting_ldap_rolemapping('enrol_ldap/role_mapping', get_string ('role_mapping_key', 'enrol_ldap'), get_string ('role_mapping', 'enrol_ldap'), ''));
         }
         $options = $yesno;
         $settings->add(new admin_setting_configselect('enrol_ldap/course_search_sub', get_string('course_search_sub_key', 'enrol_ldap'), get_string('course_search_sub', 'enrol_ldap'), 0, $options));
index 8ca6b1e..bcacf6d 100644 (file)
@@ -627,7 +627,7 @@ class grade_report_grader extends grade_report {
             $usercell->scope = 'row';
 
             if ($showuserimage) {
-                $usercell->text = $OUTPUT->container($OUTPUT->user_picture($user), 'userpic');
+                $usercell->text = $OUTPUT->user_picture($user);
             }
 
             $usercell->text .= html_writer::link(new moodle_url('/user/view.php', array('id' => $user->id, 'course' => $this->course->id)), fullname($user));
index b5a3f95..20c78ed 100644 (file)
@@ -269,16 +269,12 @@ table#user-grades td.topleft {
 background-color:#fff;
 }
 
-.path-grade-report-grader div.userpic {
-margin-right:10px;
-float:left;
-}
-
-.path-grade-report-grader div.userpic img {
+.path-grade-report-grader th.user img {
 border:3px double #cecece;
-vertical-align:middle;
+vertical-align:top;
 width:2.7em;
 height:2.7em;
+margin-right:10px;
 }
 
 .path-grade-report-grader a.quickedit {
index e540801..a8a8f51 100644 (file)
@@ -6951,6 +6951,34 @@ FROM
     // Moodle v2.2.0 release upgrade line
     // Put any upgrade step following this
 
+    if ($oldversion < 2011120500.02) {
+
+        upgrade_set_timeout(60*20); // This may take a while
+        // MDL-28180. Some missing restrictions in certain backup & restore operations
+        // were causing incorrect duplicates in the course_completion_aggr_methd table.
+        // This upgrade step takes rid of them.
+        $sql = 'SELECT course, criteriatype, MIN(id) AS minid
+                  FROM {course_completion_aggr_methd}
+              GROUP BY course, criteriatype
+                HAVING COUNT(*) > 1';
+        $duprs = $DB->get_recordset_sql($sql);
+        foreach ($duprs as $duprec) {
+            // We need to handle NULLs in criteriatype diferently
+            if (is_null($duprec->criteriatype)) {
+                $where = 'course = ? AND criteriatype IS NULL AND id > ?';
+                $params = array($duprec->course, $duprec->minid);
+            } else {
+                $where = 'course = ? AND criteriatype = ? AND id > ?';
+                $params = array($duprec->course, $duprec->criteriatype, $duprec->minid);
+            }
+            $DB->delete_records_select('course_completion_aggr_methd', $where, $params);
+        }
+        $duprs->close();
+
+        // Main savepoint reached
+        upgrade_main_savepoint(true, 2011120500.02);
+    }
+
     return true;
 }
 
index d6bba11..dbd6fca 100644 (file)
@@ -2760,7 +2760,11 @@ function require_login($courseorid = NULL, $autologinguest = true, $cm = NULL, $
 
         $access = false;
 
-        if (is_viewing($coursecontext, $USER)) {
+        if (is_role_switched($course->id)) {
+            // ok, user had to be inside this course before the switch
+            $access = true;
+
+        } else if (is_viewing($coursecontext, $USER)) {
             // ok, no need to mess with enrol
             $access = true;
 
index 8645e27..121b432 100644 (file)
@@ -2014,7 +2014,7 @@ class global_navigation extends navigation_node {
                 }
             }
             if ($gradeaccess) {
-                $reporttab->add(get_string('grade'), new moodle_url('/course/user.php', array('mode'=>'grade', 'id'=>$course->id)));
+                $reporttab->add(get_string('grade'), new moodle_url('/course/user.php', array('mode'=>'grade', 'id'=>$course->id, 'user'=>$usercontext->instanceid)));
             }
         }
         // Check the number of nodes in the report node... if there are none remove the node
index c5c2046..16f1fe2 100644 (file)
@@ -270,7 +270,7 @@ class user_picture implements renderable {
      * @return moodle_url
      */
     public function get_url(moodle_page $page, renderer_base $renderer = null) {
-        global $CFG, $FULLME;
+        global $CFG;
 
         if (is_null($renderer)) {
             $renderer = $page->get_renderer('core');
@@ -329,7 +329,7 @@ class user_picture implements renderable {
             // Build a gravatar URL with what we know.
             // If the currently requested page is https then we'll return an
             // https gravatar page.
-            if (strpos($FULLME, 'https://') === 0) {
+            if (strpos($CFG->httpswwwroot, 'https:') === 0) {
                 $imageurl = new moodle_url("https://secure.gravatar.com/avatar/{$md5}", array('s' => $size, 'd' => $imageurl->out(false)));
             } else {
                 $imageurl = new moodle_url("http://www.gravatar.com/avatar/{$md5}", array('s' => $size, 'd' => $imageurl->out(false)));
index 93c5cbe..f216297 100644 (file)
@@ -127,6 +127,7 @@ class page_requirements_manager {
         if (debugging('', DEBUG_DEVELOPER)) {
             $this->yui3loader->filter = YUI_RAW; // for more detailed logging info use YUI_DEBUG here
             $this->yui2loader->filter = YUI_RAW; // for more detailed logging info use YUI_DEBUG here
+            $this->yui2loader->allowRollups = false;
         } else {
             $this->yui3loader->filter = null;
             $this->yui2loader->filter = null;
@@ -160,7 +161,7 @@ class page_requirements_manager {
         $this->M_yui_loader->base         = $this->yui3loader->base;
         $this->M_yui_loader->comboBase    = $this->yui3loader->comboBase;
         $this->M_yui_loader->combine      = $this->yui3loader->combine;
-        $this->M_yui_loader->filter       = ($this->yui3loader->filter == YUI_DEBUG) ? 'debug' : '';
+        $this->M_yui_loader->filter       = (string)$this->yui3loader->filter;
         $this->M_yui_loader->insertBefore = 'firstthemesheet';
         $this->M_yui_loader->modules      = array();
         $this->M_yui_loader->groups       = array(
@@ -267,7 +268,7 @@ class page_requirements_manager {
      * Initialise with the bits of JavaScript that every Moodle page should have.
      *
      * @param moodle_page $page
-     * @param core_renderer $output
+     * @param core_renderer $renderer
      */
     protected function init_requirements_data(moodle_page $page, core_renderer $renderer) {
         global $CFG;
@@ -547,7 +548,7 @@ class page_requirements_manager {
     /**
      * Returns true if the module has already been loaded.
      *
-     * @param string|array $modulename
+     * @param string|array $module
      * @return bool True if the module has already been loaded
      */
     protected function js_module_loaded($module) {
@@ -818,7 +819,7 @@ class page_requirements_manager {
      * (e.g. and array) that you pass to JavaScript with {@link data_for_js()}.
      *
      * @param string $identifier the desired string.
-     * @param string $module the language file to look in.
+     * @param string $component the language file to look in.
      * @param mixed $a any extra data to add into the string (optional).
      */
     public function string_for_js($identifier, $component, $a = NULL) {
@@ -918,7 +919,8 @@ class page_requirements_manager {
 
     /**
      * Get the inline JavaScript code that need to appear in a particular place.
-     * @return bool $ondomready
+     * @param bool $ondomready
+     * @return string
      */
     protected function get_javascript_code($ondomready) {
         $where = $ondomready ? 'ondomready' : 'normal';
@@ -972,10 +974,14 @@ class page_requirements_manager {
             $code .= '<link rel="stylesheet" type="text/css" href="'.$this->yui3loader->base.'cssbase/base-min.css" />';
         }
 
-        if (debugging('', DEBUG_DEVELOPER)) {
-            $code .= '<script type="text/javascript" src="'.$this->yui3loader->base.'yui/yui-debug.js"></script>';
-        } else {
-            $code .= '<script type="text/javascript" src="'.$this->yui3loader->base.'yui/yui-min.js"></script>';
+        $code .= '<script type="text/javascript" src="'.$this->yui3loader->base.'yui/yui-min.js"></script>';
+
+        if ($this->yui3loader->filter === YUI_RAW) {
+            $code = str_replace('-min.css', '.css', $code);
+            $code = str_replace('-min.js', '.js', $code);
+        } else if ($this->yui3loader->filter === YUI_DEBUG) {
+            $code = str_replace('-min.css', '.css', $code);
+            $code = str_replace('-min.js', '-debug.js', $code);
         }
 
         return $code;
@@ -1045,6 +1051,7 @@ class page_requirements_manager {
 
     /**
      * Adds extra modules specified after printing of page header
+     * @return string
      */
     protected function get_extra_modules_code() {
         if (empty($this->extramodules)) {
@@ -1059,6 +1066,8 @@ class page_requirements_manager {
      * Normally, this method is called automatically by the code that prints the
      * <head> tag. You should not normally need to call it in your own code.
      *
+     * @param moodle_page $page
+     * @param core_renderer $renderer
      * @return string the HTML code to to inside the <head> tag.
      */
     public function get_head_code(moodle_page $page, core_renderer $renderer) {
index f01e74c..aafe23a 100644 (file)
@@ -1185,6 +1185,8 @@ class moodle_page {
         }
 
         // now the real test and redirect!
+        // NOTE: do NOT use this test for detection of https on current page because this code is not compatible with SSL proxies,
+        //       instead use strpos($CFG->httpswwwroot, 'https:') === 0
         if (strpos($FULLME, 'https:') !== 0) {
             // this may lead to infinite redirect on misconfigured sites, in that case use $CFG->loginhttps=0; in /config.php
             redirect($this->_url);
index 6e605db..2c77eda 100644 (file)
@@ -484,7 +484,7 @@ function question_delete_course_category($category, $newcategory, $feedback=true
 /**
  * Enter description here...
  *
- * @param string $questionids list of questionids
+ * @param array $questionids of question ids
  * @param object $newcontext the context to create the saved category in.
  * @param string $oldplace a textual description of the think being deleted,
  *      e.g. from get_context_name
@@ -571,7 +571,7 @@ function question_delete_activity($cm, $feedback=true) {
  * function also have to do other work, which is why you should not call this method
  * directly from outside the questionbank.
  *
- * @param string $questionids a comma-separated list of question ids.
+ * @param array $questionids of question ids.
  * @param integer $newcategoryid the id of the category to move to.
  */
 function question_move_questions_to_category($questionids, $newcategoryid) {
index 2b51b1b..2f0f1e4 100644 (file)
@@ -341,6 +341,10 @@ global $MCACHE;
 
 /**
  * Full script path including all params, slash arguments, scheme and host.
+ *
+ * Note: Do NOT use for getting of current page URL or detection of https,
+ * instead use $PAGE->url or strpos($CFG->httpswwwroot, 'https:') === 0
+ *
  * @global string $FULLME
  * @name $FULLME
  */
index c206d10..cc1cd12 100644 (file)
@@ -1193,7 +1193,12 @@ function make_upload_directory($directory, $exceptiononerror = true) {
  */
 function make_temp_directory($directory, $exceptiononerror = true) {
     global $CFG;
-    protect_directory($CFG->tempdir);
+    if ($CFG->tempdir !== "$CFG->dataroot/temp") {
+        check_dir_exists($CFG->tempdir, true, true);
+        protect_directory($CFG->tempdir);
+    } else {
+        protect_directory($CFG->dataroot);
+    }
     return make_writable_directory("$CFG->tempdir/$directory", $exceptiononerror);
 }
 
@@ -1206,7 +1211,12 @@ function make_temp_directory($directory, $exceptiononerror = true) {
  */
 function make_cache_directory($directory, $exceptiononerror = true) {
     global $CFG;
-    protect_directory($CFG->cachedir);
+    if ($CFG->cachedir !== "$CFG->dataroot/cache") {
+        check_dir_exists($CFG->cachedir, true, true);
+        protect_directory($CFG->cachedir);
+    } else {
+        protect_directory($CFG->dataroot);
+    }
     return make_writable_directory("$CFG->cachedir/$directory", $exceptiononerror);
 }
 
index 475644b..2f37a14 100644 (file)
@@ -17,7 +17,7 @@ class mod_glossary_import_form extends moodleform {
         $options = array();
         $options['current'] = get_string('currentglossary', 'glossary');
         $options['newglossary'] = get_string('newglossary', 'glossary');
-        $mform->addElement('select', 'dest', get_string('currentglossary', 'glossary'), $options);
+        $mform->addElement('select', 'dest', get_string('destination', 'glossary'), $options);
         $mform->addHelpButton('dest', 'destination', 'glossary');
         $mform->addElement('checkbox', 'catsincl', get_string('importcategories', 'glossary'));
         $submit_string = get_string('submit');
index 53425a3..74f0276 100644 (file)
@@ -1127,8 +1127,8 @@ function lti_get_launch_container($lti, $toolconfig) {
 }
 
 function lti_request_is_using_ssl() {
-    global $FULLME;
-    return (stripos($FULLME, 'https://') === 0);
+    global $CFG;
+    return (stripos($CFG->httpswwwroot, 'https://') === 0);
 }
 
 function lti_ensure_url_is_https($url) {
index f1371d3..54fdfc4 100644 (file)
@@ -84,8 +84,6 @@ if ($userid) {
     if (has_capability('moodle/course:viewparticipants', $coursecontext) || has_capability('moodle/site:viewparticipants', $systemcontext)) {
         $link = new moodle_url('/user/index.php',array('id'=>$course->id));
     }
-    $PAGE->navbar->add(get_string('participants'), $link);
-    $PAGE->navbar->add($strnotes);
 }
 
 $PAGE->set_pagelayout('course');
index 8881ce4..07c2d91 100644 (file)
@@ -360,7 +360,7 @@ class question_category_object {
         global $DB;
         $questionids = $DB->get_records_select_menu('question',
                 'category = ? AND (parent = 0 OR parent = id)', array($oldcat), '', 'id,1');
-        question_move_questions_to_category($questionids, $newcat);
+        question_move_questions_to_category(array_keys($questionids), $newcat);
     }
 
     /**
index 66f8404..7e0f27d 100644 (file)
@@ -47,6 +47,10 @@ function user_create_user($user) {
 /// insert the user into the database
     $newuserid = $DB->insert_record('user', $user);
 
+/// trigger user_created event on the full database user row
+    $newuser = $DB->get_record('user', array('id' => $newuserid));
+    events_trigger('user_created', $newuser);
+
 /// create USER context for this user
     get_context_instance(CONTEXT_USER, $newuserid);
 
@@ -71,6 +75,11 @@ function user_update_user($user) {
 
     $user->timemodified = time();
     $DB->update_record('user', $user);
+
+    /// trigger user_updated event on the full database user row
+    $updateduser = $DB->get_record('user', array('id' => $user->id));
+    events_trigger('user_updated', $updateduser);
+
 }
 
 
index 868b083..ce0a35c 100644 (file)
@@ -30,7 +30,7 @@
 defined('MOODLE_INTERNAL') || die();
 
 
-$version  = 2011120500.01;              // YYYYMMDD      = weekly release date of this DEV branch
+$version  = 2011120500.02;              // YYYYMMDD      = weekly release date of this DEV branch
                                         //         RR    = release increments - 00 in DEV branches
                                         //           .XX = incremental changes