Merge branch 'MDL-36415-master-int' of git://github.com/FMCorz/moodle
authorDan Poltawski <dan@moodle.com>
Mon, 19 Nov 2012 02:51:54 +0000 (10:51 +0800)
committerDan Poltawski <dan@moodle.com>
Mon, 19 Nov 2012 02:51:54 +0000 (10:51 +0800)
Conflicts:
theme/upgrade.txt

49 files changed:
cache/classes/config.php
cache/classes/definition.php
cache/classes/factory.php
cache/classes/helper.php
cache/classes/loaders.php
cache/stores/file/lib.php
cache/testperformance.php
cache/tests/locallib_test.php
calendar/lib.php
calendar/managesubscriptions_form.php
course/category.php
course/index.php
course/lib.php
course/search.php
enrol/manual/lib.php
grade/report/grader/index.php
grade/report/grader/lib.php
install/lang/en_fix/langconfig.php [deleted file]
install/lang/hr/moodle.php
install/lang/lt/install.php [new file with mode: 0644]
lib/db/upgrade.php
lib/enrollib.php
lib/googleapi.php
lib/moodlelib.php
lib/outputlib.php
lib/tests/outputlib_test.php
mod/lesson/format.php
pix/i/cohort.png [new file with mode: 0644]
pix/i/cohort.svg [new file with mode: 0644]
pix/i/enrolusers.png [new file with mode: 0644]
pix/i/enrolusers.svg [new file with mode: 0644]
pix/i/permissions.png [new file with mode: 0644]
pix/i/permissions.svg [new file with mode: 0644]
pix/i/rss.png [new file with mode: 0644]
pix/i/rss.svg [new file with mode: 0644]
pix/i/users.png
pix/i/users.svg
pix/i/withsubcat.png
pix/i/withsubcat.svg [new file with mode: 0644]
pix/t/backup.png [new file with mode: 0644]
pix/t/backup.svg [new file with mode: 0644]
pix/t/cohort.png [new file with mode: 0644]
pix/t/cohort.svg [new file with mode: 0644]
pix/t/enrolusers.png [new file with mode: 0644]
pix/t/enrolusers.svg [new file with mode: 0644]
pix/t/restore.png [new file with mode: 0644]
pix/t/restore.svg [new file with mode: 0644]
theme/upgrade.txt
version.php

index 682ef18..da3b966 100644 (file)
@@ -344,6 +344,61 @@ class cache_config {
         return $this->configdefinitions;
     }
 
+    /**
+     * Returns the definitions mapped into the given store name.
+     *
+     * @param string $storename
+     * @return array Associative array of definitions, id=>definition
+     */
+    public static function get_definitions_by_store($storename) {
+        $definitions = array();
+
+        $config = cache_config::instance();
+        $stores = $config->get_all_stores();
+        if (!array_key_exists($storename, $stores)) {
+            // The store does not exist.
+            return false;
+        }
+
+        $defmappings = $config->get_definition_mappings();
+        // Create an associative array for the definition mappings.
+        $thedefmappings = array();
+        foreach ($defmappings as $defmapping) {
+            $thedefmappings[$defmapping['definition']] = $defmapping;
+        }
+
+        // Search for matches in default mappings.
+        $defs = $config->get_definitions();
+        foreach($config->get_mode_mappings() as $modemapping) {
+            if ($modemapping['store'] !== $storename) {
+                continue;
+            }
+            foreach($defs as $id => $definition) {
+                if ($definition['mode'] !== $modemapping['mode']) {
+                    continue;
+                }
+                // Exclude custom definitions mapping: they will be managed few lines below.
+                if (array_key_exists($id, $thedefmappings)) {
+                    continue;
+                }
+                $definitions[$id] = $definition;
+            }
+        }
+
+        // Search for matches in the custom definitions mapping
+        foreach ($defmappings as $defmapping) {
+            if ($defmapping['store'] !== $storename) {
+                continue;
+            }
+            $definition = $config->get_definition_by_id($defmapping['definition']);
+            if ($definition) {
+                $definitions[$defmapping['definition']] = $definition;
+            }
+        }
+
+        return $definitions;
+    }
+
     /**
      * Returns all of the stores that are suitable for the given mode and requirements.
      *
index fd93324..607f074 100644 (file)
@@ -457,20 +457,31 @@ class cache_definition {
      * @param int $mode One of cache_store::MODE_*
      * @param string $component The component this definition relates to.
      * @param string $area The area this definition relates to.
-     * @param string $overrideclass The class to use as the loader.
-     * @param bool $persistent If this cache should be persistent.
+     * @param array $options An array of options, available options are:
+     *   - simplekeys : Set to true if the keys you will use are a-zA-Z0-9_
+     *   - simpledata : Set to true if the type of the data you are going to store is scalar, or an array of scalar vars
+     *   - overrideclass : The class to use as the loader.
+     *   - persistent : If set to true the cache will persist construction requests.
      * @return cache_application|cache_session|cache_request
      */
