Merge branch 'MDL-31983-master' of git://github.com/FMCorz/moodle
authorDan Poltawski <dan@moodle.com>
Mon, 18 Feb 2013 07:54:22 +0000 (15:54 +0800)
committerDan Poltawski <dan@moodle.com>
Mon, 18 Feb 2013 07:54:22 +0000 (15:54 +0800)
35 files changed:
blocks/html/backup/moodle1/lib.php
blocks/rss_client/backup/moodle1/lib.php
blog/edit_form.php
cache/classes/config.php
cache/classes/definition.php
cache/classes/factory.php
cache/classes/helper.php
cache/locallib.php
cache/tests/cache_test.php
cache/tests/fixtures/lib.php
comment/comment_ajax.php
course/tests/courselib_test.php
enrol/imsenterprise/locallib.php
enrol/locallib.php
enrol/manual/ajax.php
enrol/manual/yui/quickenrolment/quickenrolment.js
grade/report/grader/module.js
lib/db/upgrade.php
lib/filelib.php
lib/moodlelib.php
lib/statslib.php
lib/upgradelib.php
mod/assign/externallib.php
mod/assign/lang/en/assign.php
mod/assign/locallib.php
mod/assign/mod_form.php
mod/assign/submission/file/locallib.php
mod/assign/tests/lib_test.php
mod/assign/tests/locallib_test.php
mod/data/renderer.php
mod/scorm/report/graphs/graph.php
report/courseoverview/index.php
report/courseoverview/settings.php
tag/coursetagslib.php
version.php

index d4a491f..6373a01 100644 (file)
@@ -1,46 +1,46 @@
-<?php\r
-\r
-/**\r
- * Provides support for the conversion of moodle1 backup to the moodle2 format\r
- *\r
- * @package    block_html\r
- * @copyright  2012 Paul Nicholls\r
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\r
- */\r
-\r
-defined('MOODLE_INTERNAL') || die();\r
-\r
-/**\r
- * Block conversion handler for html\r
- */\r
-class moodle1_block_html_handler extends moodle1_block_handler {\r
-    private $fileman = null;\r
-    protected function convert_configdata(array $olddata) {\r
-        $instanceid = $olddata['id'];\r
-        $contextid  = $this->converter->get_contextid(CONTEXT_BLOCK, $olddata['id']);\r
-        $configdata = unserialize(base64_decode($olddata['configdata']));\r
-\r
-        // get a fresh new file manager for this instance\r
-        $this->fileman = $this->converter->get_file_manager($contextid, 'block_html');\r
-\r
-        // convert course files embedded in the block content\r
-        $this->fileman->filearea = 'content';\r
-        $this->fileman->itemid   = 0;\r
-        $configdata->text = moodle1_converter::migrate_referenced_files($configdata->text, $this->fileman);\r
-        $configdata->format = FORMAT_HTML;\r
-\r
-        return base64_encode(serialize($configdata));\r
-    }\r
-\r
-    protected function write_inforef_xml($newdata, $data) {\r
-        $this->open_xml_writer("course/blocks/{$data['name']}_{$data['id']}/inforef.xml");\r
-        $this->xmlwriter->begin_tag('inforef');\r
-        $this->xmlwriter->begin_tag('fileref');\r
-        foreach ($this->fileman->get_fileids() as $fileid) {\r
-            $this->write_xml('file', array('id' => $fileid));\r
-        }\r
-        $this->xmlwriter->end_tag('fileref');\r
-        $this->xmlwriter->end_tag('inforef');\r
-        $this->close_xml_writer();\r
-    }\r
-}
\ No newline at end of file
+<?php
+
+/**
+ * Provides support for the conversion of moodle1 backup to the moodle2 format
+ *
+ * @package    block_html
+ * @copyright  2012 Paul Nicholls
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * Block conversion handler for html
+ */
+class moodle1_block_html_handler extends moodle1_block_handler {
+    private $fileman = null;
+    protected function convert_configdata(array $olddata) {
+        $instanceid = $olddata['id'];
+        $contextid  = $this->converter->get_contextid(CONTEXT_BLOCK, $olddata['id']);
+        $configdata = unserialize(base64_decode($olddata['configdata']));
+
+        // get a fresh new file manager for this instance
+        $this->fileman = $this->converter->get_file_manager($contextid, 'block_html');
+
+        // convert course files embedded in the block content
+        $this->fileman->filearea = 'content';
+        $this->fileman->itemid   = 0;
+        $configdata->text = moodle1_converter::migrate_referenced_files($configdata->text, $this->fileman);
+        $configdata->format = FORMAT_HTML;
+
+        return base64_encode(serialize($configdata));
+    }
+
+    protected function write_inforef_xml($newdata, $data) {
+        $this->open_xml_writer("course/blocks/{$data['name']}_{$data['id']}/inforef.xml");
+        $this->xmlwriter->begin_tag('inforef');
+        $this->xmlwriter->begin_tag('fileref');
+        foreach ($this->fileman->get_fileids() as $fileid) {
+            $this->write_xml('file', array('id' => $fileid));
+        }
+        $this->xmlwriter->end_tag('fileref');
+        $this->xmlwriter->end_tag('inforef');
+        $this->close_xml_writer();
+    }
+}
index 95da634..d698365 100644 (file)
@@ -1,34 +1,34 @@
-<?php\r
-\r
-/**\r
- * Provides support for the conversion of moodle1 backup to the moodle2 format\r
- *\r
- * @package    block_rss_client\r
- * @copyright  2012 Paul Nicholls\r
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\r
- */\r
-\r
-defined('MOODLE_INTERNAL') || die();\r
-\r
-/**\r
- * Block conversion handler for rss_client\r
- */\r
-class moodle1_block_rss_client_handler extends moodle1_block_handler {\r
-    public function process_block(array $data) {\r
-        parent::process_block($data);\r
-        $instanceid = $data['id'];\r
-        $contextid = $this->converter->get_contextid(CONTEXT_BLOCK, $data['id']);\r
-\r
-        // Moodle 1.9 backups do not include sufficient data to restore feeds, so we need an empty shell rss_client.xml\r
-        // for the restore process to find\r
-        $this->open_xml_writer("course/blocks/{$data['name']}_{$instanceid}/rss_client.xml");\r
-        $this->xmlwriter->begin_tag('block', array('id' => $instanceid, 'contextid' => $contextid, 'blockname' => 'rss_client'));\r
-        $this->xmlwriter->begin_tag('rss_client', array('id' => $instanceid));\r
-        $this->xmlwriter->full_tag('feeds', '');\r
-        $this->xmlwriter->end_tag('rss_client');\r
-        $this->xmlwriter->end_tag('block');\r
-        $this->close_xml_writer();\r
-\r
-        return $data;\r
-    }\r
-}
\ No newline at end of file
+<?php
+
+/**
+ * Provides support for the conversion of moodle1 backup to the moodle2 format
+ *
+ * @package    block_rss_client
+ * @copyright  2012 Paul Nicholls
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * Block conversion handler for rss_client
+ */
+class moodle1_block_rss_client_handler extends moodle1_block_handler {
+    public function process_block(array $data) {
+        parent::process_block($data);
+        $instanceid = $data['id'];
+        $contextid = $this->converter->get_contextid(CONTEXT_BLOCK, $data['id']);
+
+        // Moodle 1.9 backups do not include sufficient data to restore feeds, so we need an empty shell rss_client.xml
+        // for the restore process to find
+        $this->open_xml_writer("course/blocks/{$data['name']}_{$instanceid}/rss_client.xml");
+        $this->xmlwriter->begin_tag('block', array('id' => $instanceid, 'contextid' => $contextid, 'blockname' => 'rss_client'));
+        $this->xmlwriter->begin_tag('rss_client', array('id' => $instanceid));
+        $this->xmlwriter->full_tag('feeds', '');
+        $this->xmlwriter->end_tag('rss_client');
+        $this->xmlwriter->end_tag('block');
+        $this->close_xml_writer();
+
+        return $data;
+    }
+}
index 919fed1..42ab6e3 100644 (file)
@@ -87,8 +87,8 @@ class blog_edit_form extends moodleform {
                 }
 
                 if (has_capability('moodle/blog:associatecourse', $context)) {
-                    $mform->addElement('header', 'assochdr', get_string('associations', 'blog'));\r
-                    $mform->addElement('advcheckbox', 'courseassoc', get_string('associatewithcourse', 'blog', $a), null, null, array(0, $contextid));\r
+                    $mform->addElement('header', 'assochdr', get_string('associations', 'blog'));
+                    $mform->addElement('advcheckbox', 'courseassoc', get_string('associatewithcourse', 'blog', $a), null, null, array(0, $contextid));
                     $mform->setDefault('courseassoc', $contextid);
                 }
 
