Merge branch 'MDL-30472-master' of git://github.com/ankitagarwal/moodle
authorAparup Banerjee <aparup@moodle.com>
Tue, 13 Dec 2011 06:34:42 +0000 (14:34 +0800)
committerAparup Banerjee <aparup@moodle.com>
Tue, 13 Dec 2011 06:34:42 +0000 (14:34 +0800)
47 files changed:
admin/tool/health/index.php
admin/tool/qeupgradehelper/locallib.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
blocks/glossary_random/block_glossary_random.php
course/format/topics/format.php
course/format/weeks/format.php
course/moodleform_mod.php
course/user.php
enrol/database/lib.php
enrol/ldap/lib.php
enrol/ldap/settings.php
filter/glossary/filter.php
grade/report/grader/lib.php
grade/report/grader/styles.css
lang/en/condition.php
lib/blocklib.php
lib/db/upgrade.php
lib/moodlelib.php
lib/navigationlib.php
lib/outputcomponents.php
lib/outputrequirementslib.php
lib/pagelib.php
lib/phpmailer/class.phpmailer.php
lib/questionlib.php
lib/setup.php
lib/setuplib.php
mod/glossary/db/access.php
mod/glossary/import_form.php
mod/glossary/lang/en/glossary.php
mod/glossary/lib.php
mod/glossary/rsslib.php
mod/glossary/version.php
mod/glossary/view.php
mod/lti/locallib.php
mod/quiz/lib.php
mod/scorm/datamodels/scorm_13.js.php
notes/index.php
question/category_class.php
question/type/questiontypebase.php
question/type/shortanswer/questiontype.php
question/type/upgrade.txt
user/index.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 7c001d4..62cfca6 100644 (file)
@@ -178,7 +178,7 @@ abstract class tool_qeupgradehelper_quiz_list {
             html_writer::link(new moodle_url('/course/view.php',
                     array('id' => $quizinfo->courseid)), format_string($quizinfo->shortname)),
             html_writer::link(new moodle_url('/mod/quiz/view.php',
-                    array('id' => $quizinfo->name)), format_string($quizinfo->name)),
+                    array('q' => $quizinfo->id)), format_string($quizinfo->name)),
             $quizinfo->attemptcount,
             $quizinfo->questionattempts ? $quizinfo->questionattempts : 0,
         );
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 72fc75b..7eab69b 100644 (file)
@@ -118,6 +118,10 @@ class block_glossary_random extends block_base {
     function get_content() {
         global $USER, $CFG, $DB;
 
+        if (!has_capability('mod/glossary:read', $this->context)) {
+            return "";
+        }
+
         if (empty($this->config->glossary)) {
             $this->content->text   = get_string('notyetconfigured','block_glossary_random');
             $this->content->footer = '';
index fe8fb3e..7e24305 100644 (file)
@@ -110,7 +110,7 @@ if ($thissection->summary or $thissection->sequence or $PAGE->user_is_editing())
     if ($PAGE->user_is_editing() && has_capability('moodle/course:update', $coursecontext)) {
         echo '<a title="'.$streditsummary.'" '.
              ' href="editsection.php?id='.$thissection->id.'"><img src="'.$OUTPUT->pix_url('t/edit') . '" '.
-             ' class="icon edit" alt="'.$streditsummary.'" /></a>';
+             ' class="iconsmall edit" alt="'.$streditsummary.'" /></a>';
     }
     echo '</div>';
 
@@ -234,7 +234,7 @@ while ($section <= $course->numsections) {
 
             if ($PAGE->user_is_editing() && has_capability('moodle/course:update', get_context_instance(CONTEXT_COURSE, $course->id))) {
                 echo ' <a title="'.$streditsummary.'" href="editsection.php?id='.$thissection->id.'">'.
-                     '<img src="'.$OUTPUT->pix_url('t/edit') . '" class="icon edit" alt="'.$streditsummary.'" /></a><br /><br />';
+                     '<img src="'.$OUTPUT->pix_url('t/edit') . '" class="iconsmall edit" alt="'.$streditsummary.'" /></a><br /><br />';
             }
             echo '</div>';
 
index cf48505..74fb964 100644 (file)
@@ -103,7 +103,7 @@ defined('MOODLE_INTERNAL') || die();
         if ($PAGE->user_is_editing() && has_capability('moodle/course:update', get_context_instance(CONTEXT_COURSE, $course->id))) {
             echo '<p><a title="'.$streditsummary.'" '.
                  ' href="editsection.php?id='.$thissection->id.'"><img src="'.$OUTPUT->pix_url('t/edit') . '" '.
-                 ' class="icon edit" alt="'.$streditsummary.'" /></a></p>';
+                 ' class="iconsmall edit" alt="'.$streditsummary.'" /></a></p>';
         }
         echo '</div>';
 
@@ -234,7 +234,7 @@ defined('MOODLE_INTERNAL') || die();
 
                 if ($PAGE->user_is_editing() && has_capability('moodle/course:update', get_context_instance(CONTEXT_COURSE, $course->id))) {
                     echo ' <a title="'.$streditsummary.'" href="editsection.php?id='.$thissection->id.'">'.
-                         '<img src="'.$OUTPUT->pix_url('t/edit') . '" class="icon edit" alt="'.$streditsummary.'" /></a><br /><br />';
+                         '<img src="'.$OUTPUT->pix_url('t/edit') . '" class="iconsmall edit" alt="'.$streditsummary.'" /></a><br /><br />';
                 }
                 echo '</div>';
 
index a531061..75e0874 100644 (file)
@@ -313,6 +313,35 @@ abstract class moodleform_mod extends moodleform {
             $errors['availablefrom'] = get_string('badavailabledates', 'condition');
         }
 
+        // Conditions: Verify that the grade conditions are numbers, and make sense.
+        if (array_key_exists('conditiongradegroup', $data)) {
+            foreach ($data['conditiongradegroup'] as $i => $gradedata) {
+                if ($gradedata['conditiongrademin'] !== '' && !is_numeric($gradedata['conditiongrademin'])) {
+                    $errors["conditiongradegroup[{$i}]"] = get_string('gradesmustbenumeric', 'condition');
+                    continue;
+                }
+                if ($gradedata['conditiongrademax'] !== '' && !is_numeric($gradedata['conditiongrademax'])) {
+                    $errors["conditiongradegroup[{$i}]"] = get_string('gradesmustbenumeric', 'condition');
+                    continue;
+                }
+                if ($gradedata['conditiongrademin'] !== '' && $gradedata['conditiongrademax'] !== '' &&
+                        $gradedata['conditiongrademax'] < $gradedata['conditiongrademin']) {
+                    $errors["conditiongradegroup[{$i}]"] = get_string('badgradelimits', 'condition');
+                    continue;
+                }
+                if ($gradedata['conditiongrademin'] === '' && $gradedata['conditiongrademax'] === '' &&
+                        $gradedata['conditiongradeitemid']) {
+                    $errors["conditiongradegroup[{$i}]"] = get_string('gradeitembutnolimits', 'condition');
+                    continue;
+                }
+                if (($gradedata['conditiongrademin'] !== '' || $gradedata['conditiongrademax'] !== '') &&
+                        !$gradedata['conditiongradeitemid']) {
+                    $errors["conditiongradegroup[{$i}]"] = get_string('gradelimitsbutnoitem', 'condition');
+                    continue;
+                }
+            }
+        }
+
         return $errors;
     }
 
@@ -471,8 +500,6 @@ abstract class moodleform_mod extends moodleform {
             $grouparray[] =& $mform->createElement('static', '', '','% '.get_string('grade_upto','condition').' ');
             $grouparray[] =& $mform->createElement('text', 'conditiongrademax','',array('size'=>3));
             $grouparray[] =& $mform->createElement('static', '', '','%');
-            $mform->setType('conditiongrademin',PARAM_FLOAT);
-            $mform->setType('conditiongrademax',PARAM_FLOAT);
             $group = $mform->createElement('group','conditiongradegroup',
                 get_string('gradecondition', 'condition'),$grouparray);
 
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 8592626..6de83d6 100644 (file)
@@ -57,7 +57,7 @@ class filter_glossary extends moodle_text_filter {
             $nothingtodo = false;
         }
 
-        if ($nothingtodo === true) {
+        if (($nothingtodo === true) || (!has_capability('mod/glossary:read', $this->context))) {
             return $text;
         }
 
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 ed05e32..9a1c764 100644 (file)
@@ -32,6 +32,7 @@ $string['availablefrom_help'] = 'Access from/to dates determine when students ca
 The difference between access from/to dates and availability settings for the activity is that outside the set dates the latter allows students to view the activity description, whereas access from/to dates prevent access completely.';
 $string['availableuntil'] = 'Allow access until';
 $string['badavailabledates'] = 'Invalid dates. If you set both dates, the \'Allow access from\' date should be before the \'until\' date.';
+$string['badgradelimits'] = 'If you set both an upper and lower grade limit, the upper limit must be higher than the lower limit.';
 $string['completion_complete'] = 'must be marked complete';
 $string['completioncondition'] = 'Activity completion condition';
 $string['completioncondition_help'] = 'This setting determines any activity completion conditions which must be met in order to access the activity. Note that completion tracking must first be set before an activity completion condition can be set.
@@ -48,6 +49,9 @@ $string['gradecondition_help'] = 'This setting determines any grade conditions w
 
 Multiple grade conditions may be set if desired. If so, the activity will only allow access when ALL grade conditions are met.';
 $string['grade_upto'] = 'and less than';
+$string['gradeitembutnolimits'] = 'You must enter an upper or lower limit, or both.';
+$string['gradelimitsbutnoitem'] = 'You must choose a grade item.';
+$string['gradesmustbenumeric'] = 'The minimum and maximum grades must be numeric (or blank).';
 $string['none'] = '(none)';
 $string['notavailableyet'] = 'Not available yet';
 $string['requires_completion_0'] = 'Not available unless the activity <strong>{$a}</strong> is incomplete.';
index d5d1c3b..508b94c 100644 (file)
@@ -1467,8 +1467,10 @@ class block_manager {
         } else {
             $newweight = ceil($newweight);
             for ($weight = $bestgap - 1; $weight >= $newweight; $weight--) {
-                foreach ($usedweights[$weight] as $biid) {
-                    $this->reposition_block($biid, $newregion, $weight + 1);
+                if (array_key_exists($weight, $usedweights)) {
+                    foreach ($usedweights[$weight] as $biid) {
+                        $this->reposition_block($biid, $newregion, $weight + 1);
+                    }
                 }
             }
             $this->reposition_block($block->instance->id, $newregion, $newweight);
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 094f6be..430cbc9 100644 (file)
@@ -1080,9 +1080,9 @@ class PHPMailer {
 
     $result .= $this->HeaderLine('Date', self::RFCDate());
     if($this->Sender == '') {
-      $result .= $this->HeaderLine('Return-Path', trim($this->From));
+      $result .= $this->HeaderLine('Return-Path', trim($this->SecureHeader($this->From))); // Moodle modification
     } else {
-      $result .= $this->HeaderLine('Return-Path', trim($this->Sender));
+      $result .= $this->HeaderLine('Return-Path', trim($this->SecureHeader($this->Sender))); // Moodle modification
     }
 
     // To be created automatically by mail()
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 13ca170..0116daa 100644 (file)
 
 $capabilities = array(
 
+    'mod/glossary:read' => array(
+
+        'captype' => 'read',
+        'contextlevel' => CONTEXT_MODULE,
+        'archetypes' => array(
+            'guest' => CAP_ALLOW,
+            'student' => CAP_ALLOW,
+            'teacher' => CAP_ALLOW,
+            'editingteacher' => CAP_ALLOW,
+            'manager' => CAP_ALLOW
+        )
+    ),
+
+
     'mod/glossary:write' => array(
 
         'riskbitmask' => RISK_SPAM,
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 535f758..4c4827c 100644 (file)
@@ -178,6 +178,7 @@ $string['glossary:managecategories'] = 'Manage categories';
 $string['glossary:managecomments'] = 'Manage comments';
 $string['glossary:manageentries'] = 'Manage entries';
 $string['glossary:rate'] = 'Rate entries';
+$string['glossary:read'] = 'Read entries';
 $string['glossarytype'] = 'Glossary type';
 $string['glossarytype_help'] = 'A main glossary is a glossary in which entries from secondary glossaries can be imported. There can only be one main glossary in a course. if glossary entry import is not required, all glossaries in the course can be secondary glossaries.';
 $string['glossary:view'] = 'View glossary';
index 2c4ac78..eb22669 100644 (file)
@@ -323,7 +323,7 @@ function glossary_user_complete($course, $user, $mod, $glossary) {
  * @return bool
  */
 function glossary_print_recent_activity($course, $viewfullnames, $timestart) {
-    global $CFG, $USER, $DB, $OUTPUT;
+    global $CFG, $USER, $DB, $OUTPUT, $PAGE;
 
     //TODO: use timestamp in approved field instead of changing timemodified when approving in 2.0
     if (!defined('GLOSSARY_RECENT_ACTIVITY_LIMIT')) {
@@ -351,6 +351,9 @@ function glossary_print_recent_activity($course, $viewfullnames, $timestart) {
     $approvals = array();
     foreach ($ids as $glinstanceid => $glcmid) {
         $context = get_context_instance(CONTEXT_MODULE, $glcmid);
+        if (!has_capability('mod/glossary:read', $context)) {
+            continue;
+        }
         // get records glossary entries that are approved if user has no capability to approve entries.
         if (has_capability('mod/glossary:approve', $context)) {
             $approvals[] = ' ge.glossaryid = :glsid'.$glinstanceid.' ';
@@ -2771,7 +2774,7 @@ function glossary_extend_settings_navigation(settings_navigation $settings, navi
 
     $glossary = $DB->get_record('glossary', array("id" => $PAGE->cm->instance));
 
-    if (!empty($CFG->enablerssfeeds) && !empty($CFG->glossary_enablerssfeeds) && $glossary->rsstype && $glossary->rssarticles  && can_access_course($PAGE->course, $USER)) {
+    if (!empty($CFG->enablerssfeeds) && !empty($CFG->glossary_enablerssfeeds) && $glossary->rsstype && $glossary->rssarticles && has_capability('mod/glossary:read', $PAGE->cm->context)) {
         require_once("$CFG->libdir/rsslib.php");
 
         $string = get_string('rsstype','forum');
index 5134126..bb84a6d 100644 (file)
@@ -23,8 +23,7 @@
                 $course = $DB->get_record('course', array('id'=>$cm->course), '*', MUST_EXIST);
             }
             //context id from db should match the submitted one
-            //no specific capability required to view glossary entries so just check user is enrolled
-            if ($context->id != $modcontext->id || !can_access_course($course, $USER)) {
+            if ($context->id != $modcontext->id || !has_capability('mod/glossary:read', $modcontext)) {
                 return null;
             }
         }
index 250d937..aa71ab0 100644 (file)
@@ -25,7 +25,7 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$module->version   = 2011112900;       // The current module version (Date: YYYYMMDDXX)
+$module->version   = 2011120200;       // The current module version (Date: YYYYMMDDXX)
 $module->requires  = 2011112900;       // Requires this Moodle version
 $module->component = 'mod_glossary';   // Full name of the plugin (used for diagnostics)
 $module->cron      = 0;
index fe16b5e..420d604 100644 (file)
@@ -49,6 +49,7 @@ if (!empty($id)) {
 
 require_course_login($course->id, true, $cm);
 $context = get_context_instance(CONTEXT_MODULE, $cm->id);
+require_capability('mod/glossary:read', $context);
 
 // Prepare format_string/text options
 $fmtoptions = array(
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 1a45b15..9e2bf23 100644 (file)
@@ -1447,7 +1447,7 @@ function quiz_num_attempt_summary($quiz, $cm, $returnzero = false, $currentgroup
         if (groups_get_activity_groupmode($cm)) {
             $a->total = $numattempts;
             if ($currentgroup) {
-                $a->group = $DB->count_records_sql('SELECT count(1) FROM ' .
+                $a->group = $DB->count_records_sql('SELECT COUNT(DISTINCT qa.id) FROM ' .
                         '{quiz_attempts} qa JOIN ' .
                         '{groups_members} gm ON qa.userid = gm.userid ' .
                         'WHERE quiz = ? AND preview = 0 AND groupid = ?',
@@ -1455,7 +1455,7 @@ function quiz_num_attempt_summary($quiz, $cm, $returnzero = false, $currentgroup
                 return get_string('attemptsnumthisgroup', 'quiz', $a);
             } else if ($groups = groups_get_all_groups($cm->course, $USER->id, $cm->groupingid)) {
                 list($usql, $params) = $DB->get_in_or_equal(array_keys($groups));
-                $a->group = $DB->count_records_sql('SELECT count(1) FROM ' .
+                $a->group = $DB->count_records_sql('SELECT COUNT(DISTINCT qa.id) FROM ' .
                         '{quiz_attempts} qa JOIN ' .
                         '{groups_members} gm ON qa.userid = gm.userid ' .
                         'WHERE quiz = ? AND preview = 0 AND ' .
index d6e0b03..8349cb1 100644 (file)
@@ -200,10 +200,10 @@ function SCORMapi1_3() {
         'cmi.learner_id':{'defaultvalue':'<?php echo $userdata->student_id ?>', 'mod':'r'},
         'cmi.learner_name':{'defaultvalue':'<?php echo $userdata->student_name ?>', 'mod':'r'},
         'cmi.learner_preference._children':{'defaultvalue':student_preference_children, 'mod':'r'},
-        'cmi.learner_preference.audio_level':{'defaultvalue':'1', 'format':CMIDecimal, 'range':audio_range, 'mod':'rw'},
-        'cmi.learner_preference.language':{'defaultvalue':'', 'format':CMILang, 'mod':'rw'},
-        '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.learner_preference.audio_level':{'defaultvalue':<?php echo !empty($userdata->{'cmi.learner_preference.audio_level'})?'\''.$userdata->{'cmi.learner_preference.audio_level'}.'\'':'\'1\'' ?>, 'format':CMIDecimal, 'range':audio_range, 'mod':'rw'},
+        'cmi.learner_preference.language':{'defaultvalue':<?php echo !empty($userdata->{'cmi.learner_preference.language'})?'\''.$userdata->{'cmi.learner_preference.language'}.'\'':'\'\'' ?>, 'format':CMILang, 'mod':'rw'},
+        'cmi.learner_preference.delivery_speed':{'defaultvalue':<?php echo !empty($userdata->{'cmi.learner_preference.delivery_speed'})?'\''.$userdata->{'cmi.learner_preference.delivery_speed'}.'\'':'\'1\'' ?>, 'format':CMIDecimal, 'range':speed_range, 'mod':'rw'},
+        'cmi.learner_preference.audio_captioning':{'defaultvalue':<?php echo !empty($userdata->{'cmi.learner_preference.audio_captioning'})?'\''.$userdata->{'cmi.learner_preference.audio_captioning'}.'\'':'\'0\'' ?>, 'format':CMISInteger, 'range':text_range, 'mod':'rw'},
         'cmi.location':{'defaultvalue':<?php echo !empty($userdata->{'cmi.location'})?'\''.$userdata->{'cmi.location'}.'\'':'null' ?>, 'format':CMIString1000, 'mod':'rw'},
         'cmi.max_time_allowed':{'defaultvalue':<?php echo !empty($userdata->attemptAbsoluteDurationLimit)?'\''.$userdata->attemptAbsoluteDurationLimit.'\'':'null' ?>, 'mod':'r'},
         'cmi.mode':{'defaultvalue':'<?php echo $userdata->mode ?>', 'mod':'r'},
@@ -219,7 +219,7 @@ function SCORMapi1_3() {
         'cmi.objectives.n.completion_status':{'defaultvalue':'unknown', 'pattern':CMIIndex, 'format':CMICStatus, 'mod':'rw'},
         'cmi.objectives.n.progress_measure':{'defaultvalue':null, 'format':CMIDecimal, 'range':progress_range, 'mod':'rw'},
         'cmi.objectives.n.description':{'pattern':CMIIndex, 'format':CMILangString250, 'mod':'rw'},
-        'cmi.progress_measure':{'defaultvalue':<?php echo !empty($userdata->{'cmi.progess_measure'})?'\''.$userdata->{'cmi.progress_measure'}.'\'':'null' ?>, 'format':CMIDecimal, 'range':progress_range, 'mod':'rw'},
+        'cmi.progress_measure':{'defaultvalue':<?php echo !empty($userdata->{'cmi.progress_measure'})?'\''.$userdata->{'cmi.progress_measure'}.'\'':'null' ?>, 'format':CMIDecimal, 'range':progress_range, 'mod':'rw'},
         'cmi.scaled_passing_score':{'defaultvalue':<?php echo !empty($userdata->{'cmi.scaled_passing_score'})?'\''.$userdata->{'cmi.scaled_passing_score'}.'\'':'null' ?>, 'format':CMIDecimal, 'range':scaled_range, 'mod':'r'},
         'cmi.score._children':{'defaultvalue':score_children, 'mod':'r'},
         'cmi.score.scaled':{'defaultvalue':<?php echo !empty($userdata->{'cmi.score.scaled'})?'\''.$userdata->{'cmi.score.scaled'}.'\'':'null' ?>, 'format':CMIDecimal, 'range':scaled_range, 'mod':'rw'},
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 5e76deb..ba8858d 100644 (file)
@@ -165,7 +165,7 @@ class question_type {
      * If you use extra_question_fields, overload this function to return question id field name
      *  in case you table use another name for this column
      */
-    protected function questionid_column_name() {
+    public function questionid_column_name() {
         return 'questionid';
     }
 
@@ -176,7 +176,7 @@ class question_type {
      *
      * @return mixed array as above, or null to tell the base class to do nothing.
      */
-    protected function extra_answer_fields() {
+    public function extra_answer_fields() {
         return null;
     }
 
index b43e3ee..ff9df64 100644 (file)
@@ -42,7 +42,7 @@ class qtype_shortanswer extends question_type {
         return array('question_shortanswer', 'answers', 'usecase');
     }
 
-    protected function questionid_column_name() {
+    public function questionid_column_name() {
         return 'question';
     }
 
index aaf2213..acaacd3 100644 (file)
@@ -38,3 +38,8 @@ $string['pluginnameediting'] = 'Editing a Description';
 $string['pluginnamesummary'] = 'This is not actually a question. Instead it is a way to add some instructions, rubric or other content to the activity. This is similar to the way that labels can be used to add content to the course page.';
 
 The old strings will continue to work, but only until Moodle 2.3 is released.
+
+* If you are using the facilities provided by overriding the extra_answer_fields
+  or questionid_column_name methods, then you must change these to be public
+  methods. (This is required so that backup and restore can be made to work
+  automatically. MDL-24408, MDL-25617, MDL-30562)
index 5954571..362d2be 100644 (file)
 
     $isseparategroups = ($course->groupmode == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', $context));
 
-    if ($course->id===SITEID) {
-        $PAGE->navbar->ignore_active();
-    }
-
-    $PAGE->navbar->add(get_string('participants'));
     $PAGE->set_title("$course->shortname: ".get_string('participants'));
     $PAGE->set_heading($course->fullname);
     $PAGE->set_pagetype('course-view-' . $course->format);
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