Merge branch 'MDL-35966-master' of git://github.com/damyon/moodle
authorDan Poltawski <dan@moodle.com>
Wed, 28 Nov 2012 06:15:28 +0000 (14:15 +0800)
committerDan Poltawski <dan@moodle.com>
Wed, 28 Nov 2012 06:15:28 +0000 (14:15 +0800)
31 files changed:
blocks/moodleblock.class.php
calendar/lib.php
calendar/managesubscriptions_form.php
enrol/manual/yui/quickenrolment/assets/skins/sam/quickenrolment.css
enrol/manual/yui/quickenrolment/quickenrolment.js
lang/en/cache.php
lang/en/webservice.php
lib/db/caches.php
lib/db/services.php
lib/external/externallib.php [new file with mode: 0644]
lib/external/tests/externallib_test.php [new file with mode: 0644]
lib/javascript-static.js
lib/outputrenderers.php
mod/assign/gradingtable.php
mod/assign/lang/en/assign.php
mod/lti/backup/moodle2/restore_lti_stepslib.php
mod/workshop/pix/userplan/task-done.png [new file with mode: 0644]
mod/workshop/pix/userplan/task-done.svg [new file with mode: 0644]
mod/workshop/pix/userplan/task-fail.png [new file with mode: 0644]
mod/workshop/pix/userplan/task-fail.svg [new file with mode: 0644]
mod/workshop/pix/userplan/task-info.png [new file with mode: 0644]
mod/workshop/pix/userplan/task-info.svg [new file with mode: 0644]
mod/workshop/pix/userplan/task-todo.png [new file with mode: 0644]
mod/workshop/pix/userplan/task-todo.svg [new file with mode: 0644]
mod/workshop/styles.css
mod/workshop/view.php
pix/i/scheduled.png
pix/i/scheduled.svg [new file with mode: 0644]
portfolio/upgrade.txt
report/log/index.php
version.php

index 02c53bf..236c103 100644 (file)
@@ -565,7 +565,8 @@ class block_base {
         // The blocks in My Moodle are a special case and use a different capability.
         if (!empty($USER->id)
             && $page->context->contextlevel == CONTEXT_USER // Page belongs to a user
-            && $page->context->instanceid == $USER->id) { // Page belongs to this user
+            && $page->context->instanceid == $USER->id // Page belongs to this user
+            && $page->pagetype == 'my-index') { // Ensure we are on the My Moodle page
             $capability = 'block/' . $this->name() . ':myaddinstance';
             return $this->has_add_block_capability($page, $capability)
                     && has_capability('moodle/my:manageblocks', $page->context);
index 2549493..86ca22f 100644 (file)
@@ -1753,11 +1753,19 @@ function calendar_get_allowed_types(&$allowed, $course = null) {
                 $allowed->courses = array($course->id => 1);
 
                 if ($course->groupmode != NOGROUPS || !$course->groupmodeforce) {
-                    $allowed->groups = groups_get_all_groups($course->id);
+                    if (has_capability('moodle/site:accessallgroups', $coursecontext)) {
+                        $allowed->groups = groups_get_all_groups($course->id);
+                    } else {
+                        $allowed->groups = groups_get_all_groups($course->id, $USER->id);
+                    }
                 }
             } else if (has_capability('moodle/calendar:managegroupentries', $coursecontext)) {
                 if($course->groupmode != NOGROUPS || !$course->groupmodeforce) {
-                    $allowed->groups = groups_get_all_groups($course->id);
+                    if (has_capability('moodle/site:accessallgroups', $coursecontext)) {
+                        $allowed->groups = groups_get_all_groups($course->id);
+                    } else {
+                        $allowed->groups = groups_get_all_groups($course->id, $USER->id);
+                    }
                 }
             }
         }
index caf3400..28344cd 100644 (file)
@@ -122,8 +122,10 @@ class calendar_addsubscription_form extends moodleform {
                     $errors['importfile'] = get_string('errorrequiredurlorfile', 'calendar');
                 }
             }
