Merge branch 'MDL-27387_rating_scale_validation_master2' of git://github.com/andyjdav...
authorSam Hemelryk <sam@moodle.com>
Mon, 16 May 2011 04:14:11 +0000 (12:14 +0800)
committerSam Hemelryk <sam@moodle.com>
Mon, 16 May 2011 04:14:11 +0000 (12:14 +0800)
14 files changed:
admin/roles/lib.php
backup/util/xml/parser/processors/grouped_parser_processor.class.php
backup/util/xml/parser/processors/simplified_parser_processor.class.php
backup/util/xml/parser/simpletest/testparser.php
comment/lib.php
course/format/weeks/lib.php
lib/simpletest/testpagelib_moodlepage.php
lib/simpletestlib.php
lib/xhprof/xhprof_moodle.php
mod/choice/backup/moodle2/backup_choice_stepslib.php
mod/feedback/db/messages.php
mod/feedback/show_nonrespondents.php
mod/feedback/version.php
version.php

index 3e9624e..7fc5782 100644 (file)
@@ -1316,6 +1316,7 @@ abstract class role_allow_role_page {
         foreach ($rs as $allow) {
             $this->allowed[$allow->roleid][$allow->{$this->targetcolname}] = true;
         }
+        $rs->close();
     }
 
     /**
index ca5d3f4..46391e6 100644 (file)
@@ -70,16 +70,6 @@ abstract class grouped_parser_processor extends simplified_parser_processor {
         parent::add_path($path);
     }
 
-    /**
-     * Notify start of path if selected and not under grouped
-     */
-    public function before_path($path) {
-        if ($this->path_is_selected($path) && !$this->grouped_parent_exists($path)) {
-            parent::before_path($path);
-        }
-    }
-
-
     /**
      * Dispatch grouped chunks safely once their end tag happens.
      * Also notify end of path if selected and not under grouped
@@ -110,6 +100,7 @@ abstract class grouped_parser_processor extends simplified_parser_processor {
         $path = $data['path'];
         // If the chunk is a grouped one, simply put it into currentdata
         if ($this->path_is_grouped($path)) {
+            $this->notify_path_start($path);
             $this->currentdata[$path] = $data;
 
         // If the chunk is child of grouped one, add it to currentdata
@@ -119,6 +110,7 @@ abstract class grouped_parser_processor extends simplified_parser_processor {
 
         // No grouped nor child of grouped, dispatch it
         } else {
+            $this->notify_path_start($path);
             $this->dispatch_chunk($data);
         }
     }
index e4432af..0544b43 100644 (file)
@@ -149,15 +149,6 @@ abstract class simplified_parser_processor extends progressive_parser_processor
         return true;
     }
 
-    /**
-     * The parser fires this each time one path is going to be parsed
-     */
-    public function before_path($path) {
-        if ($this->path_is_selected($path)) {
-            $this->notify_path_start($path);
-        }
-    }
-
     /**
      * The parser fires this each time one path has been parsed
      */
@@ -170,6 +161,7 @@ abstract class simplified_parser_processor extends progressive_parser_processor
 // Protected API starts here
 
     protected function postprocess_chunk($data) {
+        $this->notify_path_start($data['path']);
         $this->dispatch_chunk($data);
     }
 