-    public static function load_adhoc($mode, $component, $area, $overrideclass = null, $persistent = false) {
+    public static function load_adhoc($mode, $component, $area, array $options = array()) {
         $id = 'adhoc/'.$component.'_'.$area;
         $definition = array(
             'mode' => $mode,
             'component' => $component,
             'area' => $area,
-            'persistent' => $persistent
         );
-        if (!is_null($overrideclass)) {
-            $definition['overrideclass'] = $overrideclass;
+        if (!empty($options['simplekeys'])) {
+            $definition['simplekeys'] = $options['simplekeys'];
+        }
+        if (!empty($options['simpledata'])) {
+            $definition['simpledata'] = $options['simpledata'];
+        }
+        if (!empty($options['persistent'])) {
+            $definition['persistent'] = $options['persistent'];
+        }
+        if (!empty($options['overrideclass'])) {
+            $definition['overrideclass'] = $options['overrideclass'];
         }
         return self::load($id, $definition, null);
     }
index ddf4e8d..9a588df 100644 (file)
@@ -151,16 +151,19 @@ class cache_factory {
      * @param string $component
      * @param string $area
      * @param array $identifiers
-     * @param bool $persistent
+     * @param array $options An array of options, available options are:
+     *   - simplekeys : Set to true if the keys you will use are a-zA-Z0-9_
+     *   - simpledata : Set to true if the type of the data you are going to store is scalar, or an array of scalar vars
+     *   - persistent : If set to true the cache will persist construction requests.
      * @return cache_application|cache_session|cache_request
      */
-    public function create_cache_from_params($mode, $component, $area, array $identifiers = array(), $persistent = false) {
+    public function create_cache_from_params($mode, $component, $area, array $identifiers = array(), array $options = array()) {
         $key = "{$mode}_{$component}_{$area}";
         if (array_key_exists($key, $this->cachesfromparams)) {
             return $this->cachesfromparams[$key];
         }
         // 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, null, $persistent);
+        $definition = cache_definition::load_adhoc($mode, $component, $area, $options);
         $definition->set_identifiers($identifiers);
         $cache = $this->create_cache($definition, $identifiers);
         if ($definition->should_be_persistent()) {
index 154d9d8..4439a56 100644 (file)
@@ -270,6 +270,8 @@ class cache_helper {
     /**
      * Purges the cache for a specific definition.
      *
+     * @todo MDL-36660: Change the signature: $aggregate must be added.
+     *
      * @param string $component
      * @param string $area
      * @param array $identifiers
@@ -278,6 +280,14 @@ class cache_helper {
     public static function purge_by_definition($component, $area, array $identifiers = array()) {
         // Create the cache.
         $cache = cache::make($component, $area, $identifiers);
+        // Initialise, in case of a store.
+        if ($cache instanceof cache_store) {
+            $factory = cache_factory::instance();
+            // TODO MDL-36660: Providing $aggregate is required for purging purposes: $definition->get_id()
+            $definition = $factory->create_definition($component, $area, null);
+            $definition->set_identifiers($identifiers);
+            $cache->initialise($definition);
+        }
         // Purge baby, purge.
         $cache->purge();
         return true;
@@ -295,8 +305,13 @@ class cache_helper {
         foreach ($instance->get_definitions() as $name => $definitionarr) {
             $definition = cache_definition::load($name, $definitionarr);
             if ($definition->invalidates_on_event($event)) {
-                // Purge the cache.
+                // Create the cache.
                 $cache = $factory->create_cache($definition);
+                // Initialise, in case of a store.
+                if ($cache instanceof cache_store) {
+                    $cache->initialise($definition);
+                }
+                // Purge the cache.
                 $cache->purge();
 
                 // We need to flag the event in the "Event invalidation" cache if it hasn't already happened.
@@ -389,16 +404,9 @@ class cache_helper {
      */
     public static function purge_all() {
         $config = cache_config::instance();
-        $stores = $config->get_all_stores();
-        $definition = cache_definition::load_adhoc(cache_store::MODE_REQUEST, 'core', 'cache_purge');
-        foreach ($stores as $store) {
-            $class = $store['class'];
-            $instance = new $class($store['name'], $store['configuration']);
-            if (!$instance->is_ready()) {
-                continue;
-            }
-            $instance->initialise($definition);
-            $instance->purge();
+
+        foreach ($config->get_all_stores() as $store) {
+            self::purge_store($store['name']);
         }
     }
 
@@ -410,21 +418,32 @@ class cache_helper {
      */
     public static function purge_store($storename) {
         $config = cache_config::instance();
-        foreach ($config->get_all_stores() as $store) {
-            if ($store['name'] !== $storename) {
-                continue;
-            }
-            $class = $store['class'];
+
+        $stores = $config->get_all_stores();
+        if (!array_key_exists($storename, $stores)) {
+            // The store does not exist.
+            return false;
+        }
+
+        $store = $stores[$storename];
+        $class = $store['class'];
+
+        // Found the store: is it ready?
+        $instance = new $class($store['name'], $store['configuration']);
+        if (!$instance->is_ready()) {
+            unset($instance);
+            return false;
+        }
+
+        foreach ($config->get_definitions_by_store($storename) as $id => $definition) {
+            $definition = cache_definition::load($id, $definition);
             $instance = new $class($store['name'], $store['configuration']);
-            if (!$instance->is_ready()) {
-                continue;
-            }
-            $definition = cache_definition::load_adhoc(cache_store::MODE_REQUEST, 'core', 'cache_purge');
             $instance->initialise($definition);
             $instance->purge();
-            return true;
+            unset($instance);
         }
-        return false;
+
+        return true;
     }
 
     /**
@@ -453,6 +472,9 @@ class cache_helper {
      */
     public static function hash_key($key, cache_definition $definition) {
         if ($definition->uses_simple_keys()) {
+            if (debugging() && preg_match('#[^a-zA-Z0-9_]#', $key)) {
+                throw new coding_exception('Cache definition '.$definition->get_id().' requires simple keys. Invalid key provided.', $key);
+            }
             // We put the key first so that we can be sure the start of the key changes.
             return (string)$key . '-' . $definition->generate_single_key_prefix();
         }
index c837cd8..433e9b7 100644 (file)
@@ -176,12 +176,15 @@ class cache implements cache_loader {
      * @param string $component The component this cache relates to.
      * @param string $area The area this cache relates to.
      * @param array $identifiers Any additional identifiers that should be provided to the definition.
-     * @param bool $persistent If set to true the cache will persist construction requests.
+     * @param array $options An array of options, available options are:
+     *   - simplekeys : Set to true if the keys you will use are a-zA-Z0-9_
+     *   - simpledata : Set to true if the type of the data you are going to store is scalar, or an array of scalar vars
+     *   - persistent : If set to true the cache will persist construction requests.
      * @return cache_application|cache_session|cache_store
      */
-    public static function make_from_params($mode, $component, $area, array $identifiers = array(), $persistent = false) {
+    public static function make_from_params($mode, $component, $area, array $identifiers = array(), array $options = array()) {
         $factory = cache_factory::instance();
-        return $factory->create_cache_from_params($mode, $component, $area, $identifiers, $persistent);
+        return $factory->create_cache_from_params($mode, $component, $area, $identifiers, $options);
     }
 
     /**
@@ -272,11 +275,11 @@ class cache implements cache_loader {
         // 1. Parse the key.
         $parsedkey = $this->parse_key($key);
         // 2. Get it from the persist cache if we can (only when persist is enabled and it has already been requested/set).
-        $result = $this->get_from_persist_cache($parsedkey);
+        $result = false;
+        if ($this->is_using_persist_cache()) {
+            $result = $this->get_from_persist_cache($parsedkey);
+        }
         if ($result !== false) {
-            if ($this->perfdebug) {
-                cache_helper::record_cache_hit('** static persist **', $this->definition->get_id());
-            }
             if (!is_scalar($result)) {
                 // If data is an object it will be a reference.
                 // If data is an array if may contain references.
@@ -285,8 +288,6 @@ class cache implements cache_loader {
                 $result = $this->unref($result);
             }
             return $result;
-        } else if ($this->perfdebug) {
-            cache_helper::record_cache_miss('** static persist **', $this->definition->get_id());
         }
         // 3. Get it from the store. Obviously wasn't in the persist cache.
         $result = $this->store->get($parsedkey);
@@ -906,23 +907,34 @@ class cache implements cache_loader {
             $key = $key['key'];
         }
         if (!$this->persist || !array_key_exists($key, $this->persistcache)) {
-            return false;
-        }
-        $data = $this->persistcache[$key];
-        if (!$this->has_a_ttl() || !$data instanceof cache_ttl_wrapper) {
-            if ($data instanceof cache_cached_object) {
-                $data = $data->restore_object();
+            $result = false;
+        } else {
+            $data = $this->persistcache[$key];
+            if (!$this->has_a_ttl() || !$data instanceof cache_ttl_wrapper) {
+                if ($data instanceof cache_cached_object) {
+                    $data = $data->restore_object();
+                }
+                $result = $data;
+            } else if ($data->has_expired()) {
+                $this->delete_from_persist_cache($key);
+                $result = false;
+            } else {
+                if ($data instanceof cache_cached_object) {
+                    $data = $data->restore_object();
+                }
+                $result = $data->data;
             }
-            return $data;
         }
-        if ($data->has_expired()) {
-            $this->delete_from_persist_cache($key);
-            return false;
+        if ($result) {
+            if ($this->perfdebug) {
+                cache_helper::record_cache_hit('** static persist **', $this->definition->get_id());
+            }
+            return $result;
         } else {
-            if ($data instanceof cache_cached_object) {
-                $data = $data->restore_object();
+            if ($this->perfdebug) {
+                cache_helper::record_cache_miss('** static persist **', $this->definition->get_id());
             }
-            return $data->data;
+            return false;
         }
     }
 
index 0a18b3a..19fdfb6 100644 (file)
@@ -373,9 +373,13 @@ class cachestore_file implements cache_store, cache_is_key_aware {
     public function delete($key) {
         $filename = $key.'.cache';
         $file = $this->file_path_for_key($key);
-        $result = @unlink($file);
-        unset($this->keys[$filename]);
-        return $result;
+
+        if (@unlink($file)) {
+            unset($this->keys[$filename]);
+            return true;
+        }
+
+        return false;
     }
 
     /**
@@ -682,4 +686,4 @@ class cachestore_file implements cache_store, cache_is_key_aware {
     public function my_name() {
         return $this->name;
     }
-}
\ No newline at end of file
+}
index dc273ca..2d22751 100644 (file)
@@ -47,9 +47,9 @@ $sessiontable = clone($applicationtable);
 $requesttable = clone($applicationtable);
 
 
-$application = cache_definition::load_adhoc(cache_store::MODE_APPLICATION, 'cache', 'applicationtest', null, false);
-$session = cache_definition::load_adhoc(cache_store::MODE_SESSION, 'cache', 'sessiontest', null, false);
-$request = cache_definition::load_adhoc(cache_store::MODE_REQUEST, 'cache', 'requesttest', null, false);
+$application = cache_definition::load_adhoc(cache_store::MODE_APPLICATION, 'cache', 'applicationtest');
+$session = cache_definition::load_adhoc(cache_store::MODE_SESSION, 'cache', 'sessiontest');
+$request = cache_definition::load_adhoc(cache_store::MODE_REQUEST, 'cache', 'requesttest');
 
 $strinvalidplugin = new lang_string('invalidplugin', 'cache');
 $strunsupportedmode = new lang_string('unsupportedmode', 'cache');
index ba467e2..3e6ba79 100644 (file)
@@ -422,4 +422,53 @@ class cache_administration_helper_phpunit_tests extends advanced_testcase {
             $this->assertInstanceOf('coding_exception', $e);
         }
     }
-}
\ No newline at end of file
+
+    /**
+     * Test the hash_key functionality.
+     */
+    public function test_hash_key() {
+        global $CFG;
+
+        $currentdebugging = $CFG->debug;
+
+        $CFG->debug = E_ALL;
+
+        // First with simplekeys
+        $instance = cache_config_phpunittest::instance(true);
+        $instance->phpunit_add_definition('phpunit/hashtest', array(
+            'mode' => cache_store::MODE_APPLICATION,
+            'component' => 'phpunit',
+            'area' => 'hashtest',
+            'simplekeys' => true
+        ));
+        $factory = cache_factory::instance();
+        $definition = $factory->create_definition('phpunit', 'hashtest');
+
+        $result = cache_helper::hash_key('test', $definition);
+        $this->assertEquals('test-'.$definition->generate_single_key_prefix(), $result);
+
+        try {
+            cache_helper::hash_key('test/test', $definition);
+            $this->fail('Invalid key was allowed, you should see this.');
+        } catch (coding_exception $e) {
+            $this->assertEquals('test/test', $e->debuginfo);
+        }
+
+        // Second without simple keys
+        $instance->phpunit_add_definition('phpunit/hashtest2', array(
+            'mode' => cache_store::MODE_APPLICATION,
+            'component' => 'phpunit',
+            'area' => 'hashtest2',
+            'simplekeys' => false
+        ));
+        $definition = $factory->create_definition('phpunit', 'hashtest2');
+
+        $result = cache_helper::hash_key('test', $definition);
+        $this->assertEquals(sha1($definition->generate_single_key_prefix().'-test'), $result);
+
+        $result = cache_helper::hash_key('test/test', $definition);
+        $this->assertEquals(sha1($definition->generate_single_key_prefix().'-test/test'), $result);
+
+        $CFG->debug = $currentdebugging;
+    }
+}
index 698f403..02f541b 100644 (file)
@@ -1465,6 +1465,11 @@ function calendar_edit_event_allowed($event) {
         return false;
     }
 
+    // You cannot edit calendar subscription events presently.
+    if (!empty($event->subscriptionid)) {
+        return false;
+    }
+
     $sitecontext = context_system::instance();
     // if user has manageentries at site level, return true
     if (has_capability('moodle/calendar:manageentries', $sitecontext)) {
@@ -2868,8 +2873,10 @@ function calendar_get_icalendar($url) {
     require_once($CFG->libdir.'/filelib.php');
 
     $curl = new curl();
+    $curl->setopt(array('CURLOPT_FOLLOWLOCATION' => 1, 'CURLOPT_MAXREDIRS' => 5));
     $calendar = $curl->get($url);
-    if (!$calendar) {
+    // Http code validation should actually be the job of curl class.
+    if (!$calendar || $curl->info['http_code'] != 200 || !empty($curl->errorno)) {
         throw new moodle_exception('errorinvalidicalurl', 'calendar');
     }
 
index 6488847..fcd7979 100644 (file)
@@ -123,6 +123,7 @@ class calendar_addsubscription_form extends moodleform {
         $mform =& $this->_form;
 
         $mform->applyFilter('url', 'calendar_addsubscription_form::strip_webcal');
+        $mform->applyFilter('url', 'trim');
     }
 
     /**
index e363e41..43b1132 100644 (file)
@@ -368,7 +368,7 @@ if (!$courses) {
             // role assignment link
             if (has_capability('moodle/course:enrolreview', $coursecontext)) {
                 $url = new moodle_url('/enrol/users.php', array('id' => $acourse->id));
-                echo $OUTPUT->action_icon($url, new pix_icon('i/users', get_string('enrolledusers', 'enrol')));
+                echo $OUTPUT->action_icon($url, new pix_icon('t/enrolusers', get_string('enrolledusers', 'enrol')));
             }
 
             if (can_delete_course($acourse->id)) {
index 209e280..a1a5e56 100644 (file)
@@ -340,7 +340,7 @@ function print_category_edit($category, $displaylist, $parentslist, $depth=-1, $
 
             if (has_capability('moodle/cohort:manage', $category->context) or has_capability('moodle/cohort:view', $category->context)) {
                 echo '<a title="'.$str->cohorts.'" href="'.$CFG->wwwroot.'/cohort/index.php?contextid='.$category->context->id.'"><img'.
-                     ' src="'.$OUTPUT->pix_url('i/cohort') . '" class="iconsmall" alt="'.$str->cohorts.'" /></a> ';
+                     ' src="'.$OUTPUT->pix_url('t/cohort') . '" class="iconsmall" alt="'.$str->cohorts.'" /></a> ';
             }
 
             if ($up) {
index 8626b42..7d2ed99 100644 (file)
@@ -1252,6 +1252,7 @@ function get_module_types_names($plural = false) {
 function course_set_marker($courseid, $marker) {
     global $DB;
     $DB->set_field("course", "marker", $marker, array('id' => $courseid));
+    format_base::reset_course_cache($courseid);
 }
 
 /**
index 8c9f85c..393ab0b 100644 (file)
@@ -336,7 +336,7 @@ if ($courses) {
             // checks whether user can do role assignment
             if (has_capability('moodle/course:enrolreview', $coursecontext)) {
                 echo'<a title="'.get_string('enrolledusers', 'enrol').'" href="'.$CFG->wwwroot.'/enrol/users.php?id='.$course->id.'">';
-                echo '<img src="'.$OUTPUT->pix_url('i/users') . '" class="iconsmall" alt="'.get_string('enrolledusers', 'enrol').'" /></a> ' . "\n";
+                echo '<img src="'.$OUTPUT->pix_url('i/enrolusers') . '" class="iconsmall" alt="'.get_string('enrolledusers', 'enrol').'" /></a> ' . "\n";
             }
 
             // checks whether user can delete course
index ee17fa9..94b89dc 100644 (file)
@@ -113,7 +113,7 @@ class enrol_manual_plugin extends enrol_plugin {
 
         if (has_capability('enrol/manual:manage', $context)) {
             $managelink = new moodle_url("/enrol/manual/manage.php", array('enrolid'=>$instance->id));
-            $icons[] = $OUTPUT->action_icon($managelink, new pix_icon('i/users', get_string('enrolusers', 'enrol_manual'), 'core', array('class'=>'iconsmall')));
+            $icons[] = $OUTPUT->action_icon($managelink, new pix_icon('t/enrolusers', get_string('enrolusers', 'enrol_manual'), 'core', array('class'=>'iconsmall')));
         }
         if (has_capability('enrol/manual:config', $context)) {
             $editlink = new moodle_url("/enrol/manual/edit.php", array('courseid'=>$instance->courseid));
index a26537b..36e493e 100644 (file)
@@ -107,7 +107,7 @@ grade_regrade_final_grades($courseid);
 
 // Perform actions
 if (!empty($target) && !empty($action) && confirm_sesskey()) {
-    grade_report_grader::process_action($target, $action);
+    grade_report_grader::do_process_action($target, $action);
 }
 
 $reportname = get_string('pluginname', 'gradereport_grader');
index fccb042..2f9d0d4 100644 (file)
@@ -1584,13 +1584,17 @@ class grade_report_grader extends grade_report {
         return $icon;
     }
 
+    public function process_action($target, $action) {
+        return self::do_process_action($target, $action);
+    }
+
     /**
      * Processes a single action against a category, grade_item or grade.
      * @param string $target eid ({type}{id}, e.g. c4 for category4)
      * @param string $action Which action to take (edit, delete etc...)
      * @return
      */
-    public function process_action($target, $action) {
+    public static function do_process_action($target, $action) {
         // TODO: this code should be in some grade_tree static method
         $targettype = substr($target, 0, 1);
         $targetid = substr($target, 1);
diff --git a/install/lang/en_fix/langconfig.php b/install/lang/en_fix/langconfig.php
deleted file mode 100644 (file)
index d563203..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-<?php
-
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * Automatically generated strings for Moodle installer
- *
- * Do not edit this file manually! It contains just a subset of strings
- * needed during the very first steps of installation. This file was
- * generated automatically by export-installer.php (which is part of AMOS
- * {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
- * list of strings defined in /install/stringnames.txt.
- *
- * @package   installer
- * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-defined('MOODLE_INTERNAL') || die();
-
-$string['thislanguage'] = 'English (fixes)';
index 62aec64..17b22ef 100644 (file)
@@ -31,6 +31,6 @@
 defined('MOODLE_INTERNAL') || die();
 
 $string['language'] = 'Jezik';
-$string['next'] = 'Nastavi';
+$string['next'] = 'Nastavite';
 $string['previous'] = 'Prethodni';
 $string['reload'] = 'Učitaj ponovno';
diff --git a/install/lang/lt/install.php b/install/lang/lt/install.php
new file mode 100644 (file)
index 0000000..cf54d95
--- /dev/null
@@ -0,0 +1,99 @@
+<?php
+
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Automatically generated strings for Moodle installer
+ *
+ * Do not edit this file manually! It contains just a subset of strings
+ * needed during the very first steps of installation. This file was
+ * generated automatically by export-installer.php (which is part of AMOS
+ * {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
+ * list of strings defined in /install/stringnames.txt.
+ *
+ * @package   installer
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+$string['admindirname'] = 'Administratoriaus aplankas';
+$string['availablelangs'] = 'Galimų kalbų sąrašas';
+$string['chooselanguagehead'] = 'Pasirinkite kalbą';
+$string['chooselanguagesub'] = 'Prašome pasirinkti diegimo kalbą. Ši kalba taip pat taps numatytąją svetainės kalba. Tačiau vėliau, jei norėsite, Jūs galėsite ją pakeisti.';
+$string['clialreadyconfigured'] = 'config.php failas jau egzistuoja. Prašome naudotis admin/cli/install_database.php, jei Jūs norite įdiegti šią svetainę.';
+$string['clialreadyinstalled'] = 'config.php failas jau egzistuoja. Prašome naudoti admin/cli/upgrade.php jei Jūs norite išplėtoti šią svetainę.';
+$string['cliinstallheader'] = '"Moodle" {$a} komandinės eilutės įdiegimo programa';
+$string['databasehost'] = 'Duomenų bazės serveris';
+$string['databasename'] = 'Duomenų bazės pavadinimas';
+$string['databasetypehead'] = 'Pasirinkite duomenų bazės tvarkyklę';
+$string['dataroot'] = 'Duomenų aplankas';
+$string['datarootpermission'] = 'Duomenų aplanko leidimai';
+$string['dbprefix'] = 'Lentelių priešdėlis';
+$string['dirroot'] = '"Moodle" aplankas';
+$string['environmenthead'] = 'Tikrinama Jūsų aplinka...';
+$string['environmentsub2'] = 'Kiekviena "Moodle" laida turi kai kuriuos minimalius reikalavimus PHP versijai ir tam tikrą privalomų PHP plėtinių skaičių.
+Pilnas aplinkos patikrinimas yra padaromas prieš kiekvieną įdiegimą ar plėtotę. Prašome susisiekti su serverio administratoriumi, jeigu Jūs nežinote kaip įdiegti naują versiją ar įgalinti PHP plėtinius.';
+$string['errorsinenvironment'] = 'Aplinkos patikrinimas nesėkmingas!';
+$string['installation'] = 'Įdiegimas';
+$string['langdownloaderror'] = 'Deja "{$a}" kalba negali būti parsiųsta. Diegimo procesas bus tęsiamas anglų kalba.';
+$string['memorylimithelp'] = '<p>Šiuo metu Jūsų serverio PHP atminties limitas yra {$a}.</p>
+
+<p>Vėliau tai gali sukelti atminties trūkumo problemų "Moodle", ypač jei Jūs turite daug įgalintų modulių ir/ar daug vartotojų.</p>
+
+<p>Mes rekomenduojame suderinti PHP taip, kad jis turėtų kiek galima didesnį limitą, pvz.: 40MB.
+ Tam yra keletas būdų, kuriuos Jūs galite pabandyti:</p>
+<ol>
+<li>Jei Jūs galite, sukompiliuokite iš naujo PHP panaudodami <i>--enable-memory-limit</i> raktą.
+   Tai leis nustatyti atminties limitą pačiai "Moodle".</li>
+<li>Jei Jūs turite galimybę koreguoti Jūsų "php.ini" failą, tada pakeiskite <b>memory_limit</b> nuostatą į kažką artimo 40MB. Jei Jūs negalite koreguoti, tuomet gal galite paprašyti, kad Jūsų serverio administratorius tai padarytų už Jus.</li>
+<li>Kai kuriuose PHP serveriuose Jūs galite sukurti ".htaccess" failą "Moodle" aplanke ir įrašykite į jį šią eilutę:
+<blockquote><div>php_value memory_limit 40M</div></blockquote>
+<p>Tačiau kai kuriuose serveriuose tai neleis veikti <b>visiems</b> PHP puslapiams (Jūs matysite klaidas bandydami peržiūrėti tinklapius). Taigi Jums gali tekti pašalinti ".htaccess" failą.</p></li>
+</ol>';
+$string['paths'] = 'Keliai';
+$string['pathserrcreatedataroot'] = 'Diegiklis negali sukurti duomenų katalogo ({$a->dataroot}).';
+$string['pathshead'] = 'Patvirtinkite kelius';
+$string['pathsrodataroot'] = 'Dataroot katalogas yra neįrašomas';
+$string['pathsroparentdataroot'] = 'Virškatalogis ({$a->parent}) yra neįrašomas. Diegiklis negali sukurti duomenų katalogo ({$a->dataroot}).';
+$string['pathssubadmindir'] = 'Nedaugelis interneto paslaugų tiekėjų naudoja /admin kaip specialų URL skirtą prisijungti prie valdymo skydo ar panašiai. Deja tai kelia konfliktus su įprastais Moodle administravimo puslapių talpinimo keliais. Jūs galite tai pataisyti
+pervardydami admin katalogą Jūsų diegime bei įrašydami naują pavadinimą čia. Pavyzdžiui: <em>moodleadmin</em>. Tai pakeis visas admin nuorodas Moodle diegime.';
+$string['pathssubdataroot'] = 'Jums reikia vietos kur Moodle gali išsaugoti įkeliamus failus. Šis katalogas turi būti skaitomas IR ĮRAŠOMAS web serverio naudotojo
+(dažniausiai tai \'nobody\' arba \'apache\'), tačiau jis neturi būti pasiekiamas tiesiogiai per internetą. Diegiklis pabandys sukurti katalogą, jei tokio nėra.';
+$string['pathssubdirroot'] = 'Pilnas kelias iki Moodle diegimo vietos.';
+$string['pathssubwwwroot'] = 'Pilnas internetinis adresas, kuriuo bus pasiekiamas Moodle.
+Pasiekti Moodle naudojantis keliais adresais yra neįmanoma.
+Jei Jūsų svetainėje yra keletas viešų adresų, Jūs turite visuose adresuose nustatyti pastovų peradresavimą į šį adresą.
+Jei Jūsų svetainė yra pasiekiama ir iš Intraneto, ir iš Interneto - panaudokite viešą adresą čia ir nustatykite DNS taip, kad Intraneto naudotojai taip pat galėtų matyti viešą adresą.
+Jei adresas neteisingas - prašome pakeisti URL Jūsų naršyklėje ir pradėti diegimą su nauju adresu.';
+$string['pathsunsecuredataroot'] = 'Dataroot katalogo vieta yra nesaugi.';
+$string['pathswrongadmindir'] = 'Admin katalogas neegzistuoja';
+$string['phpextension'] = '{$a} PHP plėtinys';
+$string['phpversion'] = 'PHP versija';
+$string['phpversionhelp'] = '<p>Moodle reikalauja, kad būtų įdiegta bent 4.3.0 arba 5.1.0 PHP versija (5.0.x versija turi keletą žymių problemų).
+</p>
+<p>Jūs šiuo metu naudojate {$a} versiją</p>
+<p>Jūs turite išplėtoti turimą PHP versiją iki naujesnės arba persikelti pas kitą interneto paslaugų tiekėją, turintį naujesnę PHP versiją!<br/>
+(Turint 5.0.x versiją, Jūs turėtumėte pereiti prie žemesnės 4.4.x versijos)</p>';
+$string['welcomep10'] = '{$a->installername} ({$a->installerversion})';
+$string['welcomep20'] = 'Jūs matote šį puslapį, nes sėkmingai įdiegėte ir užkrovėte <strong>{$a->packname} {$a->packversion}</strong> paketą savo kompiuteryje.
+Sveikiname!';
+$string['welcomep30'] = 'Šis <strong>{$a->installername}</strong> leidimas turi programas skirtas sukurti aplinką, kurioje <strong>Moodle</strong> veiks. Būtent:';
+$string['welcomep40'] = 'Šis paketas taip pat turi  <strong>Moodle {$a->moodlerelease} ({$a->moodleversion})</strong>.';
+$string['welcomep50'] = 'Pakete esančių programų naudojimas yra reguliuojamas atitinkamų licencijų. Pilnas <strong>{$a->installername}</strong> paketas  yra <a href="http://www.opensource.org/docs/definition_plain.html">atviro kodo</a> ir platinamas remiantis <a href="http://www.gnu.org/copyleft/gpl.html">GPL</a> licencija.';
+$string['welcomep60'] = 'Sekantys puslapiai ves Jus per keletą lengvų žingsnių, kurie padės sukonfigūruoti ir nustatyti <strong>Moodle</strong> Jūsų kompiuteryje. Jūs galite priimti nustatymus pagal nutylėjimą arba, pasirinktinai, pakeisti juos pagal savo poreikius.';
+$string['welcomep70'] = 'Spauskite "Toliau" mygtuką, norėdami tęsti <strong>Moodle</strong> nustatymą.';
+$string['wwwroot'] = 'Interneto adresas';
index fc2df44..65c3046 100644 (file)
@@ -1465,6 +1465,14 @@ function xmldb_main_upgrade($oldversion) {
         upgrade_main_savepoint(true, 2012111200.00);
     }
 
+    if ($oldversion < 2012111200.01) {
+        // Force the rebuild of the cache of every courses, some cached information could contain wrong icon references.
+        rebuild_course_cache();
+
+        // Main savepoint reached.
+        upgrade_main_savepoint(true, 2012111200.01);
+    }
+
 
     return true;
 }
index 835a07a..6295a10 100644 (file)
@@ -401,7 +401,7 @@ function enrol_add_course_navigation(navigation_node $coursenode, $course) {
         // list all participants - allows assigning roles, groups, etc.
         if (has_capability('moodle/course:enrolreview', $coursecontext)) {
             $url = new moodle_url('/enrol/users.php', array('id'=>$course->id));
-            $usersnode->add(get_string('enrolledusers', 'enrol'), $url, navigation_node::TYPE_SETTING, null, 'review', new pix_icon('i/users', ''));
+            $usersnode->add(get_string('enrolledusers', 'enrol'), $url, navigation_node::TYPE_SETTING, null, 'review', new pix_icon('i/enrolusers', ''));
         }
 
         // manage enrol plugin instances
index f9fe137..4b1307e 100644 (file)
@@ -81,11 +81,19 @@ class google_docs {
         if ($search) {
             $url.='?q='.urlencode($search);
         }
-        $content = $this->googleoauth->get($url);
-
-        $xml = new SimpleXMLElement($content);
 
         $files = array();
+        $content = $this->googleoauth->get($url);
+        try {
+            if (strpos($content, '<?xml') !== 0) {
+                throw new moodle_exception('invalidxmlresponse');
+            }
+            $xml = new SimpleXMLElement($content);
+        } catch (Exception $e) {
+            // An error occured while trying to parse the XML, let's just return nothing. SimpleXML does not
+            // return a more specific Exception, that's why the global Exception class is caught here.
+            return $files;
+        }
         foreach ($xml->entry as $gdoc) {
             $docid  = (string) $gdoc->children('http://schemas.google.com/g/2005')->resourceId;
             list($type, $docid) = explode(':', $docid);
@@ -320,11 +328,17 @@ class google_picasa {
         $files = array();
         $content = $this->googleoauth->get(self::LIST_ALBUMS_URL);
 
-        if (empty($content)) {
+        try {
+            if (strpos($content, '<?xml') !== 0) {
+                throw new moodle_exception('invalidxmlresponse');
+            }
+            $xml = new SimpleXMLElement($content);
+        } catch (Exception $e) {
+            // An error occured while trying to parse the XML, let's just return nothing. SimpleXML does not
+            // return a more specific Exception, that's why the global Exception class is caught here.
             return $files;
         }
 
-        $xml = new SimpleXMLElement($content);
         foreach ($xml->entry as $album) {
             $gphoto = $album->children('http://schemas.google.com/photos/2007');
 
@@ -355,11 +369,17 @@ class google_picasa {
      */
     public function get_photo_details($rawxml) {
         $files = array();
-        if (empty($rawxml)) {
+
+        try {
+            if (strpos($rawxml, '<?xml') !== 0) {
+                throw new moodle_exception('invalidxmlresponse');
+            }
+            $xml = new SimpleXMLElement($rawxml);
+        } catch (Exception $e) {
+            // An error occured while trying to parse the XML, let's just return nothing. SimpleXML does not
+            // return a more specific Exception, that's why the global Exception class is caught here.
             return $files;
         }
-
-        $xml = new SimpleXMLElement($rawxml);
         $this->lastalbumname = (string)$xml->title;
 
         foreach ($xml->entry as $photo) {
index 77e9883..7279079 100644 (file)
@@ -6490,7 +6490,11 @@ class core_string_manager implements string_manager {
             $this->cache = cache::make('core', 'string');
         } else {
             // We only want a cache for the length of the request, create a static cache.
-            $this->cache = cache::make_from_params(cache_store::MODE_REQUEST, 'core', 'string');
+            $options = array(
+                'simplekeys' => true,
+                'simpledata' => true
+            );
+            $this->cache = cache::make_from_params(cache_store::MODE_REQUEST, 'core', 'string', array(), $options);
         }
     }
 
index e8357c9..da1761b 100644 (file)
@@ -1126,6 +1126,9 @@ class theme_config {
                 } else if (preg_match('#Android +[0-2]\.#', $_SERVER['HTTP_USER_AGENT'])) {
                     // Android < 3 doesn't support SVG. Say no.
                     $this->usesvg = false;
+                } else if (check_browser_version('Opera', 0)) {
+                    // Opera 12 still does not support SVG well enough. Say no.
+                    $this->usesvg = false;
                 } else {
                     // Presumed fine.
                     $this->usesvg = true;
index 8fd97b6..ee3e8bc 100644 (file)
@@ -208,7 +208,7 @@ class theme_config_testcase extends advanced_testcase {
             // Firefox 15 on Ubuntu.
             'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:15.0) Gecko/20100101 Firefox/15.0.1' => true,
             // Opera 12.02 on Ubuntu.
-            'Opera/9.80 (X11; Linux x86_64; U; en) Presto/2.10.289 Version/12.02' => true,
+            'Opera/9.80 (X11; Linux x86_64; U; en) Presto/2.10.289 Version/12.02' => false,
             // Android browser pre 1.0
             'Mozilla/5.0 (Linux; U; Android 0.5; en-us) AppleWebKit/522+ (KHTML, like Gecko) Safari/419.3' => false,
             // Android browser 2.3 (HTC)
index f1027ba..9bbf4f5 100644 (file)
@@ -241,6 +241,7 @@ function lesson_save_question_options($question, $lesson) {
             // The first answer should always be the correct answer
             $correctanswer = clone($defaultanswer);
             $correctanswer->answer = get_string('thatsthecorrectanswer', 'lesson');
+            $correctanswer->jumpto = LESSON_NEXTPAGE;
             $DB->insert_record("lesson_answers", $correctanswer);
 
             // The second answer should always be the wrong answer
diff --git a/pix/i/cohort.png b/pix/i/cohort.png
new file mode 100644 (file)
index 0000000..d9c15bd
Binary files /dev/null and b/pix/i/cohort.png differ
diff --git a/pix/i/cohort.svg b/pix/i/cohort.svg
new file mode 100644 (file)
index 0000000..c573e94
--- /dev/null
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 15.1.0, SVG Export Plug-In  -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [\r
+       <!ENTITY ns_flows "http://ns.adobe.com/Flows/1.0/">\r
+]>\r
+<svg version="1.1"\r
+        xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"\r
+        x="0px" y="0px" width="16px" height="16px" viewBox="0 0 16 16" style="overflow:visible;enable-background:new 0 0 16 16;"\r
+        xml:space="preserve">\r
+<defs>\r
+</defs>\r
+<path style="fill:#999999;" d="M8,4c1.6,0,2.9,1.7,2.9,3.8c0,1.4-0.9,2.5-0.9,2.5c-0.3,0.4-0.2,1,0.3,1.2l3.6,1.7\r
+       c0.5,0.3,1.1,0.9,1.1,1.5V16H1v-1.2c0-0.5,0.6-1.2,1.1-1.5l3.6-1.8c0.5-0.3,0.6-0.8,0.3-1.3c0,0-0.9-1.1-0.9-2.5C5.1,5.7,6.4,4,8,4z\r
+        M11.9,7.8c0,1.1-0.4,2.1-0.4,2.1c-0.2,0.5,0,1.1,0.5,1.4l1.5,0.7H16V8.4l-1.7-0.8c-0.5-0.3-0.6-0.8-0.3-1.2c0,0,0.9-1.1,0.9-2.5\r
+       C14.9,1.7,13.6,0,12,0c-1.5,0-2.6,1.4-2.8,3.2C10.7,3.9,11.9,5.6,11.9,7.8z M1.7,7.6L0,8.4V12h2.6L4,11.3c0.5-0.3,0.8-0.9,0.5-1.4\r
+       c0,0-0.4-1-0.4-2.1c0-2.1,1.2-3.9,2.8-4.6C6.6,1.4,5.5,0,4,0C2.4,0,1.1,1.7,1.1,3.8C1.1,5.2,2,6.3,2,6.3C2.3,6.7,2.2,7.3,1.7,7.6z"\r
+       />\r
+</svg>\r
diff --git a/pix/i/enrolusers.png b/pix/i/enrolusers.png
new file mode 100644 (file)
index 0000000..23d7832
Binary files /dev/null and b/pix/i/enrolusers.png differ
diff --git a/pix/i/enrolusers.svg b/pix/i/enrolusers.svg
new file mode 100644 (file)
index 0000000..28ce5f4
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 15.1.0, SVG Export Plug-In  -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [\r
+       <!ENTITY ns_flows "http://ns.adobe.com/Flows/1.0/">\r
+]>\r
+<svg version="1.1"\r
+        xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"\r
+        x="0px" y="0px" width="16px" height="16px" viewBox="0 0 16 16" style="overflow:visible;enable-background:new 0 0 16 16;"\r
+        xml:space="preserve">\r
+<defs>\r
+</defs>\r
+<path style="fill:#999999;" d="M16,11.9V16h-4.6l-0.9-3.6l0.6-0.6L10.3,11H9.7l-0.8,0.9l0.6,0.6L8.6,16H4v-4l3.2-1.7\r
+       C7.7,10,7.8,9.5,7.5,9C7.5,9,6,7.2,6,5.2C6,2.3,7.8,0,10,0s4,2.3,4,5.2c0,2-1.4,3.8-1.4,3.8c-0.3,0.4-0.2,1,0.3,1.2L16,11.9z\r
+        M6.1,8.7C5.6,7.9,5,6.9,5,5.2c0-2.1,0.8-3.9,2-5C6.7,0.1,6.4,0,6,0C3.8,0,2,2.3,2,5.2C2,7.2,3.4,9,3.4,9c0.3,0.4,0.2,1-0.3,1.3\r
+       L0,12v4h3v-4.6c0,0,2.6-1.3,2.8-1.4C6.2,9.7,6.6,9.6,6.1,8.7z"/>\r
+</svg>\r
diff --git a/pix/i/permissions.png b/pix/i/permissions.png
new file mode 100644 (file)
index 0000000..7c1c8ec
Binary files /dev/null and b/pix/i/permissions.png differ
diff --git a/pix/i/permissions.svg b/pix/i/permissions.svg
new file mode 100644 (file)
index 0000000..935d811
--- /dev/null
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 15.1.0, SVG Export Plug-In  -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [\r
+       <!ENTITY ns_flows "http://ns.adobe.com/Flows/1.0/">\r
+]>\r
+<svg version="1.1"\r
+        xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"\r
+        x="0px" y="0px" width="16px" height="16px" viewBox="0 0 16 16" style="overflow:visible;enable-background:new 0 0 16 16;"\r
+        xml:space="preserve">\r
+<defs>\r
+</defs>\r
+<path style="fill:#999999;" d="M11,0C8.3,0,6,2.2,6,5c0,0.4,0.1,0.9,0.2,1.3L0,12.5v2.1l6.9-6.9C6.9,7.8,7,7.9,7,8l-7,7v1h2v-1h2v-2\r
+       h2h0v-2h2l1.3-1.3C9.9,9.8,10.4,10,11,10c2.8,0,5-2.2,5-5S13.8,0,11,0z M12.5,2C13.3,2,14,2.7,14,3.5S13.3,5,12.5,5S11,4.3,11,3.5\r
+       S11.7,2,12.5,2z"/>\r
+</svg>\r
diff --git a/pix/i/rss.png b/pix/i/rss.png
new file mode 100644 (file)
index 0000000..9835e38
Binary files /dev/null and b/pix/i/rss.png differ
diff --git a/pix/i/rss.svg b/pix/i/rss.svg
new file mode 100644 (file)
index 0000000..99cf4d2
--- /dev/null
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 15.1.0, SVG Export Plug-In  -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [\r
+       <!ENTITY ns_flows "http://ns.adobe.com/Flows/1.0/">\r
+]>\r
+<svg version="1.1"\r
+        xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"\r
+        x="0px" y="0px" width="16px" height="16px" viewBox="0 0 16 16" style="overflow:visible;enable-background:new 0 0 16 16;"\r
+        xml:space="preserve">\r
+<defs>\r
+</defs>\r
+<path style="fill:#999999;" d="M0,0.1C0.3,0,0.7,0,1,0c8.2,0,15,6.7,15,15c0,0.3,0,0.7-0.1,1h-3c0-0.3,0.1-0.7,0.1-1\r
+       C13,8.4,7.6,3,1,3C0.7,3,0.3,3,0,3.1V0.1z M2.5,11c-1.3,0-2.4,1-2.5,2.3v0.5c0.1,1.2,1,2.1,2.2,2.2h0.5C4,15.8,5,14.8,5,13.5\r
+       C5,12.1,3.9,11,2.5,11z M0,5v3c4.4,0,8,3.6,8,8h3C11,9.9,6.1,5,0,5z"/>\r
+</svg>\r
index 23d7832..393371b 100644 (file)
Binary files a/pix/i/users.png and b/pix/i/users.png differ
index 28ce5f4..837e63d 100644 (file)
@@ -9,8 +9,8 @@
         xml:space="preserve">\r
 <defs>\r
 </defs>\r
-<path style="fill:#999999;" d="M16,11.9V16h-4.6l-0.9-3.6l0.6-0.6L10.3,11H9.7l-0.8,0.9l0.6,0.6L8.6,16H4v-4l3.2-1.7\r
-       C7.7,10,7.8,9.5,7.5,9C7.5,9,6,7.2,6,5.2C6,2.3,7.8,0,10,0s4,2.3,4,5.2c0,2-1.4,3.8-1.4,3.8c-0.3,0.4-0.2,1,0.3,1.2L16,11.9z\r
-        M6.1,8.7C5.6,7.9,5,6.9,5,5.2c0-2.1,0.8-3.9,2-5C6.7,0.1,6.4,0,6,0C3.8,0,2,2.3,2,5.2C2,7.2,3.4,9,3.4,9c0.3,0.4,0.2,1-0.3,1.3\r
-       L0,12v4h3v-4.6c0,0,2.6-1.3,2.8-1.4C6.2,9.7,6.6,9.6,6.1,8.7z"/>\r
+<path style="fill:#999999;" d="M3,16H0v-4l3.2-1.7C3.6,10,3.8,9.5,3.4,9C3.4,9,2,7.2,2,5.2C2,2.3,3.8,0,6,0c0.4,0,0.7,0.1,1.1,0.2\r
+       c-1.2,1.1-2,3-2,5c0,1.7,0.6,2.7,1,3.5c0.6,0.9,0.1,1-0.3,1.3C5.6,10.1,3,11.4,3,11.4V16z M16,11.9l-3.1-1.6\r
+       C12.4,10,12.3,9.4,12.6,9c0,0,1.4-1.8,1.4-3.8C14,2.3,12.2,0,10,0S6,2.3,6,5.2C6,7.2,7.5,9,7.5,9c0.3,0.4,0.2,1-0.3,1.3L4,12v4h12\r
+       V11.9z"/>\r
 </svg>\r
index e0fd2e1..2e5c33b 100644 (file)
Binary files a/pix/i/withsubcat.png and b/pix/i/withsubcat.png differ
diff --git a/pix/i/withsubcat.svg b/pix/i/withsubcat.svg
new file mode 100644 (file)
index 0000000..86ff2ef
--- /dev/null
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 15.1.0, SVG Export Plug-In  -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [\r
+       <!ENTITY ns_flows "http://ns.adobe.com/Flows/1.0/">\r
+]>\r
+<svg version="1.1"\r
+        xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"\r
+        x="0px" y="0px" width="16px" height="16px" viewBox="0 0 16 16" style="overflow:visible;enable-background:new 0 0 16 16;"\r
+        xml:space="preserve">\r
+<defs>\r
+</defs>\r
+<polygon style="fill:#999999;" points="16,10 16,6 5,6 5,7 3,7 3,4 13,4 13,0 0,0 0,4 2,4 2,7 2,8 2,13 2,14 3,14 5,14 5,16 16,16 \r
+       16,12 5,12 5,13 3,13 3,8 5,8 5,10 "/>\r
+</svg>\r
diff --git a/pix/t/backup.png b/pix/t/backup.png
new file mode 100644 (file)
index 0000000..27fb529
Binary files /dev/null and b/pix/t/backup.png differ
diff --git a/pix/t/backup.svg b/pix/t/backup.svg
new file mode 100644 (file)
index 0000000..4513122
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 15.1.0, SVG Export Plug-In  -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [\r
+       <!ENTITY ns_flows "http://ns.adobe.com/Flows/1.0/">\r
+]>\r
+<svg version="1.1"\r
+        xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"\r
+        x="0px" y="0px" width="12px" height="12px" viewBox="0 0 12 12" style="overflow:visible;enable-background:new 0 0 12 12;"\r
+        xml:space="preserve">\r
+<defs>\r
+</defs>\r
+<path style="fill:#999999;" d="M12,7v4c0,0.5-0.5,1-1,1h-0.5l0,0H1c-0.5,0-1-0.5-1-1V7c0-0.5,0.5-1,1-1h0.5c0.5,0,1,0.5,1,1l0,2.5h7\r
+       V7c0-0.5,0.5-1,1-1H11C11.5,6,12,6.5,12,7z M9.9,3.6L6.6,0.3C6.4,0.1,6.2,0,5.9,0C5.7,0,5.4,0.1,5.2,0.3L1.9,3.6\r
+       C1.5,4,1.5,4.6,1.9,5l0.3,0.3c0.4,0.4,1,0.4,1.4,0l1-1.1l0,2.7c0,0.5,0.5,1,1,1l0.5,0c0.5,0,1-0.5,1-1l0-2.7l1,1\r
+       c0.4,0.4,1,0.4,1.4,0L10,5C10.3,4.6,10.3,4,9.9,3.6z"/>\r
+</svg>\r
diff --git a/pix/t/cohort.png b/pix/t/cohort.png
new file mode 100644 (file)
index 0000000..77b26b6
Binary files /dev/null and b/pix/t/cohort.png differ
diff --git a/pix/t/cohort.svg b/pix/t/cohort.svg
new file mode 100644 (file)
index 0000000..49b1c74
--- /dev/null
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 15.1.0, SVG Export Plug-In  -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [\r
+       <!ENTITY ns_flows "http://ns.adobe.com/Flows/1.0/">\r
+]>\r
+<svg version="1.1"\r
+        xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"\r
+        x="0px" y="0px" width="12px" height="12px" viewBox="0 0 12 12" style="overflow:visible;enable-background:new 0 0 12 12;"\r
+        xml:space="preserve">\r
+<defs>\r
+</defs>\r
+<path style="fill:#999999;" d="M12,6.4V8H8.9C9,7.8,9.1,7.4,9.1,6.9c0-1.8-1-3.2-2.3-3.7c0-0.1,0-0.2,0-0.3c0-1.6,1-2.9,2.2-2.9\r
+       c1.2,0,2.2,1.3,2.2,2.9c0,1.1-0.5,1.7-0.5,1.7c-0.3,0.4-0.2,1,0.3,1.2L12,6.4z M2.7,6.9c0-1.9,1.1-3.4,2.6-3.8c0-0.1,0-0.1,0-0.2\r
+       c0-1.6-1-2.9-2.2-2.9C1.9,0,0.9,1.3,0.9,2.9c0,1.1,0.5,1.7,0.5,1.7c0.3,0.4,0.2,1-0.3,1.3L0,6.4V8h2.9C2.8,7.8,2.7,7.4,2.7,6.9z\r
+        M10.7,12c-0.1-0.5-0.4-0.9-0.8-1.1L7.8,9.8C7.3,9.5,7.2,9,7.6,8.6c0,0,0.5-0.6,0.5-1.7c0-1.6-1-2.9-2.2-2.9C4.7,4,3.7,5.3,3.7,6.9\r
+       c0,1.1,0.5,1.7,0.5,1.7c0.3,0.4,0.2,1-0.3,1.3l-2.1,1.1C1.5,11.1,1.2,11.6,1,12H10.7z"/>\r
+</svg>\r
diff --git a/pix/t/enrolusers.png b/pix/t/enrolusers.png
new file mode 100644 (file)
index 0000000..4f41e91
Binary files /dev/null and b/pix/t/enrolusers.png differ
diff --git a/pix/t/enrolusers.svg b/pix/t/enrolusers.svg
new file mode 100644 (file)
index 0000000..13fd167
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 15.1.0, SVG Export Plug-In  -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [\r
+       <!ENTITY ns_flows "http://ns.adobe.com/Flows/1.0/">\r
+]>\r
+<svg version="1.1"\r
+        xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"\r
+        x="0px" y="0px" width="12px" height="12px" viewBox="0 0 12 12" style="overflow:visible;enable-background:new 0 0 12 12;"\r
+        xml:space="preserve">\r
+<defs>\r
+</defs>\r
+<path style="fill:#999999;" d="M12,8.4V12H9.2L8.5,9.5l0.6-0.6L8.3,8H7.7L6.9,8.8l0.6,0.6L6.8,12H2v-1.2c0-0.5,0.2-1.2,0.7-1.5\r
+       l3.2-1.8c0.5-0.3,0.6-0.8,0.3-1.3c0,0-0.9-1.1-0.9-2.5C5.2,1.7,6.5,0,8.1,0S11,1.7,11,3.8c0,1.4-0.9,2.5-0.9,2.5\r
+       c-0.3,0.4-0.2,1,0.3,1.2L12,8.4z M4.7,5.9c0,0-0.5-1-0.5-2.1c0-1.3,0.4-2.4,1.1-3.3C4.9,0.2,4.4,0,3.9,0C2.3,0,1,1.7,1,3.8\r
+       c0,1.4,0.9,2.5,0.9,2.5c0.3,0.4,0,1-0.5,1.3L0,8.2V12h1v-1.8C1,9.7,1.2,9,1.7,8.8l2.6-1.5C4.8,7,5,6.4,4.7,5.9z"/>\r
+</svg>\r
diff --git a/pix/t/restore.png b/pix/t/restore.png
new file mode 100644 (file)
index 0000000..86e52f5
Binary files /dev/null and b/pix/t/restore.png differ
diff --git a/pix/t/restore.svg b/pix/t/restore.svg
new file mode 100644 (file)
index 0000000..092073a
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 15.1.0, SVG Export Plug-In  -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [\r
+       <!ENTITY ns_flows "http://ns.adobe.com/Flows/1.0/">\r
+]>\r
+<svg version="1.1"\r
+        xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"\r
+        x="0px" y="0px" width="12px" height="12px" viewBox="0 0 12 12" style="overflow:visible;enable-background:new 0 0 12 12;"\r
+        xml:space="preserve">\r
+<defs>\r
+</defs>\r
+<path style="fill:#999999;" d="M12,7v4c0,0.5-0.5,1-1,1h-0.5l0,0H1c-0.5,0-1-0.5-1-1V7c0-0.5,0.5-1,1-1h0.5c0.5,0,1,0.5,1,1l0,2.5h7\r
+       V7c0-0.5,0.5-1,1-1H11C11.5,6,12,6.4,12,7z M10,3L9.6,2.7c-0.4-0.4-1-0.4-1.4,0l-1,1l0-2.7c0-0.5-0.5-1-1-1L5.7,0c-0.5,0-1,0.5-1,1\r
+       l0,2.7l-1.1-1c-0.4-0.4-1-0.4-1.4,0L1.9,3c-0.4,0.4-0.4,1,0,1.4l3.3,3.3C5.4,7.9,5.7,8,6,8c0.3,0,0.5-0.1,0.7-0.3L10,4.4\r
+       C10.4,4,10.4,3.4,10,3z"/>\r
+</svg>\r
index f524071..908ffb5 100644 (file)
@@ -16,6 +16,8 @@ optional changes:
 * new icons i/export and i/import (sized 16x16). Previously export and import actions used i/backup and i/restore.
 * new icon i/assignroles (sized 16x16), to prevent the use of i/roles which is 12x12.
 * new icon i/switchrole (sized 16x16), was previously using i/roles. Now is a copy of the new i/assignroles icon.
+* new icons i/enrolusers and t/enrolusers, previsouly i/users was used.
+* new icon t/cohorts (sized 12x12), to prevent the use of i/cohorts which is 16x16.
 * new icons t/sort_asc, t/sort_desc to use for ordering in table headers.
 * new class 'iconsort' for icons used for ordering in table headers.
 
index 36fd328..87c4490 100644 (file)
 defined('MOODLE_INTERNAL') || die();
 
 
-$version  = 2012111200.00;              // YYYYMMDD      = weekly release date of this DEV branch
+$version  = 2012111601.00;              // YYYYMMDD      = weekly release date of this DEV branch
                                         //         RR    = release increments - 00 in DEV branches
                                         //           .XX = incremental changes
 
-$release  = '2.4beta (Build: 20121109)'; // Human-friendly version name
+$release  = '2.4beta+ (Build: 20121116)'; // Human-friendly version name
 
 $branch   = '24';                       // this version's branch
 $maturity = MATURITY_BETA;             // this version's maturity level