-        } else if (($data['importfrom'] == CALENDAR_IMPORT_FROM_URL) && (clean_param($data['url'], PARAM_URL) !== $data['url'])) {
-            $errors['url']  = get_string('invalidurl', 'error');
+        } else if (($data['importfrom'] == CALENDAR_IMPORT_FROM_URL)) {
+            if (clean_param($data['url'], PARAM_URL) !== $data['url']) {
+                $errors['url']  = get_string('invalidurl', 'error');
+            }
         } else {
             // Shouldn't happen.
             $errors['url'] = get_string('errorrequiredurlorfile', 'calendar');
index ff3543f..e8a4cda 100644 (file)
@@ -64,7 +64,8 @@ Structure of the user enroller panel
 .user-enroller-panel .uep-footer {padding:3px;background-color:#ddd;text-align:center;}
 .user-enroller-panel .uep-search {margin:3px;}
 .user-enroller-panel .uep-search label {padding-right:8px;}
-.user-enroller-panel .uep-search input {width:70%;}
+.user-enroller-panel .uep-search input {width:50%;}
+.user-enroller-panel .uep-search input.uep-search-btn {width:20%;}
 .user-enroller-panel .uep-searchoptions {margin:3px;cursor:pointer;}
 .user-enroller-panel .uep-searchoptions select {margin-left:1em;}
 .user-enroller-panel .collapsibleheading img {margin-right:8px;}
index c047999..81774af 100644 (file)
@@ -5,6 +5,7 @@ YUI.add('moodle-enrol_manual-quickenrolment', function(Y) {
         /** Properties **/
         BASE : 'base',
         SEARCH : 'search',
+        SEARCHBTN : 'searchbtn',
         PARAMS : 'params',
         URL : 'url',
         AJAXURL : 'ajaxurl',
@@ -62,6 +63,7 @@ YUI.add('moodle-enrol_manual-quickenrolment', function(Y) {
         DURATION : 'duration',
         ACTIVE : 'active',
         SEARCH : 'uep-search',
+        SEARCHBTN : 'uep-search-btn',
         CLOSE : 'close',
         CLOSEBTN : 'close-button'
     };
@@ -109,8 +111,9 @@ YUI.add('moodle-enrol_manual-quickenrolment', function(Y) {
                                 .setAttribute('src', M.util.image_url('i/loading', 'moodle')))
                             .setStyle('opacity', 0.5)))
                     .append(create('<div class="'+CSS.FOOTER+'"></div>')
-                        .append(create('<div class="'+CSS.SEARCH+'"><label>'+M.str.enrol.usersearch+'</label></div>')
+                        .append(create('<div class="'+CSS.SEARCH+'"><label for="enrolusersearch" class="accesshide">'+M.str.enrol.usersearch+'</label></div>')
                             .append(create('<input type="text" id="enrolusersearch" value="" />'))
+                                .append(create('<input type="button" id="searchbtn" class="'+CSS.SEARCHBTN+'" value="'+M.str.enrol.usersearch+'" />'))
                         )
                         .append(create('<div class="'+CSS.CLOSEBTN+'"></div>')
                             .append(create('<input type="button" value="'+M.str.enrol.finishenrollingusers+'" />'))
@@ -120,6 +123,7 @@ YUI.add('moodle-enrol_manual-quickenrolment', function(Y) {
             );
 
             this.set(UEP.SEARCH, this.get(UEP.BASE).one('#enrolusersearch'));
+            this.set(UEP.SEARCHBTN, this.get(UEP.BASE).one('#searchbtn'));
             Y.all('.enrol_manual_plugin input').each(function(node){
                 if (node.getAttribute('type', 'submit')) {
                     node.on('click', this.show, this);
@@ -133,6 +137,7 @@ YUI.add('moodle-enrol_manual-quickenrolment', function(Y) {
             this.set(UEP.PARAMS, params);
 
             Y.on('key', this.preSearch, this.get(UEP.SEARCH), 'down:13', this);
+            this.get(UEP.SEARCHBTN).on('click', this.preSearch, this);
 
             Y.one(document.body).append(this.get(UEP.BASE));
 
index 399c49d..6a42f24 100644 (file)
@@ -34,7 +34,6 @@ $string['area'] = 'Area';
 $string['caching'] = 'Caching';
 $string['cacheadmin'] = 'Cache administration';
 $string['cacheconfig'] = 'Configuration';
-$string['cachedef_config'] = 'Config settings';
 $string['cachedef_databasemeta'] = 'Database meta information';
 $string['cachedef_eventinvalidation'] = 'Event invalidation';
 $string['cachedef_locking'] = 'Locking';
@@ -118,4 +117,4 @@ $string['supports_keyawareness'] = 'key awareness';
 $string['tested'] = 'Tested';
 $string['testperformance'] = 'Test performance';
 $string['unsupportedmode'] = 'Unsupported mode';
-$string['untestable'] = 'Untestable';
\ No newline at end of file
+$string['untestable'] = 'Untestable';
index 2415007..39021ec 100644 (file)
@@ -180,6 +180,7 @@ $string['tokenauthlog'] = 'Token authentication';
 $string['tokencreatedbyadmin'] = 'Can only be reset by administrator (*)';
 $string['tokencreator'] = 'Creator';
 $string['unknownoptionkey'] = 'Unknown option key ({$a})';
+$string['unnamedstringparam'] = 'A string parameter is unnamed.';
 $string['updateusersettings'] = 'Update';
 $string['userasclients'] = 'Users as clients with token';
 $string['userasclientsdescription'] = 'The following steps help you to set up the Moodle web service for users as clients. These steps also help to set up the recommended token (security keys) authentication method. In this use case, the user will generate his token from the security keys page via My profile settings.';
index 5d44fd1..6c3ebe0 100644 (file)
@@ -51,18 +51,6 @@ $definitions = array(
         'persistentmaxsize' => 2
     ),
 
-    // Used to store data from the config + config_plugins table in the database.
-    // The key used is the component:
-    //   - core for all core config settings
-    //   - plugin component for all plugin settings.
-    // Persistence is used because normally several settings within a script.
-    'config' => array(
-        'mode' => cache_store::MODE_APPLICATION,
-        'persistent' => true,
-        'simplekeys' => true,
-        'simpledata' => true
-    ),
-
     // Event invalidation cache.
     // This cache is used to manage event invalidation, its keys are the event names.
     // Whenever something is invalidated it is both purged immediately and an event record created with the timestamp.
index ac1b79b..9301edd 100644 (file)
@@ -610,6 +610,30 @@ $functions = array(
         'type'        => 'read',
     ),
 
+    'core_get_string' => array(
+        'classname'   => 'core_external',
+        'methodname'  => 'get_string',
+        'classpath'   => 'lib/external/externallib.php',
+        'description' => 'Return a translated string - similar to core get_string() call',
+        'type'        => 'read',
+    ),
+
+    'core_get_strings' => array(
+        'classname'   => 'core_external',
+        'methodname'  => 'get_strings',
+        'classpath'   => 'lib/external/externallib.php',
+        'description' => 'Return some translated strings - like several core get_string() calls',
+        'type'        => 'read',
+    ),
+
+    'core_get_component_strings' => array(
+        'classname'   => 'core_external',
+        'methodname'  => 'get_component_strings',
+        'classpath'   => 'lib/external/externallib.php',
+        'description' => 'Return all raw strings (with {$a->xxx}) for a specific component
+            - similar to core get_component_strings() call',
+        'type'        => 'read',
+    ),
 );
 
 $services = array(
@@ -623,7 +647,8 @@ $services = array(
             'moodle_user_get_course_participants_by_id',
             'moodle_user_get_users_by_courseid',
             'moodle_message_send_instantmessages',
-            'core_course_get_contents'),
+            'core_course_get_contents',
+            'core_get_component_strings'),
         'enabled' => 0,
         'restrictedusers' => 0,
         'shortname' => MOODLE_OFFICIAL_MOBILE_SERVICE,
diff --git a/lib/external/externallib.php b/lib/external/externallib.php
new file mode 100644 (file)
index 0000000..5ba6a5e
--- /dev/null
@@ -0,0 +1,258 @@
+<?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/>.
+
+
+/**
+ * external API for core library
+ *
+ * @package    core_webservice
+ * @category   external
+ * @copyright  2012 Jerome Mouneyrac <jerome@moodle.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die;
+
+require_once("$CFG->libdir/externallib.php");
+
+/**
+ * Web service related functions
+ *
+ * @package    core
+ * @category   external
+ * @copyright  2012 Jerome Mouneyrac <jerome@moodle.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @since Moodle 2.4
+ */
+class core_external extends external_api {
+
+
+    /**
+     * Format the received string parameters to be sent to the core get_string() function.
+     *
+     * @param array $stringparams
+     * @return object|string
+     * @since 2.4
+     */
+    public static function format_string_parameters($stringparams) {
+        // Check if there are some string params.
+        $strparams = new stdClass();
+        if (!empty($stringparams)) {
+            // There is only one string parameter.
+            if (count($stringparams) == 1) {
+                $stringparam = array_pop($stringparams);
+                if (isset($stringparam['name'])) {
+                    $strparams->{$stringparam['name']} = $stringparam['value'];
+                } else {
+                    // It is a not named string parameter.
+                    $strparams = $stringparam['value'];
+                }
+            }  else {
+                // There are more than one parameter.
+                foreach ($stringparams as $stringparam) {
+
+                    // If a parameter is unnamed throw an exception
+                    // unnamed param is only possible if one only param is sent.
+                    if (empty($stringparam['name'])) {
+                        throw new moodle_exception('unnamedstringparam', 'webservice');
+                    }
+
+                    $strparams->{$stringparam['name']} = $stringparam['value'];
+                }
+            }
+        }
+        return $strparams;
+    }
+
+    /**
+     * Returns description of get_string parameters
+     *
+     * @return external_function_parameters
+     * @since Moodle 2.4
+     */
+    public static function get_string_parameters() {
+        return new external_function_parameters(
+            array('stringid' => new external_value(PARAM_STRINGID, 'string identifier'),
+                  'component' => new external_value(PARAM_COMPONENT,'component', VALUE_DEFAULT, 'moodle'),
+                  'lang' => new external_value(PARAM_LANG, 'lang', VALUE_DEFAULT, null),
+                  'stringparams' => new external_multiple_structure (
+                      new external_single_structure(array(
+                          'name' => new external_value(PARAM_ALPHANUMEXT, 'param name
+                            - if the string expect only one $a parameter then don\'t send this field, just send the value.', VALUE_OPTIONAL),
+                          'value' => new external_value(PARAM_TEXT,'param value'))),
+                          'the definition of a string param (i.e. {$a->name})', VALUE_DEFAULT, array()
+                   )
+            )
+        );
+    }
+
+    /**
+     * Return a core get_string() call
+     *
+     * @param string $identifier string identifier
+     * @param string $component string component
+     * @param array $stringparams the string params
+     * @return string
+     * @since Moodle 2.4
+     */
+    public static function get_string($stringid, $component = 'moodle', $stringparams = array()) {
+        $params = self::validate_parameters(self::get_string_parameters(),
+                      array('stringid'=>$stringid, 'component' => $component, 'stringparams' => $stringparams));
+
+        return get_string($params['stringid'], $params['component'],
+            core_external::format_string_parameters($params['stringparams']), $params['lang']);
+    }
+
+    /**
+     * Returns description of get_string() result value
+     *
+     * @return string
+     * @since Moodle 2.4
+     */
+    public static function get_string_returns() {
+        return new external_value(PARAM_TEXT, 'translated string');
+    }
+
+    /**
+     * Returns description of get_string parameters
+     *
+     * @return external_function_parameters
+     * @since Moodle 2.4
+     */
+    public static function get_strings_parameters() {
+        return new external_function_parameters(
+            array('strings' => new external_multiple_structure (
+                    new external_single_structure (array(
+                        'stringid' => new external_value(PARAM_STRINGID, 'string identifier'),
+                        'component' => new external_value(PARAM_COMPONENT, 'component', VALUE_DEFAULT, 'moodle'),
+                        'lang' => new external_value(PARAM_LANG, 'lang', VALUE_DEFAULT, null),
+                        'stringparams' => new external_multiple_structure (
+                            new external_single_structure(array(
+                                'name' => new external_value(PARAM_ALPHANUMEXT, 'param name
+                                    - if the string expect only one $a parameter then don\'t send this field, just send the value.', VALUE_OPTIONAL),
+                                'value' => new external_value(PARAM_TEXT, 'param value'))),
+                                'the definition of a string param (i.e. {$a->name})', VALUE_DEFAULT, array()
+                        ))
+                    )
+                )
+            )
+        );
+    }
+
+    /**
+     * Return multiple call to core get_string()
+     *
+     * @param array $strings strings to translate
+     * @return array
+     *
+     * @since Moodle 2.4
+     */
+    public static function get_strings($strings) {
+        $params = self::validate_parameters(self::get_strings_parameters(),
+                      array('strings'=>$strings));
+
+        $translatedstrings = array();
+        foreach($params['strings'] as $string) {
+
+            if (empty($string['lang'])) {
+                $lang = $string['lang'];
+            } else {
+                $lang = current_language();
+            }
+
+            $translatedstrings[] = array(
+                'stringid' => $string['stringid'],
+                'component' => $string['component'],
+                'lang' => $lang,
+                'string' => get_string($string['stringid'], $string['component'],
+                    core_external::format_string_parameters($string['stringparams']), $lang));
+        }
+
+        return $translatedstrings;
+    }
+
+    /**
+     * Returns description of get_string() result value
+     *
+     * @return array
+     * @since Moodle 2.4
+     */
+    public static function get_strings_returns() {
+        return new external_multiple_structure(
+            new external_single_structure(array(
+                'stringid' => new external_value(PARAM_STRINGID, 'string id'),
+                'component' => new external_value(PARAM_COMPONENT, 'string component'),
+                'lang' => new external_value(PARAM_LANG, 'lang'),
+                'string' => new external_value(PARAM_TEXT, 'translated string'))
+            ));
+    }
+
+     /**
+     * Returns description of get_component_strings parameters
+     *
+     * @return external_function_parameters
+     * @since Moodle 2.4
+     */
+    public static function get_component_strings_parameters() {
+        return new external_function_parameters(
+            array('component' => new external_value(PARAM_COMPONENT, 'component'),
+                  'lang' => new external_value(PARAM_LANG, 'lang', VALUE_DEFAULT, null),
+            )
+        );
+    }
+
+    /**
+     * Return all lang strings of a component - call to core get_component_strings().
+     *
+     * @param string $component component name
+     * @return array
+     *
+     * @since Moodle 2.4
+     */
+    public static function get_component_strings($component, $lang = null) {
+
+        if (empty($lang)) {
+            $lang = current_language();
+        }
+
+        $params = self::validate_parameters(self::get_component_strings_parameters(),
+                      array('component'=>$component, 'lang' => $lang));
+
+        $stringmanager = get_string_manager();
+
+        $wsstrings = array();
+        $componentstrings = $stringmanager->load_component_strings($params['component'], $params['lang']);
+        foreach($componentstrings as $stringid => $string) {
+            $wsstrings[$stringid] = $string;
+        }
+
+        return $wsstrings;
+    }
+
+    /**
+     * Returns description of get_component_strings() result value
+     *
+     * @return array
+     * @since Moodle 2.4
+     */
+    public static function get_component_strings_returns() {
+        return new external_multiple_structure(
+            new external_single_structure(array(
+                'stringid' => new external_value(PARAM_STRINGID, 'string id'),
+                'string' => new external_value(PARAM_TEXT, 'translated string'))
+            ));
+    }
+}
diff --git a/lib/external/tests/externallib_test.php b/lib/external/tests/externallib_test.php
new file mode 100644 (file)
index 0000000..815b97e
--- /dev/null
@@ -0,0 +1,113 @@
+<?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/>.
+
+defined('MOODLE_INTERNAL') || die();
+
+global $CFG;
+require_once($CFG->dirroot . '/lib/external/externallib.php');
+require_once($CFG->dirroot . '/webservice/tests/helpers.php');
+
+/**
+ * External library functions unit tests
+ *
+ * @package    core
+ * @category   external
+ * @copyright  2012 Jerome Mouneyrac
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class core_external_testcase extends externallib_advanced_testcase {
+
+    /**
+     * Test get_string
+     */
+    public function test_get_string() {
+        $this->resetAfterTest(true);
+
+        $service = new stdClass();
+        $service->name = 'Dummy Service';
+        $service->id = 12;
+
+        // String with two parameters.
+        $returnedstring = core_external::get_string('addservice', 'webservice',
+                array(array('name' => 'name', 'value' => $service->name),
+                      array('name' => 'id', 'value' => $service->id)));
+        $corestring = get_string('addservice', 'webservice', $service);
+        $this->assertEquals($corestring, $returnedstring);
+
+        // String with one parameter.
+        $acapname = 'A capability name';
+        $returnedstring = core_external::get_string('missingrequiredcapability', 'webservice',
+                array(array('value' => $acapname)));
+        $corestring = get_string('missingrequiredcapability', 'webservice', $acapname);
+        $this->assertEquals($corestring, $returnedstring);
+
+        // String without parameters.
+        $returnedstring = core_external::get_string('missingpassword', 'webservice');
+        $corestring = get_string('missingpassword', 'webservice');
+        $this->assertEquals($corestring, $returnedstring);
+
+        // String with two parameter but one is invalid (not named).
+        $this->setExpectedException('moodle_exception');
+        $returnedstring = core_external::get_string('addservice', 'webservice',
+                array(array('value' => $service->name),
+                      array('name' => 'id', 'value' => $service->id)));
+    }
+
+    /**
+     * Test get_strings
+     */
+    public function test_get_strings() {
+        $this->resetAfterTest(true);
+
+        $service = new stdClass();
+        $service->name = 'Dummy Service';
+        $service->id = 12;
+
+        $returnedstrings = core_external::get_strings(
+                array(
+                    array(
+                        'stringid' => 'addservice', 'component' => 'webservice',
+                        'stringparams' => array(array('name' => 'name', 'value' => $service->name),
+                              array('name' => 'id', 'value' => $service->id)
+                        )
+                    ),
+                    array('stringid' =>  'addaservice', 'component' => 'webservice')
+                ));
+
+        foreach($returnedstrings as $returnedstring) {
+            $corestring = get_string($returnedstring['stringid'], $returnedstring['component'], $service);
+            $this->assertEquals($corestring, $returnedstring['string']);
+        }
+    }
+
+    /**
+     * Test get_component_strings
+     */
+    public function test_get_component_strings() {
+        global $USER;
+        $this->resetAfterTest(true);
+
+        $stringmanager = get_string_manager();
+
+        $wsstrings = $stringmanager->load_component_strings('webservice', current_language());
+
+        $componentstrings = core_external::get_component_strings('webservice');
+        $this->assertEquals(count($componentstrings), count($wsstrings));
+        foreach($wsstrings as $name => $string) {
+            $this->assertEquals($string, $componentstrings[$name]);
+        }
+    }
+}
index 574deb7..c0878b3 100644 (file)
@@ -1478,7 +1478,7 @@ M.util.help_icon = {
             return;
         }
         this.Y = Y;
-        Y.one('body').delegate('click', this.display, 'span.helplink a', this);
+        Y.one('body').delegate('click', this.display, 'span.helplink a.tooltip', this);
         this.initialised = true;
     },
     add : function(Y, properties) {
index 9d11581..ddf9147 100644 (file)
@@ -1959,7 +1959,7 @@ class core_renderer extends renderer_base {
         // note: this title is displayed only if JS is disabled, otherwise the link will have the new ajax tooltip
         $title = get_string('helpprefix2', '', trim($title, ". \t"));
 
-        $attributes = array('href'=>$url, 'title'=>$title, 'aria-haspopup' => 'true');
+        $attributes = array('href'=>$url, 'title'=>$title, 'aria-haspopup' => 'true', 'class' => 'tooltip');
         $output = html_writer::tag('a', $output, $attributes);
 
         $this->page->requires->js_init_call('M.util.help_icon.setup');
@@ -2224,9 +2224,9 @@ EOD;
             $html .= <<<EOD
     <div id="file_info_{$client_id}" class="mdl-left filepicker-filelist" style="position: relative">
     <div class="filepicker-filename">
-        <div class="filepicker-container">$currentfile<span class="dndupload-message">$strdndenabled <br/><span class="dndupload-arrow"></span></span></div>
+        <div class="filepicker-container">$currentfile<div class="dndupload-message">$strdndenabled <br/><div class="dndupload-arrow"></div></div></div>
     </div>
-    <div><div class="dndupload-target">{$strdroptoupload}<br/><span class="dndupload-arrow"></span></div></div>
+    <div><div class="dndupload-target">{$strdroptoupload}<br/><div class="dndupload-arrow"></div></div></div>
     </div>
 EOD;
         }
index 80675c6..e9747e6 100644 (file)
@@ -585,7 +585,11 @@ class assign_grading_table extends table_sql implements renderable {
         $gradingdisabled = $this->assignment->grading_disabled($row->id);
 
         if (!$this->is_downloading()) {
-            $icon = $this->output->pix_icon('gradefeedback', get_string('grade'), 'mod_assign');
+            $name = fullname($row);
+            if ($this->assignment->is_blind_marking()) {
+                $name = get_string('hiddenuser', 'assign') . $this->assignment->get_uniqueid_for_user($row->userid);
+            }
+            $icon = $this->output->pix_icon('gradefeedback', get_string('gradeuser', 'assign', $name), 'mod_assign');
             $url = new moodle_url('/mod/assign/view.php',
                                             array('id' => $this->assignment->get_course_module()->id,
                                                   'rownum'=>$this->rownum,'action'=>'grade'));
index 91a8957..671607b 100644 (file)
@@ -120,6 +120,7 @@ $string['gradersubmissionupdatedhtml'] = '{$a->username} has updated their assig
 for <i>\'{$a->assignment}\'  at {$a->timeupdated}</i><br /><br />
 It is <a href="{$a->url}">available on the web site</a>.';
 $string['gradersubmissionupdatedsmall'] = '{$a->username} has updated their submission for assignment {$a->assignment}.';
+$string['gradeuser'] = 'Grade {$a}';
 $string['grantextension'] = 'Grant extension';
 $string['grantextensionforusers'] = 'Grant extension for {$a} students';
 $string['enabled'] = 'Enabled';
index 544955a..2a76b52 100644 (file)
@@ -64,20 +64,20 @@ class restore_lti_activity_structure_step extends restore_activity_structure_ste
     }
 
     protected function process_lti($data) {
-        global $DB, $CFG;
+        global $DB;
 
         $data = (object)$data;
         $oldid = $data->id;
         $data->course = $this->get_courseid();
+        $data->servicesalt = uniqid('', true);
 
-        require_once($CFG->dirroot.'/mod/lti/lib.php');
         // Clean any course or site typeid. All modules
         // are restored as self-contained. Note this is
         // an interim solution until the issue below is implemented.
         // TODO: MDL-34161 - Fix restore to support course/site tools & submissions.
         $data->typeid = 0;
 
-        $newitemid = lti_add_instance($data, null);
+        $newitemid = $DB->insert_record('lti', $data);
 
         // immediately after inserting "activity" record, call this
         $this->apply_activity_instance($newitemid);
diff --git a/mod/workshop/pix/userplan/task-done.png b/mod/workshop/pix/userplan/task-done.png
new file mode 100644 (file)
index 0000000..11ef29b
Binary files /dev/null and b/mod/workshop/pix/userplan/task-done.png differ
diff --git a/mod/workshop/pix/userplan/task-done.svg b/mod/workshop/pix/userplan/task-done.svg
new file mode 100644 (file)
index 0000000..aef9ff6
--- /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.1 0 16 16" style="overflow:visible;enable-background:new -0.1 0 16 16;"\r
+        xml:space="preserve">\r
+<defs>\r
+</defs>\r
+<path style="fill:#99CC33;" d="M6.4,11.1c-2-2.5-3.7-4-3.7-4S0.3,9.5,0,9.8C5,13.1,8.1,16,8.1,16s0.2-0.7,0.6-1.8\r
+       c0.9-2.7,3.2-8.1,7.1-14.2C11.2,3.7,8.1,8.2,6.4,11.1z"/>\r
+</svg>\r
diff --git a/mod/workshop/pix/userplan/task-fail.png b/mod/workshop/pix/userplan/task-fail.png
new file mode 100644 (file)
index 0000000..0f5cfe0
Binary files /dev/null and b/mod/workshop/pix/userplan/task-fail.png differ
diff --git a/mod/workshop/pix/userplan/task-fail.svg b/mod/workshop/pix/userplan/task-fail.svg
new file mode 100644 (file)
index 0000000..27d851b
--- /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="-1.6 -0.5 16 16"\r
+        style="overflow:visible;enable-background:new -1.6 -0.5 16 16;" xml:space="preserve">\r
+<defs>\r
+</defs>\r
+<path style="fill:#FF403C;" d="M12.8,2.7L10.1,0c0,0-1.6,1.5-3.7,4C4.3,1.5,2.7,0,2.7,0L0,2.7c0,0,1.9,1.3,4.6,3.7\r
+       C3,8.7,1.3,11.6,0,14.9C2.2,12.2,4.4,9.9,6.4,8c2,1.9,4.2,4.2,6.4,6.9c-1.3-3.3-3-6.2-4.6-8.6C10.9,4,12.8,2.7,12.8,2.7z"/>\r
+</svg>\r
diff --git a/mod/workshop/pix/userplan/task-info.png b/mod/workshop/pix/userplan/task-info.png
new file mode 100644 (file)
index 0000000..4047841
Binary files /dev/null and b/mod/workshop/pix/userplan/task-info.png differ
diff --git a/mod/workshop/pix/userplan/task-info.svg b/mod/workshop/pix/userplan/task-info.svg
new file mode 100644 (file)
index 0000000..d782dc3
--- /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" preserveAspectRatio="xMinYMid meet">\r
+<defs>\r
+</defs>\r
+<path style="fill:#999999;" d="M8,0C3.6,0,0,3.6,0,8c0,4.4,3.6,8,8,8c4.4,0,8-3.6,8-8C16,3.6,12.4,0,8,0z M8,14c-3.3,0-6-2.7-6-6\r
+       c0-3.3,2.7-6,6-6c3.3,0,6,2.7,6,6C14,11.3,11.3,14,8,14z M9.2,12c0,0.5-0.5,1-1,1H7.8c-0.5,0-1-0.5-1-1V7.4c0-0.5,0.5-1,1-1h0.5\r
+       c0.5,0,1,0.5,1,1V12z M9.2,4.2c0,0.7-0.6,1.2-1.2,1.2c-0.7,0-1.2-0.6-1.2-1.2C6.8,3.5,7.3,3,8,3C8.7,3,9.2,3.5,9.2,4.2z"/>\r
+</svg>\r
diff --git a/mod/workshop/pix/userplan/task-todo.png b/mod/workshop/pix/userplan/task-todo.png
new file mode 100644 (file)
index 0000000..dc0a6f5
Binary files /dev/null and b/mod/workshop/pix/userplan/task-todo.png differ
diff --git a/mod/workshop/pix/userplan/task-todo.svg b/mod/workshop/pix/userplan/task-todo.svg
new file mode 100644 (file)
index 0000000..c103968
--- /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="16px" height="16px" viewBox="-0.1 0 16 16" style="overflow:visible;enable-background:new -0.1 0 16 16;"\r
+        xml:space="preserve">\r
+<defs>\r
+</defs>\r
+<path style="fill:#999999;" d="M5.5,10H0.3C0.2,9.9,0.1,9.9,0,9.8C0.2,9.6,1.1,8.7,1.8,8h1.8C4.1,8.5,4.7,9.2,5.5,10z M9.2,13\r
+       c0.2-0.6,0.5-1.3,0.8-2H6.4c0,0,0,0.1-0.1,0.1c0,0,0-0.1-0.1-0.1H1.8c1,0.7,1.9,1.4,2.7,2H9.2z M15.2,1c0.2-0.3,0.4-0.7,0.6-1\r
+       c-0.4,0.3-0.8,0.7-1.2,1H15.2z M10.7,5c-0.6,0.7-1.1,1.3-1.6,2h2.7c0.3-0.6,0.7-1.3,1-2H10.7z M8.4,8c-0.5,0.7-1,1.4-1.3,2h3.3\r
+       c0.3-0.6,0.6-1.3,0.9-2H8.4z M13.6,2c-0.7,0.7-1.3,1.3-2,2h1.8c0.4-0.7,0.8-1.3,1.2-2H13.6z M5.7,14c1.5,1.2,2.4,2,2.4,2\r
+       s0.2-0.7,0.6-1.8c0-0.1,0.1-0.2,0.1-0.2H5.7z"/>\r
+</svg>\r
index e9a1c48..2553281 100644 (file)
     background-color: #e7f1c3;
 }
 
+.path-mod-workshop .userplan th .actions {
+    display: inline;
+}
 .path-mod-workshop .userplan tr.phasetasks li {
     background-image: url([[pix:mod_workshop|userplan/task-todo]]);
     background-position: top left;
     background-repeat: no-repeat;
     list-style-type: none;
+    min-height: 16px;
+    margin: .3em 0;
 }
 
 .path-mod-workshop .userplan tr.phasetasks li.completed {
     margin: 2em auto;
     text-align: center;
 }
+
+.path-mod-workshop .workshop-risk-dataloss { vertical-align: text-bottom; }
index 42ee2ef..fbcbc46 100644 (file)
@@ -462,7 +462,8 @@ case workshop::PHASE_EVALUATION:
         echo $output->help_icon('clearassessments', 'workshop');
         echo html_writer::empty_tag('img', array('src' => $output->pix_url('i/risk_dataloss'),
                                                  'title' => get_string('riskdatalossshort', 'admin'),
-                                                 'alt' => get_string('riskdatalossshort', 'admin')));
+                                                 'alt' => get_string('riskdatalossshort', 'admin'),
+                                                 'class' => 'workshop-risk-dataloss'));
         echo $output->container_end();
 
         echo $output->box_end();
index 4c5b515..61dd4db 100644 (file)
Binary files a/pix/i/scheduled.png and b/pix/i/scheduled.png differ
diff --git a/pix/i/scheduled.svg b/pix/i/scheduled.svg
new file mode 100644 (file)
index 0000000..76864c5
--- /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="M8,0C3.6,0,0,3.6,0,8c0,4.4,3.6,8,8,8c4.4,0,8-3.6,8-8C16,3.6,12.4,0,8,0z M8,14c-3.3,0-6-2.7-6-6\r
+       s2.7-6,6-6s6,2.7,6,6S11.3,14,8,14z M12,8c0,0.6-0.4,1-1,1H8C7.4,9,7,8.6,7,8V4c0-0.6,0.4-1,1-1s1,0.4,1,1v3h2C11.6,7,12,7.4,12,8z"\r
+       />\r
+</svg>\r
index 460df3d..557a33b 100644 (file)
@@ -1,13 +1,6 @@
 This files describes API changes in /portfolio/ portfolio system,
 information provided here is intended especially for developers.
 
-=== 2.3 ===
-
-required changes:
-* The following methods must now be declared static for php5 compatibility:
-    - admin_config_form
-    - admin_config_validation
-
 === 2.4 ===
 
 The set_callback_options function's third parameter has been changed from a file path
@@ -23,4 +16,11 @@ $button->set_callback_options('assignment_portfolio_caller', array('id' => $this
 
 Now becomes:
 
-$button->set_callback_options('assignment_portfolio_caller', array('id' => $this->cm->id, 'fileid' => $file->get_id()), 'mod_assignment');
\ No newline at end of file
+$button->set_callback_options('assignment_portfolio_caller', array('id' => $this->cm->id, 'fileid' => $file->get_id()), 'mod_assignment');
+
+=== 2.3 ===
+
+required changes:
+* The following methods must now be declared static for php5 compatibility:
+    - admin_config_form
+    - admin_config_validation
index dbe5775..6c0e7ed 100644 (file)
@@ -125,6 +125,11 @@ if (!empty($page)) {
 $stradministration = get_string('administration');
 $strreports = get_string('reports');
 
+// Before we close session, make sure we have editing information in session.
+$adminediting = optional_param('adminedit', -1, PARAM_BOOL);
+if ($PAGE->user_allowed_editing() && $adminediting != -1) {
+    $USER->editing = $adminediting;
+}
 session_get_instance()->write_close();
 
 if (!empty($chooselog)) {
index 32beb69..058c8f2 100644 (file)
@@ -30,7 +30,7 @@
 defined('MOODLE_INTERNAL') || die();
 
 
-$version  = 2012112700.00;              // YYYYMMDD      = weekly release date of this DEV branch
+$version  = 2012112700.01;              // YYYYMMDD      = weekly release date of this DEV branch
                                         //         RR    = release increments - 00 in DEV branches
                                         //           .XX = incremental changes