index eccc2c4..0298304 100644 (file)
@@ -330,6 +330,13 @@ class progressive_parser_test extends UnitTestCase {
         sort($snotifs);
         sort($enotifs);
         $this->assertEqual($snotifs, $enotifs);
+
+        // Now verify that the start/process/end order is correct
+        $allnotifs = $pr->get_all_notifications();
+        $this->assertEqual(count($allnotifs), count($snotifs) + count($enotifs) + count($chunks)); // The count
+        // Check integrity of the notifications
+        $errcount = $this->helper_check_notifications_order_integrity($allnotifs);
+        $this->assertEqual($errcount, 0); // No errors found, plz
     }
 
     /*
@@ -498,6 +505,67 @@ class progressive_parser_test extends UnitTestCase {
         sort($snotifs);
         sort($enotifs);
         $this->assertEqual($snotifs, $enotifs);
+
+        // Now verify that the start/process/end order is correct
+        $allnotifs = $pr->get_all_notifications();
+        $this->assertEqual(count($allnotifs), count($snotifs) + count($enotifs) + count($chunks)); // The count
+        // Check integrity of the notifications
+        $errcount = $this->helper_check_notifications_order_integrity($allnotifs);
+        $this->assertEqual($errcount, 0); // No errors found, plz
+    }
+
+    /**
+     * Helper function that given one array of ordered start/process/end notifications will
+     * check it of integrity like:
+     *    - process only happens if start is the previous notification
+     *    - end only happens if dispatch is the previous notification
+     *    - start only happen with level > than last one and if there is no already started like that
+     *
+     * @param array $notifications ordered array of notifications with format [start|process|end]:path
+     * @return int number of integrity problems found (errors)
+     */
+    function helper_check_notifications_order_integrity($notifications) {
+        $numerrors = 0;
+        $notifpile = array('pilebase' => 'start');
+        $lastpile = 'start:pilebase';
+        foreach ($notifications as $notif) {
+            $lastpilelevel = strlen(preg_replace('/[^\/]/', '', $lastpile));
+            $lastpiletype  = preg_replace('/:.*/', '', $lastpile);
+            $lastpilepath  = preg_replace('/.*:/', '', $lastpile);
+
+            $notiflevel = strlen(preg_replace('/[^\/]/', '', $notif));
+            $notiftype  = preg_replace('/:.*/', '', $notif);
+            $notifpath  = preg_replace('/.*:/', '', $notif);
+
+            switch ($notiftype) {
+                case 'process':
+                    if ($lastpilepath != $notifpath or $lastpiletype != 'start') {
+                        $numerrors++; // Only start for same path is allowed before process
+                    }
+                    $notifpile[$notifpath] = 'process'; // Update the status in the pile
+                    break;
+                case 'end':
+                    if ($lastpilepath != $notifpath or $lastpiletype != 'process') {
+                        $numerrors++; // Only process for same path is allowed before end
+                    }
+                    unset($notifpile[$notifpath]); // Delete from the pile
+                    break;
+                case 'start':
+                    if (array_key_exists($notifpath, $notifpile) or $notiflevel <= $lastpilelevel) {
+                        $numerrors++; // If same path exists or the level is < than the last one
+                    }
+                    $notifpile[$notifpath] = 'start'; // Add to the pile
+                    break;
+                default:
+                    $numerrors++; // Incorrect type of notification => error
+            }
+            // Update lastpile
+            end($notifpile);
+            $path = key($notifpile);
+            $type = $notifpile[$path];
+            $lastpile = $type. ':' . $path;
+        }
+        return $numerrors;
     }
 }
 