index fee8aea..232aa46 100644 (file)
@@ -71,6 +71,12 @@ class cache_config {
      */
     protected $configlocks = array();
 
+    /**
+     * The site identifier used when the cache config was last saved.
+     * @var string
+     */
+    protected $siteidentifier = null;
+
     /**
      * Please use cache_config::instance to get an instance of the cache config that is ready to be used.
      */
@@ -139,6 +145,12 @@ class cache_config {
         $this->configdefinitionmappings = array();
         $this->configlockmappings = array();
 
+        $siteidentifier = 'unknown';
+        if (array_key_exists('siteidentifier', $configuration)) {
+            $siteidentifier = $configuration['siteidentifier'];
+        }
+        $this->siteidentifier = $siteidentifier;
+
         // Filter the lock instances.
         $defaultlock = null;
         foreach ($configuration['locks'] as $conf) {
@@ -271,6 +283,14 @@ class cache_config {
         return true;
     }
 
+    /**
+     * Returns the site identifier used by the cache API.
+     * @return string
+     */
+    public function get_site_identifier() {
+        return $this->siteidentifier;
+    }
+
     /**
      * Includes the configuration file and makes sure it contains the expected bits.
      *
index e278bbb..8c5a16a 100644 (file)
@@ -723,7 +723,8 @@ class cache_definition {
      */
     public function generate_single_key_prefix() {
         if ($this->keyprefixsingle === null) {
-            $this->keyprefixsingle = $this->mode.'/'.$this->mode;
+            $this->keyprefixsingle = $this->mode.'/'.$this->component.'/'.$this->area;
+            $this->keyprefixsingle .= '/'.$this->get_cache_identifier();
             $identifiers = $this->get_identifiers();
             if ($identifiers) {
                 foreach ($identifiers as $key => $value) {
@@ -746,6 +747,7 @@ class cache_definition {
                 'mode' => $this->mode,
                 'component' => $this->component,
                 'area' => $this->area,
+                'siteidentifier' => $this->get_cache_identifier()
             );
             if (!empty($this->identifiers)) {
                 $identifiers = array();
@@ -785,4 +787,13 @@ class cache_definition {
     public function get_invalidation_events() {
         return $this->invalidationevents;
     }
+
+    /**
+     * Returns a cache identification string.
+     *
+     * @return string A string to be used as part of keys.
+     */
+    protected function get_cache_identifier() {
+        return cache_helper::get_site_identifier();
+    }
 }
\ No newline at end of file
index f3d520c..24c7c1e 100644 (file)
@@ -203,6 +203,7 @@ class cache_factory {
         }
         // Get the class. Note this is a late static binding so we need to use get_called_class.
         $definition = cache_definition::load_adhoc($mode, $component, $area, $options);
+        $config = $this->create_config_instance();
         $definition->set_identifiers($identifiers);
         $cache = $this->create_cache($definition, $identifiers);
         if ($definition->should_be_persistent()) {
index 4439a56..a8f3a26 100644 (file)
@@ -54,6 +54,13 @@ class cache_helper {
      */
     protected static $instance;
 
+    /**
+     * The site identifier used by the cache.
+     * Set the first time get_site_identifier is called.
+     * @var string
+     */
+    protected static $siteidentifier = null;
+
     /**
      * Returns true if the cache API can be initialised before Moodle has finished initialising itself.
      *
@@ -489,11 +496,52 @@ class cache_helper {
      */
     public static function update_definitions($coreonly = false) {
         global $CFG;
-        // Include locallib
+        // Include locallib.
         require_once($CFG->dirroot.'/cache/locallib.php');
         // First update definitions
         cache_config_writer::update_definitions($coreonly);
         // Second reset anything we have already initialised to ensure we're all up to date.
         cache_factory::reset();
     }
-}
\ No newline at end of file
+
+    /**
+     * Update the site identifier stored by the cache API.
+     *
+     * @param string $siteidentifier
+     */
+    public static function update_site_identifier($siteidentifier) {
+        global $CFG;
+        // Include locallib.
+        require_once($CFG->dirroot.'/cache/locallib.php');
+        $factory = cache_factory::instance();
+        $factory->updating_started();
+        $config = $factory->create_config_instance(true);
+        $config->update_site_identifier($siteidentifier);
+        $factory->updating_finished();
+        cache_factory::reset();
+    }
+
+    /**
+     * Returns the site identifier.
+     *
+     * @return string
+     */
+    public static function get_site_identifier() {
+        if (is_null(self::$siteidentifier)) {
+            $factory = cache_factory::instance();
+            $config = $factory->create_config_instance();
+            self::$siteidentifier = $config->get_site_identifier();
+        }
+        return self::$siteidentifier;
+    }
+
+    /**
+     * Returns the site version.
+     *
+     * @return string
+     */
+    public static function get_site_version() {
+        global $CFG;
+        return (string)$CFG->version;
+    }
+}
index ce926a5..4d6d745 100644 (file)
@@ -119,6 +119,7 @@ class cache_config_writer extends cache_config {
      */
     protected function generate_configuration_array() {
         $configuration = array();
+        $configuration['siteidentifier'] = $this->siteidentifier;
         $configuration['stores'] = $this->configstores;
         $configuration['modemappings'] = $this->configmodemappings;
         $configuration['definitions'] = $this->configdefinitions;
@@ -524,6 +525,15 @@ class cache_config_writer extends cache_config {
         $this->config_save();
     }
 
+    /**
+     * Update the site identifier stored by the cache API.
+     *
+     * @param string $siteidentifier
+     */
+    public function update_site_identifier($siteidentifier) {
+        $this->siteidentifier = md5((string)$siteidentifier);
+        $this->config_save();
+    }
 }
 
 /**
@@ -1002,4 +1012,4 @@ abstract class cache_administration_helper extends cache_helper {
         }
         return $locks;
     }
-}
\ No newline at end of file
+}
index 98d9c5b..545986a 100644 (file)
@@ -553,6 +553,8 @@ class cache_phpunit_tests extends advanced_testcase {
             'mode' => cache_store::MODE_APPLICATION,
             'component' => 'phpunit',
             'area' => 'eventinvalidationtest',
+            'simplekeys' => true,
+            'simpledata' => true,
             'invalidationevents' => array(
                 'crazyevent'
             )
@@ -567,13 +569,16 @@ class cache_phpunit_tests extends advanced_testcase {
 
         // OK data added, data invalidated, and invalidation time has been set.
         // Now we need to manually add back the data and adjust the invalidation time.
-        $timefile = $CFG->dataroot.'/cache/cachestore_file/default_application/phpunit_eventinvalidationtest/a65/a65b1dc524cf6e03c1795197c84d5231eb229b86.cache';
+        $hash = md5(cache_store::MODE_APPLICATION.'/phpunit/eventinvalidationtest/'.$CFG->wwwroot.'phpunit');
+        $timefile = $CFG->dataroot."/cache/cachestore_file/default_application/phpunit_eventinvalidationtest/las/lastinvalidation-$hash.cache";
+        // Make sure the file is correct.
+        $this->assertTrue(file_exists($timefile));
         $timecont = serialize(cache::now() - 60); // Back 60sec in the past to force it to re-invalidate.
         make_writable_directory(dirname($timefile));
         file_put_contents($timefile, $timecont);
         $this->assertTrue(file_exists($timefile));
 
-        $datafile = $CFG->dataroot.'/cache/cachestore_file/default_application/phpunit_eventinvalidationtest/626/626e9c7a45febd98f064c2b383de8d9d4ebbde7b.cache';
+        $datafile = $CFG->dataroot."/cache/cachestore_file/default_application/phpunit_eventinvalidationtest/tes/testkey1-$hash.cache";
         $datacont = serialize("test data 1");
         make_writable_directory(dirname($datafile));
         file_put_contents($datafile, $datacont);
@@ -586,6 +591,8 @@ class cache_phpunit_tests extends advanced_testcase {
             'mode' => cache_store::MODE_APPLICATION,
             'component' => 'phpunit',
             'area' => 'eventinvalidationtest',
+            'simplekeys' => true,
+            'simpledata' => true,
         ));
         $cache = cache::make('phpunit', 'eventinvalidationtest');
         $this->assertEquals('test data 1', $cache->get('testkey1'));
@@ -597,6 +604,8 @@ class cache_phpunit_tests extends advanced_testcase {
             'mode' => cache_store::MODE_APPLICATION,
             'component' => 'phpunit',
             'area' => 'eventinvalidationtest',
+            'simplekeys' => true,
+            'simpledata' => true,
             'invalidationevents' => array(
                 'crazyevent'
             )
index d5e5297..471521b 100644 (file)
@@ -102,6 +102,16 @@ class cache_config_phpunittest extends cache_config_writer {
             'sort' => (int)$sort
         );
     }
+
+    /**
+     * Overrides the default site identifier used by the Cache API so that we can be sure of what it is.
+     *
+     * @return string
+     */
+    public function get_site_identifier() {
+        global $CFG;
+        return $CFG->wwwroot.'phpunit';
+    }
 }
 
 /**
index 91b99ca..131a803 100644 (file)
@@ -35,6 +35,10 @@ if (empty($CFG->usecomments)) {
 
 list($context, $course, $cm) = get_context_info_array($contextid);
 
+if ( $contextid == SYSCONTEXTID ) {
+    $course = $SITE;
+}
+
 $PAGE->set_url('/comment/comment_ajax.php');
 
 // Allow anonymous user to view comments providing forcelogin now enabled
index a59351b..ef8ef1b 100644 (file)
@@ -297,22 +297,71 @@ class courselib_testcase extends advanced_testcase {
     }
 
     public function test_move_module_in_course() {
+        global $DB;
+
         $this->resetAfterTest(true);
         // Setup fixture
-        $course = $this->getDataGenerator()->create_course(array('numsections'=>5));
+        $course = $this->getDataGenerator()->create_course(array('numsections'=>5), array('createsections' => true));
         $forum = $this->getDataGenerator()->create_module('forum', array('course'=>$course->id));
 
         $cms = get_fast_modinfo($course)->get_cms();
         $cm = reset($cms);
 
-        course_create_sections_if_missing($course, 3);
-        $section3 = get_fast_modinfo($course)->get_section_info(3);
+        $newsection = get_fast_modinfo($course)->get_section_info(3);
+        $oldsectionid = $cm->section;
+
+        // Perform the move
+        moveto_module($cm, $newsection);
 
-        moveto_module($cm, $section3);
+        // reset of get_fast_modinfo is usually called the code calling moveto_module so call it here
+        get_fast_modinfo(0, 0, true);
+        $cms = get_fast_modinfo($course)->get_cms();
+        $cm = reset($cms);
 
+        // Check that the cached modinfo contains the correct section info
         $modinfo = get_fast_modinfo($course);
         $this->assertTrue(empty($modinfo->sections[0]));
         $this->assertFalse(empty($modinfo->sections[3]));
+
+        // Check that the old section's sequence no longer contains this ID
+        $oldsection = $DB->get_record('course_sections', array('id' => $oldsectionid));
+        $oldsequences = explode(',', $newsection->sequence);
+        $this->assertFalse(in_array($cm->id, $oldsequences));
+
+        // Check that the new section's sequence now contains this ID
+        $newsection = $DB->get_record('course_sections', array('id' => $newsection->id));
+        $newsequences = explode(',', $newsection->sequence);
+        $this->assertTrue(in_array($cm->id, $newsequences));
+
+        // Check that the section number has been changed in the cm
+        $this->assertEquals($newsection->id, $cm->section);
+
+
+        // Perform a second move as some issues were only seen on the second move
+        $newsection = get_fast_modinfo($course)->get_section_info(2);
+        $oldsectionid = $cm->section;
+        $result = moveto_module($cm, $newsection);
+        $this->assertTrue($result);
+
+        // reset of get_fast_modinfo is usually called the code calling moveto_module so call it here
+        get_fast_modinfo(0, 0, true);
+        $cms = get_fast_modinfo($course)->get_cms();
+        $cm = reset($cms);
+
+        // Check that the cached modinfo contains the correct section info
+        $modinfo = get_fast_modinfo($course);
+        $this->assertTrue(empty($modinfo->sections[0]));
+        $this->assertFalse(empty($modinfo->sections[2]));
+
+        // Check that the old section's sequence no longer contains this ID
+        $oldsection = $DB->get_record('course_sections', array('id' => $oldsectionid));
+        $oldsequences = explode(',', $newsection->sequence);
+        $this->assertFalse(in_array($cm->id, $oldsequences));
+
+        // Check that the new section's sequence now contains this ID
+        $newsection = $DB->get_record('course_sections', array('id' => $newsection->id));
+        $newsequences = explode(',', $newsection->sequence);
+        $this->assertTrue(in_array($cm->id, $newsequences));
     }
 
     public function test_module_visibility() {
index 13c6114..921bb30 100644 (file)
@@ -114,9 +114,9 @@ class imsenterprise_courses {
      * @return array Array of assignable values
      */
     function get_imsnames($courseattr) {
-\r
-        $values = $this->imsnames;\r
-        if ($courseattr == 'summary') {\r
+
+        $values = $this->imsnames;
+        if ($courseattr == 'summary') {
             $values = array_merge(array('ignore' => get_string('emptyattribute', 'enrol_imsenterprise')), $values);
         }
         return $values;
index 5e947b6..3f6a506 100644 (file)
@@ -318,11 +318,12 @@ class course_enrolment_manager {
      * @param array $params query parameters.
      * @param int $page which page number of the results to show.
      * @param int $perpage number of users per page.
+     * @param int $addedenrollment number of users added to enrollment.
      * @return array with two elememts:
      *      int total number of users matching the search.
      *      array of user objects returned by the query.
      */
-    protected function execute_search_queries($search, $fields, $countfields, $sql, array $params, $page, $perpage) {
+    protected function execute_search_queries($search, $fields, $countfields, $sql, array $params, $page, $perpage, $addedenrollment=0) {
         global $DB, $CFG;
 
         list($sort, $sortparams) = users_order_by_sql('u', $search, $this->get_context());
@@ -330,7 +331,7 @@ class course_enrolment_manager {
 
         $totalusers = $DB->count_records_sql($countfields . $sql, $params);
         $availableusers = $DB->get_records_sql($fields . $sql . $order,
-                array_merge($params, $sortparams), $page*$perpage, $perpage);
+                array_merge($params, $sortparams), ($page*$perpage) - $addedenrollment, $perpage);
 
         return array('totalusers' => $totalusers, 'users' => $availableusers);
     }
@@ -344,9 +345,10 @@ class course_enrolment_manager {
      * @param bool $searchanywhere
      * @param int $page Defaults to 0
      * @param int $perpage Defaults to 25
+     * @param int $addedenrollment Defaults to 0
      * @return array Array(totalusers => int, users => array)
      */
-    public function get_potential_users($enrolid, $search='', $searchanywhere=false, $page=0, $perpage=25) {
+    public function get_potential_users($enrolid, $search='', $searchanywhere=false, $page=0, $perpage=25, $addedenrollment=0) {
         global $DB;
 
         list($ufields, $params, $wherecondition) = $this->get_basic_search_conditions($search, $searchanywhere);
@@ -359,7 +361,7 @@ class course_enrolment_manager {
                       AND ue.id IS NULL";
         $params['enrolid'] = $enrolid;
 
-        return $this->execute_search_queries($search, $fields, $countfields, $sql, $params, $page, $perpage);
+        return $this->execute_search_queries($search, $fields, $countfields, $sql, $params, $page, $perpage, $addedenrollment);
     }
 
     /**
index 093ee05..ea4acd8 100644 (file)
@@ -67,7 +67,9 @@ switch ($action) {
         $enrolid = required_param('enrolid', PARAM_INT);
         $search = optional_param('search', '', PARAM_RAW);
         $page = optional_param('page', 0, PARAM_INT);
-        $outcome->response = $manager->get_potential_users($enrolid, $search, $searchanywhere, $page);
+        $addedenrollment = optional_param('enrolcount', 0, PARAM_INT);
+        $perpage = optional_param('perpage', 25, PARAM_INT);  //  This value is hard-coded to 25 in quickenrolment.js
+        $outcome->response = $manager->get_potential_users($enrolid, $search, $searchanywhere, $page, $perpage, $addedenrollment);
         $extrafields = get_extra_user_fields($context);
         foreach ($outcome->response['users'] as &$user) {
             $user->picture = $OUTPUT->user_picture($user);
index aad6e62..8362185 100644 (file)
@@ -23,7 +23,9 @@ YUI.add('moodle-enrol_manual-quickenrolment', function(Y) {
         DEFAULTDURATION : 'defaultDuration',
         ASSIGNABLEROLES : 'assignableRoles',
         DISABLEGRADEHISTORY : 'disableGradeHistory',
-        RECOVERGRADESDEFAULT : 'recoverGradesDefault'
+        RECOVERGRADESDEFAULT : 'recoverGradesDefault',
+        ENROLCOUNT : 'enrolCount',
+        PERPAGE : 'perPage'
     };
     /** CSS classes for nodes in structure **/
     var CSS = {
@@ -309,6 +311,9 @@ YUI.add('moodle-enrol_manual-quickenrolment', function(Y) {
             params['action'] = 'searchusers';
             params['search'] = this.get(UEP.SEARCH).get('value');
             params['page'] = this.get(UEP.PAGE);
+            params['enrolcount'] = this.get(UEP.ENROLCOUNT);
+            params['perpage'] = this.get(UEP.PERPAGE);
+
             if (this.get(UEP.MULTIPLE)) {
                 alert('oh no there are multiple');
             } else {
@@ -376,7 +381,7 @@ YUI.add('moodle-enrol_manual-quickenrolment', function(Y) {
                 var content = create('<div class="'+CSS.SEARCHRESULTS+'"></div>')
                     .append(create('<div class="'+CSS.TOTALUSERS+'">'+usersstr+'</div>'))
                     .append(users);
-                if (result.response.totalusers > (this.get(UEP.PAGE)+1)*25) {
+                if (result.response.totalusers > (this.get(UEP.PAGE)+1)*this.get(UEP.PERPAGE)) {
                     var fetchmore = create('<div class="'+CSS.MORERESULTS+'"><a href="#">'+M.str.enrol.ajaxnext25+'</a></div>');
                     fetchmore.on('click', this.search, this, true);
                     content.append(fetchmore)
@@ -384,7 +389,7 @@ YUI.add('moodle-enrol_manual-quickenrolment', function(Y) {
                 this.setContent(content);
                 Y.delegate("click", this.enrolUser, users, '.'+CSS.USER+' .'+CSS.ENROL, this, args);
             } else {
-                if (result.response.totalusers <= (this.get(UEP.PAGE)+1)*25) {
+                if (result.response.totalusers <= (this.get(UEP.PAGE)+1)*this.get(UEP.PERPAGE)) {
                     this.get(UEP.BASE).one('.'+CSS.MORERESULTS).remove();
                 }
             }
@@ -420,6 +425,8 @@ YUI.add('moodle-enrol_manual-quickenrolment', function(Y) {
                                 args.userNode.addClass(CSS.ENROLLED);
                                 args.userNode.one('.'+CSS.ENROL).remove();
                                 this.set(UEP.REQUIREREFRESH, true);
+                                var countenrol = this.get(UEP.ENROLCOUNT)+1;
+                                this.set(UEP.ENROLCOUNT, countenrol);
                             }
                         } catch (e) {
                             new M.core.exception(e);
@@ -532,6 +539,14 @@ YUI.add('moodle-enrol_manual-quickenrolment', function(Y) {
             },
             recoverGradesDefault : {
                 value : ''
+            },
+            enrolCount : {
+                value : 0,
+                validator : Y.Lang.isNumber
+            },
+            perPage : {
+                value: 25,
+                Validator: Y.Lang.isNumber
             }
         }
     });
index 0ee92ba..54af548 100644 (file)
@@ -323,9 +323,9 @@ M.gradereport_grader.classes.ajax = function(report, cfg) {
                 this.existingfields[userid][itemid] = new M.gradereport_grader.classes.existingfield(this, userid, itemid);
             }
         }
-        // Hide the Update button
+        // Disable the Update button as we're saving using ajax.
         submitbutton = this.report.Y.one('#gradersubmit');
-        submitbutton.setStyle('visibility', 'hidden');
+        submitbutton.set('disabled', true);
     }
 };
 /**
index b563121..e8a7278 100644 (file)
@@ -1577,5 +1577,79 @@ function xmldb_main_upgrade($oldversion) {
         upgrade_main_savepoint(true, 2013021100.01);
     }
 
+    if ($oldversion < 2013021800.00) {
+        // Add the site identifier to the cache config's file.
+        $siteidentifier = $DB->get_field('config', 'value', array('name' => 'siteidentifier'));
+        cache_helper::update_site_identifier($siteidentifier);
+
+        // Main savepoint reached.
+        upgrade_main_savepoint(true, 2013021800.00);
+    }
+
+    if ($oldversion < 2013021801.00) {
+        // Fixing possible wrong MIME types for SMART Notebook files.
+        $extensions = array('%.gallery', '%.galleryitem', '%.gallerycollection', '%.nbk', '%.notebook', '%.xbk');
+        $select = $DB->sql_like('filename', '?', false);
+        foreach ($extensions as $extension) {
+            $DB->set_field_select(
+                'files',
+                'mimetype',
+                'application/x-smarttech-notebook',
+                $select,
+                array($extension)
+            );
+        }
+        upgrade_main_savepoint(true, 2013021801.00);
+    }
+
+    if ($oldversion < 2013021801.01) {
+        // Retrieve the list of course_sections as a recordset to save memory
+        $coursesections = $DB->get_recordset('course_sections', null, 'course, id', 'id, course, sequence');
+        foreach ($coursesections as $coursesection) {
+            // Retrieve all of the actual modules in this course and section combination to reduce DB calls
+            $actualsectionmodules = $DB->get_records('course_modules',
+                    array('course' => $coursesection->course, 'section' => $coursesection->id), '', 'id, section');
+
+            // Break out the current sequence so that we can compare it
+            $currentsequence = explode(',', $coursesection->sequence);
+            $newsequence = array();
+
+            // Check each of the modules in the current sequence
+            foreach ($currentsequence as $module) {
+                if (isset($actualsectionmodules[$module])) {
+                    $newsequence[] = $module;
+                    // We unset the actualsectionmodules so that we don't get duplicates and that we can add orphaned
+                    // modules later
+                    unset($actualsectionmodules[$module]);
+                }
+            }
+
+            // Append any modules which have somehow been orphaned
+            foreach ($actualsectionmodules as $module) {
+                $newsequence[] = $module->id;
+            }
+
+            // Piece it all back together
+            $sequence = implode(',', $newsequence);
+
+            // Only update if there have been changes
+            if ($sequence !== $coursesection->sequence) {
+                $coursesection->sequence = $sequence;
+                $DB->update_record('course_sections', $coursesection);
+
+                // And clear the sectioncache and modinfo cache - they'll be regenerated on next use
+                $course = new stdClass();
+                $course->id = $coursesection->course;
+                $course->sectioncache = null;
+                $course->modinfo = null;
+                $DB->update_record('course', $course);
+            }
+        }
+        $coursesections->close();
+
+        // Main savepoint reached.
+        upgrade_main_savepoint(true, 2013021801.01);
+    }
+
     return true;
 }
index d5b84aa..6fb311d 100644 (file)
@@ -1469,6 +1469,10 @@ function &get_mimetypes_array() {
         'fdf'  => array ('type'=>'application/pdf', 'icon'=>'pdf'),
         'flv'  => array ('type'=>'video/x-flv', 'icon'=>'flash', 'groups'=>array('video','web_video'), 'string'=>'video'),
         'f4v'  => array ('type'=>'video/mp4', 'icon'=>'flash', 'groups'=>array('video','web_video'), 'string'=>'video'),
+
+        'gallery'           => array ('type'=>'application/x-smarttech-notebook', 'icon'=>'archive'),
+        'galleryitem,'      => array ('type'=>'application/x-smarttech-notebook', 'icon'=>'archive'),
+        'gallerycollection' => array ('type'=>'application/x-smarttech-notebook', 'icon'=>'archive'),
         'gif'  => array ('type'=>'image/gif', 'icon'=>'gif', 'groups'=>array('image', 'web_image'), 'string'=>'image'),
         'gtar' => array ('type'=>'application/x-gtar', 'icon'=>'archive', 'groups'=>array('archive'), 'string'=>'archive'),
         'tgz'  => array ('type'=>'application/g-zip', 'icon'=>'archive', 'groups'=>array('archive'), 'string'=>'archive'),
@@ -1512,6 +1516,9 @@ function &get_mimetypes_array() {
         'mpe'  => array ('type'=>'video/mpeg', 'icon'=>'mpeg', 'groups'=>array('video','web_video'), 'string'=>'video'),
         'mpg'  => array ('type'=>'video/mpeg', 'icon'=>'mpeg', 'groups'=>array('video','web_video'), 'string'=>'video'),
 
+        'nbk'       => array ('type'=>'application/x-smarttech-notebook', 'icon'=>'archive'),
+        'notebook'  => array ('type'=>'application/x-smarttech-notebook', 'icon'=>'archive'),
+
         'odt'  => array ('type'=>'application/vnd.oasis.opendocument.text', 'icon'=>'writer', 'groups'=>array('document')),
         'ott'  => array ('type'=>'application/vnd.oasis.opendocument.text-template', 'icon'=>'writer', 'groups'=>array('document')),
         'oth'  => array ('type'=>'application/vnd.oasis.opendocument.text-web', 'icon'=>'oth', 'groups'=>array('document')),
@@ -1591,6 +1598,8 @@ function &get_mimetypes_array() {
         'webm'  => array ('type'=>'video/webm', 'icon'=>'video', 'groups'=>array('video'), 'string'=>'video'),
         'wmv'  => array ('type'=>'video/x-ms-wmv', 'icon'=>'wmv', 'groups'=>array('video'), 'string'=>'video'),
         'asf'  => array ('type'=>'video/x-ms-asf', 'icon'=>'wmv', 'groups'=>array('video'), 'string'=>'video'),
+
+        'xbk'  => array ('type'=>'application/x-smarttech-notebook', 'icon'=>'archive'),
         'xdp'  => array ('type'=>'application/pdf', 'icon'=>'pdf'),
         'xfd'  => array ('type'=>'application/pdf', 'icon'=>'pdf'),
         'xfdf' => array ('type'=>'application/pdf', 'icon'=>'pdf'),
@@ -1605,6 +1614,7 @@ function &get_mimetypes_array() {
 
         'xml'  => array ('type'=>'application/xml', 'icon'=>'markup'),
         'xsl'  => array ('type'=>'text/xml', 'icon'=>'markup'),
+
         'zip'  => array ('type'=>'application/zip', 'icon'=>'archive', 'groups'=>array('archive'), 'string'=>'archive')
     );
     return $mimearray;
index eca1097..fa53943 100644 (file)
@@ -1327,6 +1327,9 @@ function set_config($name, $value, $plugin=NULL) {
                 $DB->insert_record('config', $config, false);
             }
         }
+        if ($name === 'siteidentifier') {
+            cache_helper::update_site_identifier($value);
+        }
         cache_helper::invalidate_by_definition('core', 'config', array(), 'core');
     } else { // plugin scope
         if ($id = $DB->get_field('config_plugins', 'id', array('name'=>$name, 'plugin'=>$plugin))) {
@@ -1360,6 +1363,8 @@ function set_config($name, $value, $plugin=NULL) {
  * If called with 2 parameters it will return a string single
  * value or false if the value is not found.
  *
+ * @static $siteidentifier The site identifier is not cached. We use this static cache so
+ *     that we need only fetch it once per request.
  * @param string $plugin full component name
  * @param string $name default NULL
  * @return mixed hash-like object or single value, return false no config found
@@ -1367,6 +1372,8 @@ function set_config($name, $value, $plugin=NULL) {
 function get_config($plugin, $name = NULL) {
     global $CFG, $DB;
 
+    static $siteidentifier = null;
+
     if ($plugin === 'moodle' || $plugin === 'core' || empty($plugin)) {
         $forced =& $CFG->config_php_settings;
         $iscore = true;
@@ -1380,8 +1387,28 @@ function get_config($plugin, $name = NULL) {
         $iscore = false;
     }
 
-    if (!empty($name) && array_key_exists($name, $forced)) {
-        return (string)$forced[$name];
+    if ($siteidentifier === null) {
+        try {
+            // This may fail during installation.
+            // If you have a look at {@link initialise_cfg()} you will see that this is how we detect the need to
+            // install the database.
+            $siteidentifier = $DB->get_field('config', 'value', array('name' => 'siteidentifier'));
+        } catch (dml_exception $ex) {
+            // It's failed. We'll use this opportunity to disable cache stores so that we don't inadvertingly start using
+            // old caches. People should delete their moodledata dirs when reinstalling the database... but they don't.
+            cache_factory::disable_stores();
+            // Set siteidentifier to false. We don't want to trip this continually.
+            $siteidentifier = false;
+            throw $ex;
+        }
+    }
+
+    if (!empty($name)) {
+        if (array_key_exists($name, $forced)) {
+            return (string)$forced[$name];
+        } else if ($name === 'siteidentifier' && $plugin == 'core') {
+            return $siteidentifier;
+        }
     }
 
     $cache = cache::make('core', 'config');
@@ -1405,6 +1432,10 @@ function get_config($plugin, $name = NULL) {
         return false;
     }
 
+    if ($plugin === 'core') {
+        $result['siteidentifier'] = $siteidentifier;
+    }
+
     foreach ($forced as $key => $value) {
         if (is_null($value) or is_array($value) or is_object($value)) {
             // we do not want any extra mess here, just real settings that could be saved in db
index 3582c01..5218444 100644 (file)
@@ -1442,6 +1442,18 @@ function stats_get_report_options($courseid,$mode) {
     return $reportoptions;
 }
 
+/**
+ * Fix missing entries in the statistics.
+ *
+ * This creates a dummy stat when nothing happened during a day/week/month.
+ *
+ * @param array $stats array of statistics.
+ * @param int $timeafter unused.
+ * @param string $timestr type of statistics to generate (dayly, weekly, monthly).
+ * @param boolean $line2
+ * @param boolean $line3
+ * @return array of fixed statistics.
+ */
 function stats_fix_zeros($stats,$timeafter,$timestr,$line2=true,$line3=false) {
 
     if (empty($stats)) {
@@ -1449,23 +1461,29 @@ function stats_fix_zeros($stats,$timeafter,$timestr,$line2=true,$line3=false) {
     }
 
     $timestr = str_replace('user_','',$timestr); // just in case.
-    $fun = 'stats_get_base_'.$timestr;
 
+    // Gets the current user base time.
+    $fun = 'stats_get_base_'.$timestr;
     $now = $fun();
 
-    $times = array();
-    // add something to timeafter since it is our absolute base
+    // Extract the ending time of the statistics.
     $actualtimes = array();
-    foreach ($stats as $statid=>$s) {
-        //normalize the times in stats - those might have been created in different timezone, DST etc.
-        $s->timeend = $fun($s->timeend + 60*60*5);
+    foreach ($stats as $statid => $s) {
+        // Normalise the month date to the 1st if for any reason it's set to later. But we ignore
+        // anything above or equal to 29 because sometimes we get the end of the month.
+        if ($timestr == 'monthly' && date('d', $s->timeend) > 1 && date('d', $s->timeend) < 29) {
+            $s->timeend = mktime(date('H', $s->timeend), date('i', $s->timeend), date('s', $s->timeend),
+                date('m', $s->timeend), 1, date('Y', $s->timeend));
+        }
         $stats[$statid] = $s;
-
         $actualtimes[] = $s->timeend;
     }
 
-    $timeafter = array_pop(array_values($actualtimes));
+    $actualtimesvalues = array_values($actualtimes);
+    $timeafter = array_pop($actualtimesvalues);
 
+    // Generate a base timestamp for each possible month/week/day.
+    $times = array();
     while ($timeafter < $now) {
         $times[] = $timeafter;
         if ($timestr == 'daily') {
@@ -1473,12 +1491,26 @@ function stats_fix_zeros($stats,$timeafter,$timestr,$line2=true,$line3=false) {
         } else if ($timestr == 'weekly') {
             $timeafter = stats_get_next_week_start($timeafter);
         } else if ($timestr == 'monthly') {
-            $timeafter = stats_get_next_month_start($timeafter);
+            // We can't just simply +1 month because the 31st Jan + 1 month = 2nd of March.
+            $year = date('Y', $timeafter);
+            $month = date('m', $timeafter);
+            $day = date('d', $timeafter);
+            $dayofnextmonth = $day;
+            if ($day >= 29) {
+                $daysinmonth = date('n', mktime(0, 0, 0, $month+1, 1, $year));
+                if ($day > $daysinmonth) {
+                    $dayofnextmonth = $daysinmonth;
+                }
+            }
+            $timeafter = mktime(date('H', $timeafter), date('i', $timeafter), date('s', $timeafter), $month+1,
+                $dayofnextmonth, $year);
         } else {
-            return $stats; // this will put us in a never ending loop.
+            // This will put us in a never ending loop.
+            return $stats;
         }
     }
 
+    // Add the base timestamp to the statistics if not present.
     foreach ($times as $count => $time) {
         if (!in_array($time,$actualtimes) && $count != count($times) -1) {
             $newobj = new StdClass;
@@ -1499,7 +1531,6 @@ function stats_fix_zeros($stats,$timeafter,$timestr,$line2=true,$line3=false) {
 
     usort($stats,"stats_compare_times");
     return $stats;
-
 }
 
 // helper function to sort arrays by $obj->timeend
index 111026c..9382583 100644 (file)
@@ -1448,8 +1448,9 @@ function install_core($version, $verbose) {
 
         print_upgrade_part_end(null, true, $verbose);
 
-        // Reset the cache, this returns it to a normal operation state.
-        cache_factory::reset();
+        // Purge all caches. They're disabled but this ensures that we don't have any persistent data just in case something
+        // during installation didn't use APIs.
+        cache_helper::purge_all();
     } catch (exception $ex) {
         upgrade_handle_exception($ex);
     }
@@ -1536,8 +1537,8 @@ function upgrade_noncore($verbose) {
 
     // upgrade all plugins types
     try {
-        // Disable the use of cache stores here. We will reset the factory after we've performed the installation.
-        // This ensures that we don't permanently cache anything during installation.
+        // Disable the use of cache stores here.
+        // We don't reset this, the site can live without proper caching for life of this request.
         cache_factory::disable_stores();
 
         $plugintypes = get_plugin_types();
@@ -1546,8 +1547,6 @@ function upgrade_noncore($verbose) {
         }
         // Update cache definitions. Involves scanning each plugin for any changes.
         cache_helper::update_definitions();
-        // Reset the cache system to a normal state.
-        cache_factory::reset();
     } catch (Exception $ex) {
         upgrade_handle_exception($ex);
     }
index a5ad1c4..58b8083 100644 (file)
@@ -185,7 +185,7 @@ class mod_assign_external extends external_api {
             array(
                 'assignments' => new external_multiple_structure(self::assign_grades(), 'list of assignment grade information'),
                 'warnings'      => new external_warnings('item is always \'assignment\'',
-                    'when errorcode is 3 then itemid is an assignment id. When errorcode is 1, itemid is a course module instance id',
+                    'when errorcode is 3 then itemid is an assignment id. When errorcode is 1, itemid is a course module id',
                     'errorcode can be 3 (no grades found) or 1 (no permission to get grades)')
             )
         );
index ef1c7ed..a189bae 100644 (file)
@@ -324,4 +324,7 @@ $string['viewfull'] = 'View full';
 $string['viewsummary'] = 'View summary';
 $string['viewsubmissiongradingtable'] = 'View submission grading table.';
 $string['viewrevealidentitiesconfirm'] = 'View reveal student identities confirmation page.';
+$string['submissiontypes'] = 'Submission types';
+$string['feedbacktypes'] = 'Feedback types';
+$string['groupsubmissionsettings'] = 'Group submission settings';
 
index e28ba43..e428889 100644 (file)
@@ -657,7 +657,7 @@ class assign {
     protected function update_plugin_instance(assign_plugin $plugin, stdClass $formdata) {
         if ($plugin->is_visible()) {
             $enabledname = $plugin->get_subtype() . '_' . $plugin->get_type() . '_enabled';
-            if ($formdata->$enabledname) {
+            if (!empty($formdata->$enabledname)) {
                 $plugin->enable();
                 if (!$plugin->save_settings($formdata)) {
                     print_error($plugin->get_error());
@@ -843,17 +843,18 @@ class assign {
      * @param assign_plugin $plugin The plugin to add the settings from
      * @param MoodleQuickForm $mform The form to add the configuration settings to.
      *                               This form is modified directly (not returned).
+     * @param array $pluginsenabled A list of form elements to be added to a group.
+     *                              The new element is added to this array by this function.
      * @return void
      */
-    protected function add_plugin_settings(assign_plugin $plugin, MoodleQuickForm $mform) {
+    protected function add_plugin_settings(assign_plugin $plugin, MoodleQuickForm $mform, & $pluginsenabled) {
         global $CFG;
         if ($plugin->is_visible()) {
-            $mform->addElement('selectyesno',
-                               $plugin->get_subtype() . '_' . $plugin->get_type() . '_enabled',
-                               $plugin->get_name());
-            $mform->addHelpButton($plugin->get_subtype() . '_' . $plugin->get_type() . '_enabled',
-                                  'enabled',
-                                  $plugin->get_subtype() . '_' . $plugin->get_type());
+
+            $name = $plugin->get_subtype() . '_' . $plugin->get_type() . '_enabled';
+            $label = $plugin->get_name();
+            $label .= ' ' . $this->get_renderer()->help_icon('enabled', $plugin->get_subtype() . '_' . $plugin->get_type());
+            $pluginsenabled[] = $mform->createElement('checkbox', $name, '', $label);
 
             $default = get_config($plugin->get_subtype() . '_' . $plugin->get_type(), 'default');
             if ($plugin->get_config('enabled') !== false) {
@@ -874,16 +875,23 @@ class assign {
      * @return void
      */
     public function add_all_plugin_settings(MoodleQuickForm $mform) {
-        $mform->addElement('header', 'general', get_string('submissionsettings', 'assign'));
+        $mform->addElement('header', 'submissiontypes', get_string('submissionsettings', 'assign'));
 
+        $submissionpluginsenabled = array();
+        $group = $mform->addGroup(array(), 'submissionplugins', get_string('submissiontypes', 'assign'), array(' '), false);
         foreach ($this->submissionplugins as $plugin) {
-            $this->add_plugin_settings($plugin, $mform);
-
+            $this->add_plugin_settings($plugin, $mform, $submissionpluginsenabled);
         }
-        $mform->addElement('header', 'general', get_string('feedbacksettings', 'assign'));
+        $group->setElements($submissionpluginsenabled);
+
+        $mform->addElement('header', 'feedbacktypes', get_string('feedbacksettings', 'assign'));
+        $feedbackpluginsenabled = array();
+        $group = $mform->addGroup(array(), 'feedbackplugins', get_string('feedbacktypes', 'assign'), array(' '), false);
         foreach ($this->feedbackplugins as $plugin) {
-            $this->add_plugin_settings($plugin, $mform);
+            $this->add_plugin_settings($plugin, $mform, $feedbackpluginsenabled);
         }
+        $group->setElements($feedbackpluginsenabled);
+        $mform->setExpanded('submissiontypes');
     }
 
     /**
@@ -3112,7 +3120,6 @@ class assign {
                     }
                 }
 
-
                 $feedbackstatus = new assign_feedback_status($gradefordisplay,
                                                       $gradeddate,
                                                       $grader,
index 70bc77b..998d2e7 100644 (file)
@@ -73,7 +73,9 @@ class mod_assign_mod_form extends moodleform_mod {
 
         $config = get_config('assign');
 
-        $mform->addElement('header', 'general', get_string('settings', 'assign'));
+        $assignment->add_all_plugin_settings($mform);
+
+        $mform->addElement('header', 'availability', get_string('availability', 'assign'));
 
         $name = get_string('allowsubmissionsfromdate', 'assign');
         $options = array('optional'=>true);
@@ -92,10 +94,12 @@ class mod_assign_mod_form extends moodleform_mod {
         $mform->setDefault('cutoffdate', time()+7*24*3600);
 
         $name = get_string('alwaysshowdescription', 'assign');
-        $mform->addElement('selectyesno', 'alwaysshowdescription', $name);
+        $mform->addElement('checkbox', 'alwaysshowdescription', $name);
         $mform->addHelpButton('alwaysshowdescription', 'alwaysshowdescription', 'assign');
         $mform->setDefault('alwaysshowdescription', 1);
 
+        $mform->addElement('header', 'submissionsettings', get_string('submissionsettings', 'assign'));
+
         $name = get_string('submissiondrafts', 'assign');
         $mform->addElement('selectyesno', 'submissiondrafts', $name);
         $mform->addHelpButton('submissiondrafts', 'submissiondrafts', 'assign');
@@ -114,16 +118,7 @@ class mod_assign_mod_form extends moodleform_mod {
             $mform->addElement('hidden', 'requiresubmissionstatement', 1);
         }
 
-        $name = get_string('sendnotifications', 'assign');
-        $mform->addElement('selectyesno', 'sendnotifications', $name);
-        $mform->addHelpButton('sendnotifications', 'sendnotifications', 'assign');
-        $mform->setDefault('sendnotifications', 1);
-
-        $name = get_string('sendlatenotifications', 'assign');
-        $mform->addElement('selectyesno', 'sendlatenotifications', $name);
-        $mform->addHelpButton('sendlatenotifications', 'sendlatenotifications', 'assign');
-        $mform->setDefault('sendlatenotifications', 1);
-        $mform->disabledIf('sendlatenotifications', 'sendnotifications', 'eq', 1);
+        $mform->addElement('header', 'groupsubmissionsettings', get_string('groupsubmissionsettings', 'assign'));
 
         $name = get_string('teamsubmission', 'assign');
         $mform->addElement('selectyesno', 'teamsubmission', $name);
@@ -150,13 +145,18 @@ class mod_assign_mod_form extends moodleform_mod {
         $mform->setDefault('teamsubmissiongroupingid', 0);
         $mform->disabledIf('teamsubmissiongroupingid', 'teamsubmission', 'eq', 0);
 
-        $name = get_string('blindmarking', 'assign');
-        $mform->addElement('selectyesno', 'blindmarking', $name);
-        $mform->addHelpButton('blindmarking', 'blindmarking', 'assign');
-        $mform->setDefault('blindmarking', 0);
-        if ($assignment->has_submissions_or_grades() ) {
-            $mform->freeze('blindmarking');
-        }
+        $mform->addElement('header', 'notifications', get_string('notifications', 'assign'));
+
+        $name = get_string('sendnotifications', 'assign');
+        $mform->addElement('selectyesno', 'sendnotifications', $name);
+        $mform->addHelpButton('sendnotifications', 'sendnotifications', 'assign');
+        $mform->setDefault('sendnotifications', 1);
+
+        $name = get_string('sendlatenotifications', 'assign');
+        $mform->addElement('selectyesno', 'sendlatenotifications', $name);
+        $mform->addHelpButton('sendlatenotifications', 'sendlatenotifications', 'assign');
+        $mform->setDefault('sendlatenotifications', 1);
+        $mform->disabledIf('sendlatenotifications', 'sendnotifications', 'eq', 1);
 
         // Plagiarism enabling form.
         if (!empty($CFG->enableplagiarism)) {
@@ -164,8 +164,15 @@ class mod_assign_mod_form extends moodleform_mod {
             plagiarism_get_form_elements_module($mform, $ctx->get_course_context(), 'mod_assign');
         }
 
-        $assignment->add_all_plugin_settings($mform);
         $this->standard_grading_coursemodule_elements();
+        $name = get_string('blindmarking', 'assign');
+        $mform->addElement('selectyesno', 'blindmarking', $name);
+        $mform->addHelpButton('blindmarking', 'blindmarking', 'assign');
+        $mform->setDefault('blindmarking', 0);
+        if ($assignment->has_submissions_or_grades() ) {
+            $mform->freeze('blindmarking');
+        }
+
         $this->standard_coursemodule_elements();
 
         $this->add_action_buttons();
@@ -177,6 +184,7 @@ class mod_assign_mod_form extends moodleform_mod {
                                                   'assignment = ? AND grade <> -1',
                                                   array($this->_instance));
         }
+
         if ($mform->elementExists('grade') && $hasgrade) {
             $module = array(
                 'name' => 'mod_assign',
index 3d16000..bd08924 100644 (file)
@@ -85,7 +85,7 @@ class assign_submission_file extends assign_submission_plugin {
                               'maxfilessubmission',
                               'assignsubmission_file');
         $mform->setDefault('assignsubmission_file_maxfiles', $defaultmaxfilesubmissions);
-        $mform->disabledIf('assignsubmission_file_maxfiles', 'assignsubmission_file_enabled', 'eq', 0);
+        $mform->disabledIf('assignsubmission_file_maxfiles', 'assignsubmission_file_enabled', 'notchecked');
 
         $choices = get_max_upload_sizes($CFG->maxbytes,
                                         $COURSE->maxbytes,
@@ -105,7 +105,7 @@ class assign_submission_file extends assign_submission_plugin {
         $mform->setDefault('assignsubmission_file_maxsizebytes', $defaultmaxsubmissionsizebytes);
         $mform->disabledIf('assignsubmission_file_maxsizebytes',
                            'assignsubmission_file_enabled',
-                           'eq', 0);
+                           'notchecked');
     }
 
     /**
index 11a3de4..19d049c 100644 (file)
@@ -181,7 +181,6 @@ class mod_assign_lib_testcase extends advanced_testcase {
 
         $submission = $assign->get_user_submission($this->students[0]->id, true);
 
-
         $this->expectOutputRegex('/Draft/');
         assign_user_complete($this->course, $this->students[0], $assign->get_course_module(), $assign->get_instance());
 
index 6f533b8..ae2164c 100644 (file)
@@ -674,7 +674,7 @@ class mod_assign_locallib_testcase extends advanced_testcase {
         $data->grade = '50.0';
         $assign->testable_apply_grade_to_user($data, $this->students[0]->id);
 
-        // Now we should see the feedback
+        // Now we should see the feedback.
         $this->setUser($this->students[0]);
         $output = $assign->view_student_summary($this->students[0], true);
         $this->assertNotEquals(false, strpos($output, 'Feedback'), 'Show feedback if there is a grade');
@@ -695,7 +695,7 @@ class mod_assign_locallib_testcase extends advanced_testcase {
         $output = $assign->view_student_summary($this->students[0], true);
         $this->assertEquals(false, strpos($output, 'Feedback'), 'Do not show feedback if the grade is hidden in the gradebook');
 
-        // Do the same but add feedback
+        // Do the same but add feedback.
         $assign = $this->create_instance(array('assignfeedback_comments_enabled' => 1));
 
         $this->setUser($this->teachers[0]);
@@ -706,7 +706,7 @@ class mod_assign_locallib_testcase extends advanced_testcase {
         $plugin = $assign->get_feedback_plugin_by_type('comments');
         $plugin->save($grade, $data);
 
-        // Should have feedback but no grade
+        // Should have feedback but no grade.
         $this->setUser($this->students[0]);
         $output = $assign->view_student_summary($this->students[0], true);
         $this->assertNotEquals(false, strpos($output, 'Tomato sauce'), 'Show feedback even if there is no grade');
index 3a23941..1dff332 100644 (file)
@@ -3,7 +3,7 @@
 defined('MOODLE_INTERNAL') || die();
 
 class mod_data_renderer extends plugin_renderer_base {
-    
+
     public function import_setting_mappings($datamodule, data_preset_importer $importer) {
 
         $strblank = get_string('blank', 'data');
@@ -24,7 +24,7 @@ class mod_data_renderer extends plugin_renderer_base {
         $html .= html_writer::empty_tag('input', array('type'=>'hidden', 'name'=>'action', 'value'=>'finishimport'));
         $html .= html_writer::empty_tag('input', array('type'=>'hidden', 'name'=>'sesskey', 'value'=>sesskey()));
         $html .= html_writer::empty_tag('input', array('type'=>'hidden', 'name'=>'d', 'value'=>$datamodule->id));
-        
+
         if ($importer instanceof data_preset_existing_importer) {
             $html .= html_writer::empty_tag('input', array('type'=>'hidden', 'name'=>'fullname', 'value'=>$importer->get_userid().'/'.$importer->get_directory()));
         } else {
@@ -60,7 +60,7 @@ class mod_data_renderer extends plugin_renderer_base {
                 } else {
                     $row[1] .= html_writer::tag('option', get_string('mapnewfield', 'data'), array('value'=>'-1', 'selected'=>'selected'));
                 }
-                
+
                 $row[1] .= html_writer::end_tag('select');
                 $table->data[] = $row;
             }
@@ -82,5 +82,5 @@ class mod_data_renderer extends plugin_renderer_base {
 
         return $html;
     }
-    
-}
\ No newline at end of file
+
+}
index 1a294dc..4350157 100644 (file)
@@ -79,11 +79,11 @@ for ($i = 0; $i < $bands; $i++) {
 
 // Do this only if we have students to report
 if(!$nostudents) {
-    // Construct the SQL\r
-    $select = 'SELECT DISTINCT '.$DB->sql_concat('st.userid', '\'#\'', 'COALESCE(st.attempt, 0)').' AS uniqueid, ';\r
-    $select .= 'st.userid AS userid, st.scormid AS scormid, st.attempt AS attempt, st.scoid AS scoid ';\r
-    $from = 'FROM {scorm_scoes_track} st ';\r
-    $where = ' WHERE st.userid ' .$usql. ' and st.scoid = ?';\r
+    // Construct the SQL
+    $select = 'SELECT DISTINCT '.$DB->sql_concat('st.userid', '\'#\'', 'COALESCE(st.attempt, 0)').' AS uniqueid, ';
+    $select .= 'st.userid AS userid, st.scormid AS scormid, st.attempt AS attempt, st.scoid AS scoid ';
+    $from = 'FROM {scorm_scoes_track} st ';
+    $where = ' WHERE st.userid ' .$usql. ' and st.scoid = ?';
     $attempts = $DB->get_records_sql($select.$from.$where, $params);
 
     foreach ($attempts as $attempt) {
index bf658ea..ebf91e9 100644 (file)
@@ -33,7 +33,7 @@ $numcourses = optional_param('numcourses', 20, PARAM_INT);
 
 if (empty($CFG->enablestats)) {
     if (has_capability('moodle/site:config', context_system::instance())) {
-        redirect("$CFG->wwwroot/$CFG->admin/settings.php?section=stats", get_string('mustenablestats', 'admin'), 3);
+        redirect("$CFG->wwwroot/$CFG->admin/search.php?query=enablestats", get_string('mustenablestats', 'admin'), 3);
     } else {
         print_error('statsdisable');
     }
index e952338..5167670 100644 (file)
@@ -25,7 +25,7 @@
 
 defined('MOODLE_INTERNAL') || die;
 
-$ADMIN->add('reports', new admin_externalpage('reportcourseoverview', get_string('pluginname', 'report_courseoverview'), "$CFG->wwwroot/report/courseoverview/index.php",'report/courseoverview:view'));
+$ADMIN->add('reports', new admin_externalpage('reportcourseoverview', get_string('pluginname', 'report_courseoverview'), "$CFG->wwwroot/report/courseoverview/index.php",'report/courseoverview:view', empty($CFG->enablestats)));
 
 // no report settings
 $settings = null;
index bde390d..97c2733 100644 (file)
@@ -24,7 +24,7 @@
  */
 
 require_once $CFG->dirroot.'/tag/lib.php';
-require_once $CFG->dirroot.'/tag/locallib.php';\r
+require_once $CFG->dirroot.'/tag/locallib.php';
 
 /**
  * Returns an ordered array of tags associated with visible courses
index 5ab02ab..1f01386 100644 (file)
@@ -30,7 +30,7 @@
 defined('MOODLE_INTERNAL') || die();
 
 
-$version  = 2013021400.00;              // YYYYMMDD      = weekly release date of this DEV branch
+$version  = 2013021801.01;              // YYYYMMDD      = weekly release date of this DEV branch
                                         //         RR    = release increments - 00 in DEV branches
                                         //           .XX = incremental changes