@@ -572,17 +640,21 @@ class mock_simplified_parser_processor extends simplified_parser_processor {
     private $chunksarr = array(); // To accumulate the found chunks
     private $startarr  = array(); // To accumulate all the notified path starts
     private $endarr    = array(); // To accumulate all the notified path ends
+    private $allnotif  = array(); // To accumulate all the notified and dispatched events in an ordered way
 
     public function dispatch_chunk($data) {
         $this->chunksarr[] = $data;
+        $this->allnotif[] = 'process:' . $data['path'];
     }
 
     public function notify_path_start($path) {
         $this->startarr[] = $path;
+        $this->allnotif[] = 'start:' . $path;
     }
 
     public function notify_path_end($path) {
         $this->endarr[] = $path;
+        $this->allnotif[] = 'end:' . $path;
     }
 
     public function get_chunks() {
@@ -596,6 +668,10 @@ class mock_simplified_parser_processor extends simplified_parser_processor {
     public function get_end_notifications() {
         return $this->endarr;
     }
+
+    public function get_all_notifications() {
+        return $this->allnotif;
+    }
 }
 
 /*
@@ -606,17 +682,21 @@ class mock_grouped_parser_processor extends grouped_parser_processor {
     private $chunksarr = array(); // To accumulate the found chunks
     private $startarr  = array(); // To accumulate all the notified path starts
     private $endarr    = array(); // To accumulate all the notified path ends
+    private $allnotif  = array(); // To accumulate all the notified and dispatched events in an ordered way
 
     public function dispatch_chunk($data) {
         $this->chunksarr[] = $data;
+        $this->allnotif[] = 'process:' . $data['path'];
     }
 
     public function notify_path_start($path) {
         $this->startarr[] = $path;
+        $this->allnotif[] = 'start:' . $path;
     }
 
     public function notify_path_end($path) {
         $this->endarr[] = $path;
+        $this->allnotif[] = 'end:' . $path;
     }
 
     public function get_chunks() {
@@ -630,4 +710,8 @@ class mock_grouped_parser_processor extends grouped_parser_processor {
     public function get_end_notifications() {
         return $this->endarr;
     }
+
+    public function get_all_notifications() {
+        return $this->allnotif;
+    }
 }
index 2bf5979..184e320 100644 (file)
@@ -127,16 +127,14 @@ class comment {
      */
     protected $totalcommentcount = null;
     /**
-     * By default a user must have the generic comment capabilities plus any capabilities the
-     * component being commented on requires.
-     * When set to true only the component capabilities are checked, the system capabilities are
-     * ignored.
-     * This can be toggled by the component defining a callback in its lib.php e.g.
-     *    function forum_comment_allow_anonymous_access(comment $comment) {}
-     * Note: On the front page this defaults to true.
+     * 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 $ignoresystempermissions = false;
+    protected $allowanonymousaccess = false;
 
     /**#@+
      * static variable will be used by non-js comments UI
index 38aa940..e37454f 100644 (file)
@@ -89,7 +89,7 @@ function callback_weeks_get_section_name($course, $section) {
         foreach ($sections as $sec) {
             if ($sec->id == $section->id) {
                 break;
-            } else if ($sec->visible && $sec->section != 0) {
+            } else if ($sec->section != 0) {
                 $weekdate += 604800;
             }
         }
index 3e9f170..154c2a6 100644 (file)
@@ -525,7 +525,7 @@ class moodle_page_cm_test extends UnitTestCaseUsingDatabase {
         parent::setUp();
         $this->originalcourse = $COURSE;
         $this->testpage = new moodle_page();
-        $this->create_test_tables(array('course', 'context'), 'lib');
+        $this->create_test_tables(array('course', 'context', 'modules', 'course_modules', 'course_modules_availability', 'grade_items', 'course_sections'), 'lib');
         $this->create_test_table('forum', 'mod/forum');
         $this->switch_to_test_db();
 
@@ -551,6 +551,7 @@ class moodle_page_cm_test extends UnitTestCaseUsingDatabase {
         $course->fullname = 'Anonymous test course';
         $course->shortname = 'ANON';
         $course->summary = '';
+        $course->modinfo = null;
         $course->id = $this->testdb->insert_record('course', $course);
 
         $forum = new stdClass;
@@ -559,12 +560,23 @@ class moodle_page_cm_test extends UnitTestCaseUsingDatabase {
         $forum->intro = '';
         $forum->id = $this->testdb->insert_record('forum', $forum);
 
+        $module = new stdClass;
+        $module->name = 'forum';
+        $module->id = $this->testdb->insert_record('modules', $module);
+
         $cm = new stdClass;
-        $cm->id = 13;
         $cm->course = $course->id;
         $cm->instance = $forum->id;
         $cm->modname = 'forum';
+        $cm->module = $module->id;
         $cm->name = $forum->name;
+        $cm->id = $this->testdb->insert_record('course_modules', $cm);
+
+        $section = new stdClass;
+        $section->course = $course->id;
+        $section->section = 0;
+        $section->sequence = $cm->id;
+        $section->id = $this->testdb->insert_record('course_sections', $section);
 
         $context = new stdClass;
         $context->contextlevel = CONTEXT_MODULE;
@@ -590,26 +602,6 @@ class moodle_page_cm_test extends UnitTestCaseUsingDatabase {
         $this->assert(new CheckSpecifiedFieldsExpectation($cm), $this->testpage->cm);
     }
 
-    public function test_cannot_set_cm_without_name() {
-        // Setup fixture
-        list($cm) = $this->create_a_forum_with_context();
-        // Set expectation
-        $this->expectException();
-        // Exercise SUT
-        unset($cm->name);
-        $this->testpage->set_cm($cm);
-    }
-
-    public function test_cannot_set_cm_without_modname() {
-        // Setup fixture
-        list($cm) = $this->create_a_forum_with_context();
-        // Set expectation
-        $this->expectException();
-        // Exercise SUT
-        unset($cm->modname);
-        $this->testpage->set_cm($cm);
-    }
-
     public function test_cannot_set_activity_record_before_cm() {
         // Setup fixture
         list($cm, $course, $forum) = $this->create_a_forum_with_context();
@@ -672,18 +664,21 @@ class moodle_page_cm_test extends UnitTestCaseUsingDatabase {
         $this->testpage->set_activity_record($forum);
     }
 
-    public function test_settin_cm_sets_course() {
+    public function test_setting_cm_sets_course() {
         // Setup fixture
         list($cm, $course) = $this->create_a_forum_with_context();
         // Exercise SUT
         $this->testpage->set_cm($cm);
         // Validate
+        unset($course->modinfo); // This changed, but we don't care
         $this->assert(new CheckSpecifiedFieldsExpectation($course), $this->testpage->course);
     }
 
     public function test_set_cm_with_course_and_activity_no_db() {
         // Setup fixture
         list($cm, $course, $forum) = $this->create_a_forum_with_context();
+        // This only works without db if we already have modinfo cache
+        $modinfo = get_fast_modinfo($course);
         $this->drop_test_table('forum');
         $this->drop_test_table('course');
         // Exercise SUT
index ad3d5c5..d056060 100644 (file)
@@ -715,6 +715,8 @@ class UnitTestCaseUsingDatabase extends UnitTestCase {
 
         if ($cleanmore) {
             accesslib_clear_all_caches_for_unit_testing();
+            $course = 'reset';
+            get_fast_modinfo($course);
         }
     }
 
index 853e5f5..28c41f3 100644 (file)
@@ -152,7 +152,7 @@ function profiling_start() {
  * Stop profiling, gathering results and storing them
  */
 function profiling_stop() {
-    global $CFG, $SCRIPT;
+    global $CFG, $DB, $SCRIPT;
 
     // If profiling isn't available, nothing to stop
     if (!extension_loaded('xhprof') || !function_exists('xhprof_enable')) {
@@ -176,6 +176,14 @@ function profiling_stop() {
     profiling_is_running(false);
     $data = xhprof_disable();
 
+    // We only save the run after ensuring the DB table exists
+    // (this prevents problems with profiling runs enabled in
+    // config.php before Moodle is installed. Rare but...
+    $tables = $DB->get_tables();
+    if (!in_array('profiling', $tables)) {
+        return false;
+    }
+
     $run = new moodle_xhprofrun();
     $run->prepare_run($script);
     $runid = $run->save_run($data, null);
index d211a2d..bd9b0c2 100644 (file)
@@ -39,7 +39,7 @@ class backup_choice_activity_structure_step extends backup_activity_structure_st
         // Define each element separated
         $choice = new backup_nested_element('choice', array('id'), array(
             'name', 'intro', 'introformat', 'publish',
-            'showresults', 'display', 'allowupdate', 'allowunanswered',
+            'showresults', 'display', 'allowupdate', 'showunanswered',
             'limitanswers', 'timeopen', 'timeclose', 'timemodified',
             'completionsubmit'));
 
index 0cdead1..e99c919 100644 (file)
@@ -27,6 +27,9 @@ $messageproviders = array (
 
 /// Submitting a feedback
     'submission' => array (
+    ),
+/// Message to nonrespondents
+    'message' => array (
     )
 
 );
index 4bbc51b..92a3d82 100644 (file)
@@ -75,8 +75,8 @@
             foreach ($messageuser as $userid) {
                 $senduser = $DB->get_record('user', array('id'=>$userid));
                 $eventdata = new stdClass();
-                $eventdata->name             = 'feedback';
-                $eventdata->component        = 'mod';
+                $eventdata->name             = 'message';
+                $eventdata->component        = 'mod_feedback';
                 $eventdata->userfrom         = $USER;
                 $eventdata->userto           = $senduser;
                 $eventdata->subject          = $subject;
index 460a9d5..78178bd 100644 (file)
@@ -9,7 +9,7 @@
 */
 
 
-    $module->version = 2010112302; // The current module version (Date: YYYYMMDDXX)
+    $module->version = 2011051600; // The current module version (Date: YYYYMMDDXX)
     $module->requires = 2010080300;  // Requires this Moodle version
     $feedback_version_intern = 1; //this version is used for restore older backups
     $module->cron = 0; // Period for cron to check this module (secs)
index 55545ff..41ca75b 100644 (file)
 defined('MOODLE_INTERNAL') || die();
 
 
-$version  = 2011050500.00;              // YYYYMMDD      = weekly release date of this DEV branch
+$version  = 2011051100.00;              // YYYYMMDD      = weekly release date of this DEV branch
                                         //         RR    = release increments - 00 in DEV branches
                                         //           .XX = incremental changes
 
-$release  = '2.1dev (Build: 20110505)'; // Human-friendly version name
+$release  = '2.1dev (Build: 20110511)'; // Human-friendly version name
 
 $maturity = MATURITY_ALPHA;             // this version's maturity level