Merge branch 'MDL-36954' of git://github.com/timhunt/moodle
authorSam Hemelryk <sam@moodle.com>
Tue, 11 Dec 2012 01:59:56 +0000 (14:59 +1300)
committerSam Hemelryk <sam@moodle.com>
Tue, 11 Dec 2012 01:59:56 +0000 (14:59 +1300)
172 files changed:
admin/renderer.php
auth/shibboleth/index.php
backup/backup.class.php
backup/moodle2/backup_activity_task.class.php
backup/moodle2/restore_activity_task.class.php
backup/moodle2/restore_stepslib.php
backup/util/loggers/file_logger.class.php
backup/util/loggers/output_indented_logger.class.php
backup/util/loggers/output_text_logger.class.php
backup/util/ui/backup_ui_setting.class.php
backup/util/ui/renderer.php
blocks/course_overview/db/access.php
blocks/course_overview/lang/en/block_course_overview.php
blocks/course_overview/renderer.php
blocks/course_overview/version.php
blocks/dock.js
blocks/glossary_random/block_glossary_random.php
cache/classes/definition.php
cache/forms.php
calendar/yui/eventmanager/eventmanager.js
course/dndupload.js
course/externallib.php
course/lib.php
course/recent_form.php
course/rest.php
enrol/paypal/ipn.php
enrol/paypal/lib.php
grade/report/grader/styles.css
grade/report/lib.php
grade/tests/reportlib_test.php [new file with mode: 0644]
install/lang/es/install.php
install/lang/es_mx/langconfig.php
lang/en/message.php
lang/en/plugin.php
lib/accesslib.php
lib/ajax/blocks.php
lib/datalib.php
lib/db/upgrade.php
lib/ddl/oracle_sql_generator.php
lib/dml/pdo_moodle_database.php
lib/filelib.php
lib/formslib.php
lib/grade/grade_category.php
lib/javascript-static.js
lib/moodlelib.php
lib/navigationlib.php
lib/outputlib.php
lib/outputrenderers.php
lib/pluginlib.php
lib/sessionlib.php
lib/tests/moodlelib_test.php
lib/webdavlib.php
lib/yui/blocks/blocks.js
mdeploy.php
mdeploytest.php
message/edit.php
mod/assign/assignmentplugin.php
mod/assign/feedback/file/importzipform.php
mod/assign/feedback/offline/importgradesform.php
mod/assign/gradingoptionsform.php
mod/assign/gradingtable.php
mod/assign/locallib.php
mod/assign/pix/gradefeedback.png [new file with mode: 0644]
mod/assign/pix/gradefeedback.svg [new file with mode: 0644]
mod/assign/renderer.php
mod/assign/styles.css
mod/assign/submission/comments/locallib.php
mod/assign/submission/onlinetext/locallib.php
mod/assign/upgradelib.php
mod/data/field/latlong/kml.php
mod/data/view.php
mod/feedback/item/captcha/captcha_form.php
mod/feedback/item/multichoice/multichoice_form.php
mod/feedback/item/multichoicerated/multichoicerated_form.php
mod/feedback/item/numeric/numeric_form.php
mod/feedback/item/textarea/textarea_form.php
mod/feedback/item/textfield/textfield_form.php
mod/lesson/view.php
mod/lti/backup/moodle2/backup_lti_stepslib.php
mod/quiz/accessrule/upgrade.txt
mod/wiki/pagelib.php
mod/wiki/parser/utils.php
mod/workshop/lib.php
pix/c/course.png [new file with mode: 0644]
pix/c/course.svg [new file with mode: 0644]
pix/c/group.png [new file with mode: 0644]
pix/c/group.svg [new file with mode: 0644]
pix/c/site.png [new file with mode: 0644]
pix/c/site.svg [new file with mode: 0644]
pix/c/user.png [new file with mode: 0644]
pix/c/user.svg [new file with mode: 0644]
pix/i/approve.png [new file with mode: 0644]
pix/i/approve.svg [new file with mode: 0644]
pix/i/calendar.png [new file with mode: 0644]
pix/i/calendar.svg [new file with mode: 0644]
pix/i/configlock.png [new file with mode: 0644]
pix/i/configlock.svg [new file with mode: 0644]
pix/i/cross_red_big.png [new file with mode: 0644]
pix/i/cross_red_big.svg [new file with mode: 0644]
pix/i/cross_red_small.png [new file with mode: 0644]
pix/i/cross_red_small.svg [new file with mode: 0644]
pix/i/db.png [new file with mode: 0644]
pix/i/db.svg [new file with mode: 0644]
pix/i/files.png [new file with mode: 0644]
pix/i/files.svg [new file with mode: 0644]
pix/i/hierarchylock.png [new file with mode: 0644]
pix/i/hierarchylock.svg [new file with mode: 0644]
pix/i/permissionlock.png [new file with mode: 0644]
pix/i/permissionlock.svg [new file with mode: 0644]
pix/i/reload.png [new file with mode: 0644]
pix/i/reload.svg [new file with mode: 0644]
pix/i/risk_config.png [new file with mode: 0644]
pix/i/risk_config.svg [new file with mode: 0644]
pix/i/risk_dataloss.png [new file with mode: 0644]
pix/i/risk_dataloss.svg [new file with mode: 0644]
pix/i/risk_managetrust.png [new file with mode: 0644]
pix/i/risk_managetrust.svg [new file with mode: 0644]
pix/i/risk_personal.png [new file with mode: 0644]
pix/i/risk_personal.svg [new file with mode: 0644]
pix/i/risk_spam.png [new file with mode: 0644]
pix/i/risk_spam.svg [new file with mode: 0644]
pix/i/risk_xss.png [new file with mode: 0644]
pix/i/risk_xss.svg [new file with mode: 0644]
pix/i/roles.png [new file with mode: 0644]
pix/i/roles.svg [new file with mode: 0644]
pix/i/search.png [new file with mode: 0644]
pix/i/search.svg [new file with mode: 0644]
pix/i/switchrole.png
pix/i/switchrole.svg
pix/i/tick_amber_big.png [new file with mode: 0644]
pix/i/tick_amber_big.svg [new file with mode: 0644]
pix/i/tick_amber_small.png [new file with mode: 0644]
pix/i/tick_amber_small.svg [new file with mode: 0644]
pix/i/tick_green_big.png [new file with mode: 0644]
pix/i/tick_green_big.svg [new file with mode: 0644]
pix/i/tick_green_small.png [new file with mode: 0644]
pix/i/tick_green_small.svg [new file with mode: 0644]
pix/t/addgreen.png [new file with mode: 0644]
pix/t/addgreen.svg [new file with mode: 0644]
pix/t/clear.png [new file with mode: 0644]
pix/t/clear.svg [new file with mode: 0644]
pix/t/contextmenu.png [new file with mode: 0644]
pix/t/contextmenu.svg [new file with mode: 0644]
pix/t/manual_item.png [new file with mode: 0644]
pix/t/manual_item.svg [new file with mode: 0644]
pix/t/unlock_gray.png [new file with mode: 0644]
pix/t/unlock_gray.svg [new file with mode: 0644]
pix/t/user.png [new file with mode: 0644]
pix/t/user.svg [new file with mode: 0644]
pix/t/userblue.png [new file with mode: 0644]
pix/t/userblue.svg [new file with mode: 0644]
question/behaviour/upgrade.txt
question/export.php
question/format/upgrade.txt
question/type/multianswer/renderer.php
report/log/locallib.php
repository/webdav/lib.php
theme/base/style/core.css
theme/base/style/dock.css
theme/base/style/user.css
theme/magazine/style/core.css
theme/mymobile/javascript/custom.js
theme/mymobile/javascript/jquery.mobile-1.1.1.js
theme/mymobile/readme_moodle.txt [new file with mode: 0644]
theme/mymobile/style/core.css
theme/sky_high/style/admin.css
theme/standardold/layout/frontpage.php
theme/styles.php
theme/styles_debug.php
theme/upgrade.txt
user/index.php
version.php

index de78470..8d49636 100644 (file)
@@ -691,7 +691,7 @@ class core_admin_renderer extends plugin_renderer_base {
     function upgrade_reload($url) {
         return html_writer::empty_tag('br') .
                 html_writer::tag('div',
-                    html_writer::link($url, $this->pix_icon('i/reload', '') .
+                    html_writer::link($url, $this->pix_icon('i/reload', '', '', array('class' => 'icon icon-pre')) .
                             get_string('reload'), array('title' => get_string('reload'))),
                 array('class' => 'continuebutton')) . html_writer::empty_tag('br');
     }
@@ -1211,8 +1211,13 @@ class core_admin_renderer extends plugin_renderer_base {
             if (empty($impediments)) {
                 $widget = $deployer->make_confirm_widget($updateinfo);
                 $box .= $this->output->render($widget);
-            } else if (isset($impediments['notwritable'])) {
-                $box .= $this->output->help_icon('notwritable', 'core_plugin', get_string('notwritable', 'core_plugin'));
+            } else {
+                if (isset($impediments['notwritable'])) {
+                    $box .= $this->output->help_icon('notwritable', 'core_plugin', get_string('notwritable', 'core_plugin'));
+                }
+                if (isset($impediments['notdownloadable'])) {
+                    $box .= $this->output->help_icon('notdownloadable', 'core_plugin', get_string('notdownloadable', 'core_plugin'));
+                }
             }
         }
 
index 88caf30..61f6ba8 100644 (file)
@@ -7,7 +7,10 @@
     $PAGE->set_url('/auth/shibboleth/index.php');
 
     // Support for WAYFless URLs.
-    $SESSION->wantsurl = optional_param('target', $SESSION->wantsurl, PARAM_LOCALURL);
+    $target = optional_param('target', '', PARAM_LOCALURL);
+    if (!empty($target)) {
+        $SESSION->wantsurl = $target;
+    }
 
     if (isloggedin() && !isguestuser()) {      // Nothing to do
         if (isset($SESSION->wantsurl) and (strpos($SESSION->wantsurl, $CFG->wwwroot) === 0)) {
index 40249d0..d60142f 100644 (file)
@@ -110,7 +110,7 @@ abstract class backup implements checksumable {
 
     // Version (to keep CFG->backup_version (and release) updated automatically)
     const VERSION = 2012112900;
-    const RELEASE = '2.4';
+    const RELEASE = '2.5';
 }
 
 /*
index a597425..a1ada38 100644 (file)
@@ -258,7 +258,8 @@ abstract class backup_activity_task extends backup_task {
         // - section_included setting (if exists)
         $settingname = $settingprefix . 'included';
         $activity_included = new backup_activity_generic_setting($settingname, base_setting::IS_BOOLEAN, true);
-        $activity_included->get_ui()->set_icon(new pix_icon('icon', get_string('pluginname', $this->modulename), $this->modulename));
+        $activity_included->get_ui()->set_icon(new pix_icon('icon', get_string('pluginname', $this->modulename),
+            $this->modulename, array('class' => 'iconlarge icon-post')));
         $this->add_setting($activity_included);
         // Look for "activities" root setting
         $activities = $this->plan->get_setting('activities');
index 5838a8e..cac6824 100644 (file)
@@ -278,7 +278,8 @@ abstract class restore_activity_task extends restore_task {
         // - section_included setting (if exists)
         $settingname = $settingprefix . 'included';
         $activity_included = new restore_activity_generic_setting($settingname, base_setting::IS_BOOLEAN, true);
-        $activity_included->get_ui()->set_icon(new pix_icon('icon', get_string('pluginname', $this->modulename), $this->modulename));
+        $activity_included->get_ui()->set_icon(new pix_icon('icon', get_string('pluginname', $this->modulename),
+            $this->modulename, array('class' => 'iconlarge icon-post')));
         $this->add_setting($activity_included);
         // Look for "activities" root setting
         $activities = $this->plan->get_setting('activities');
index fe4f504..86c2dac 100644 (file)
@@ -190,6 +190,15 @@ class restore_gradebook_structure_step extends restore_structure_step {
                 $data->id = $newitemid = $existinggradeitem->id;
                 $DB->update_record('grade_items', $data);
             }
+        } else if ($data->itemtype == 'manual') {
+            // Manual items aren't assigned to a cm, so don't go duplicating them in the target if one exists.
+            $gi = array(
+                'itemtype' => $data->itemtype,
+                'courseid' => $data->courseid,
+                'itemname' => $data->itemname,
+                'categoryid' => $data->categoryid,
+            );
+            $newitemid = $DB->get_field('grade_items', 'id', $gi);
         }
 
         if (empty($newitemid)) {
index e4ab4b1..5c05380 100644 (file)
@@ -75,7 +75,7 @@ class file_logger extends base_logger {
         if (substr($this->fullpath, -5) !== '.html') {
             $content = $prefix . str_repeat('  ', $depth) . $message . PHP_EOL;
         } else {
-            $content = $prefix . str_repeat('&nbsp;&nbsp;', $depth) . htmlentities($message, ENT_QUOTES) . '<br/>' . PHP_EOL;
+            $content = $prefix . str_repeat('&nbsp;&nbsp;', $depth) . htmlentities($message, ENT_QUOTES, 'UTF-8') . '<br/>' . PHP_EOL;
         }
         if (false === fwrite($this->fhandle, $content)) {
             throw new base_logger_exception('error_writing_file', $this->fullpath);
index 8bb6811..2eaea5b 100644 (file)
@@ -38,7 +38,7 @@ class output_indented_logger extends base_logger {
         if (defined('STDOUT')) {
             echo $prefix . str_repeat('  ', $depth) . $message . PHP_EOL;
         } else {
-            echo $prefix . str_repeat('&nbsp;&nbsp;', $depth) . htmlentities($message, ENT_QUOTES) . '<br/>' . PHP_EOL;
+            echo $prefix . str_repeat('&nbsp;&nbsp;', $depth) . htmlentities($message, ENT_QUOTES, 'UTF-8') . '<br/>' . PHP_EOL;
         }
         flush();
         return true;
index fe61536..9d13dfd 100644 (file)
@@ -37,7 +37,7 @@ class output_text_logger extends base_logger {
         if (defined('STDOUT')) {
             echo $prefix . $message . PHP_EOL;
         } else {
-            echo $prefix . htmlentities($message, ENT_QUOTES) . '<br/>' . PHP_EOL;
+            echo $prefix . htmlentities($message, ENT_QUOTES, 'UTF-8') . '<br/>' . PHP_EOL;
         }
         flush();
         return true;
index c778fb7..e660c4a 100644 (file)
@@ -329,7 +329,7 @@ class backup_setting_ui_text extends backup_setting_ui {
         $icon = $this->get_icon();
         $label = $this->get_label($task);
         if (!empty($icon)) {
-            $label .= '&nbsp;'.$output->render($icon);
+            $label .= $output->render($icon);
         }
         // name, label, attributes
         return $this->apply_options(array('element'=>'text','name'=>self::NAME_PREFIX.$this->name, 'label'=>$label, 'attributes'=>$this->attributes));
@@ -380,7 +380,7 @@ class backup_setting_ui_checkbox extends backup_setting_ui {
         $icon = $this->get_icon();
         $label = $this->get_label($task);
         if (!empty($icon)) {
-            $label .= '&nbsp;'.$output->render($icon);
+            $label .= $output->render($icon);
         }
         return $this->apply_options(array('element'=>'checkbox','name'=>self::NAME_PREFIX.$this->name, 'label'=>$label, 'text'=>$this->text, 'attributes'=>$this->attributes));
     }
@@ -473,7 +473,7 @@ class backup_setting_ui_radio extends backup_setting_ui {
         $icon = $this->get_icon();
         $label = $this->get_label($task);
         if (!empty($icon)) {
-            $label .= '&nbsp;'.$output->render($icon);
+            $label .= $output->render($icon);
         }
         // name, label, text, value, attributes
         return $this->apply_options(array('element'=>'radio','name'=>self::NAME_PREFIX.$this->name, 'label'=>$label, 'text'=>$this->text, 'value'=>$this->value, 'attributes'=>$this->attributes));
@@ -538,7 +538,7 @@ class backup_setting_ui_select extends backup_setting_ui {
         $icon = $this->get_icon();
         $label = $this->get_label($task);
         if (!empty($icon)) {
-            $label .= '&nbsp;'.$output->render($icon);
+            $label .= $output->render($icon);
         }
         // name, label, options, attributes
         return $this->apply_options(array('element'=>'select','name'=>self::NAME_PREFIX.$this->name, 'label'=>$label, 'options'=>$this->values, 'attributes'=>$this->attributes));
index c58f367..7b8dfe2 100644 (file)
@@ -147,9 +147,9 @@ class core_backup_renderer extends plugin_renderer_base {
                         $table->data = array();
                     }
                     $name = get_string('pluginname', $activity->modulename);
-                    $icon = new pix_icon('icon', $name, $activity->modulename);
+                    $icon = new pix_icon('icon', $name, $activity->modulename, array('class' => 'iconlarge icon-pre'));
                     $table->data[] = array(
-                        $this->output->render($icon).'&nbsp;'.$name,
+                        $this->output->render($icon).$name,
                         $activity->title,
                         ($activity->settings[$activitykey.'_userinfo'])?$yestick:$notick,
                     );
index 828135c..00752d3 100644 (file)
@@ -34,18 +34,5 @@ $capabilities = array(
         ),
 
         'clonepermissionsfrom' => 'moodle/my:manageblocks'
-    ),
-
-    'block/course_overview:addinstance' => array(
-        'riskbitmask' => RISK_SPAM | RISK_XSS,
-
-        'captype' => 'write',
-        'contextlevel' => CONTEXT_BLOCK,
-        'archetypes' => array(
-            'editingteacher' => CAP_ALLOW,
-            'manager' => CAP_ALLOW
-        ),
-
-        'clonepermissionsfrom' => 'moodle/site:manageblocks'
-    ),
+    )
 );
index d7be855..3535110 100644 (file)
@@ -27,7 +27,6 @@ $string['alwaysshowall'] = 'Always Show All';
 $string['collapseall'] = 'Collapse All Course Lists';
 $string['configotherexpanded'] = 'If enabled, Other Courses will be expanded by default unless overriden by user preferences.';
 $string['configpreservestates'] = 'If enabled, the collapsed/expanded states set by the user are stored and used on each load.';
-$string['course_overview:addinstance'] = 'Add a new course overview block';
 $string['course_overview:myaddinstance'] = 'Add a new course overview block to the My Moodle page';
 $string['defaultmaxcourses'] = 'Default maximum courses';
 $string['defaultmaxcoursesdesc'] = 'Maximum courses which should be displayed on course overview block, 0 will show all courses';
index 9e5a93a..8c42428 100644 (file)
@@ -106,7 +106,9 @@ class block_course_overview_renderer extends plugin_renderer_base {
 
             $attributes = array('title' => s($course->fullname));
             if ($course->id > 0) {
-                $link = html_writer::link(new moodle_url('/course/view.php', array('id' => $course->id)), format_string($course->shortname, true, $course->id), $attributes);
+                $courseurl = new moodle_url('/course/view.php', array('id' => $course->id));
+                $coursefullname = format_string($course->fullname, true, $course->id);
+                $link = html_writer::link($courseurl, $coursefullname, $attributes);
                 $html .= $this->output->heading($link, 2, 'title');
             } else {
                 $html .= $this->output->heading(html_writer::link(
index 51a734f..40abe52 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2012112900;        // The current plugin version (Date: YYYYMMDDXX)
+$plugin->version   = 2012121000;        // The current plugin version (Date: YYYYMMDDXX)
 $plugin->requires  = 2012112900;        // Requires this Moodle version
-$plugin->component = 'block_course_overview'; // Full name of the plugin (used for diagnostics)
\ No newline at end of file
+$plugin->component = 'block_course_overview'; // Full name of the plugin (used for diagnostics)
index 6e56390..73249e9 100644 (file)
@@ -516,7 +516,7 @@ M.core_dock.fixTitleOrientation = function(item, title, text) {
     // We need to fix a font-size - sorry theme designers.
     var fontsize = '11px';
     var transform = (clockwise) ? 'rotate(90deg)' : 'rotate(270deg)';
-    var test = Y.Node.create('<h2><span style="font-size:'+fontsize+';position:absolute;">'+text+'</span></h2>');
+    var test = Y.Node.create('<h2><span class="transform-test-node" style="font-size:'+fontsize+';">'+text+'</span></h2>');
     this.nodes.body.insert(test, 0);
     var width = test.one('span').get('offsetWidth') * 1.2;
     var height = test.one('span').get('offsetHeight');
index 916780d..1eccd11 100644 (file)
@@ -137,6 +137,7 @@ class block_glossary_random extends block_base {
             $this->config->cache = '';
             $this->instance_config_commit();
 
+            $this->content = new stdClass();
             $this->content->text   = get_string('notyetconfigured','block_glossary_random');
             $this->content->footer = '';
             return $this->content;
index 607f074..e278bbb 100644 (file)
@@ -750,7 +750,7 @@ class cache_definition {
             if (!empty($this->identifiers)) {
                 $identifiers = array();
                 foreach ($this->identifiers as $key => $value) {
-                    $identifiers[] = htmlentities($key).'='.htmlentities($value);
+                    $identifiers[] = htmlentities($key, ENT_QUOTES, 'UTF-8').'='.htmlentities($value, ENT_QUOTES, 'UTF-8');
                 }
                 $this->keyprefixmulti['identifiers'] = join('&', $identifiers);
             }
index 533f1f8..542e7a0 100644 (file)
@@ -101,7 +101,13 @@ class cachestore_addinstance_form extends moodleform {
         }
 
         if (method_exists($this, 'configuration_validation')) {
-            $errors = $this->configuration_validation($data, $files);
+            $newerrors = $this->configuration_validation($data, $files, $errors);
+            // We need to selectiviliy merge here
+            foreach ($newerrors as $element => $error) {
+                if (!array_key_exists($element, $errors)) {
+                    $errors[$element] = $error;
+                }
+            }
         }
 
         return $errors;
index d07b94b..4aedc2e 100644 (file)
@@ -101,8 +101,10 @@ YUI.add('moodle-calendar-eventmanager', function(Y) {
             },
             node : {
                 setter : function(node) {
-                    var n = Y.one('#'+node);
-                    return n;
+                    if (typeof(node) === 'string') {
+                        node = Y.one('#'+node);
+                    }
+                    return node;
                 }
             },
             title : {
index e1d1b11..d41bfe9 100644 (file)
@@ -442,6 +442,7 @@ M.course_dndupload = {
             parent: modsel,
             li: document.createElement('li'),
             div: document.createElement('div'),
+            indentdiv: document.createElement('div'),
             a: document.createElement('a'),
             icon: document.createElement('img'),
             namespan: document.createElement('span'),
@@ -452,24 +453,23 @@ M.course_dndupload = {
 
         resel.li.className = 'activity resource modtype_resource';
 
-        resel.div.className = 'mod-indent';
-        resel.li.appendChild(resel.div);
+        resel.indentdiv.className = 'mod-indent';
+        resel.li.appendChild(resel.indentdiv);
+
+        resel.div.className = 'activityinstance';
+        resel.indentdiv.appendChild(resel.div);
 
         resel.a.href = '#';
         resel.div.appendChild(resel.a);
 
         resel.icon.src = M.util.image_url('i/ajaxloader');
-        resel.icon.className = 'activityicon';
+        resel.icon.className = 'activityicon iconlarge';
         resel.a.appendChild(resel.icon);
 
-        resel.a.appendChild(document.createTextNode(' '));
-
         resel.namespan.className = 'instancename';
         resel.namespan.innerHTML = name;
         resel.a.appendChild(resel.namespan);
 
-        resel.div.appendChild(document.createTextNode(' '));
-
         resel.groupingspan.className = 'groupinglabel';
         resel.div.appendChild(resel.groupingspan);
 
@@ -738,7 +738,7 @@ M.course_dndupload = {
 
                             resel.div.removeChild(resel.progressouter);
                             resel.li.id = result.elementid;
-                            resel.div.innerHTML += result.commands;
+                            resel.indentdiv.innerHTML += result.commands;
                             if (result.onclick) {
                                 resel.a.onclick = result.onclick;
                             }
index 659228c..b5c82f4 100644 (file)
@@ -211,7 +211,7 @@ class core_course_external extends external_api {
                                 array(
                                     'id' => new external_value(PARAM_INT, 'activity id'),
                                     'url' => new external_value(PARAM_URL, 'activity url', VALUE_OPTIONAL),
-                                    'name' => new external_value(PARAM_TEXT, 'activity module name'),
+                                    'name' => new external_value(PARAM_RAW, 'activity module name'),
                                     'description' => new external_value(PARAM_RAW, 'activity description', VALUE_OPTIONAL),
                                     'visible' => new external_value(PARAM_INT, 'is the module visible', VALUE_OPTIONAL),
                                     'modicon' => new external_value(PARAM_URL, 'activity icon url'),
index 358de6b..f844bc5 100644 (file)
@@ -594,7 +594,7 @@ function print_log_csv($course, $user, $date, $order='l.time DESC', $modname,
             $ld = $DB->get_record('log_display', array('module'=>$log->module, 'action'=>$log->action));
             $ldcache[$log->module][$log->action] = $ld;
         }
-        if ($ld && !empty($log->info)) {
+        if ($ld && is_numeric($log->info)) {
             // ugly hack to make sure fullname is shown correctly
             if (($ld->mtable == 'user') and ($ld->field ==  $DB->sql_concat('firstname', "' '" , 'lastname'))) {
                 $log->info = fullname($DB->get_record($ld->mtable, array('id'=>$log->info)), true);
@@ -694,7 +694,7 @@ function print_log_xls($course, $user, $date, $order='l.time DESC', $modname,
             $ld = $DB->get_record('log_display', array('module'=>$log->module, 'action'=>$log->action));
             $ldcache[$log->module][$log->action] = $ld;
         }
-        if ($ld && !empty($log->info)) {
+        if ($ld && is_numeric($log->info)) {
             // ugly hack to make sure fullname is shown correctly
             if (($ld->mtable == 'user') and ($ld->field == $DB->sql_concat('firstname', "' '" , 'lastname'))) {
                 $log->info = fullname($DB->get_record($ld->mtable, array('id'=>$log->info)), true);
@@ -808,7 +808,7 @@ function print_log_ods($course, $user, $date, $order='l.time DESC', $modname,
             $ld = $DB->get_record('log_display', array('module'=>$log->module, 'action'=>$log->action));
             $ldcache[$log->module][$log->action] = $ld;
         }
-        if ($ld && !empty($log->info)) {
+        if ($ld && is_numeric($log->info)) {
             // ugly hack to make sure fullname is shown correctly
             if (($ld->mtable == 'user') and ($ld->field == $DB->sql_concat('firstname', "' '" , 'lastname'))) {
                 $log->info = fullname($DB->get_record($ld->mtable, array('id'=>$log->info)), true);
@@ -4493,6 +4493,7 @@ function include_course_ajax($course, $usedmodules = array(), $enabledmodules =
         'courseid' => $course->id,
         'pagetype' => $PAGE->pagetype,
         'pagelayout' => $PAGE->pagelayout,
+        'subpage' => $PAGE->subpage,
         'regions' => $PAGE->blocks->get_regions(),
     );
     $PAGE->requires->yui_module('moodle-core-blocks', 'M.core_blocks.init_dragdrop', array($params), null, true);
index 349fd58..cfdbffa 100644 (file)
@@ -98,6 +98,9 @@ class recent_form extends moodleform {
 
             $mform->addElement('select', 'user', get_string('participants'), $options);
             $mform->setAdvanced('user');
+        } else {
+            // Default to no user.
+            $mform->addElement('hidden', 'user', 0);
         }
 
         $options = array(''=>get_string('allactivities'));
index 12371f8..e4ecce2 100644 (file)
@@ -167,7 +167,7 @@ switch($requestmethod) {
                         // We need to return strings after they've been through filters for multilang
                         $stringoptions = new stdClass;
                         $stringoptions->context = $coursecontext;
-                        echo json_encode(array('instancename' => format_string($module->name, true,  $stringoptions)));
+                        echo json_encode(array('instancename' => html_entity_decode(format_string($module->name, true,  $stringoptions))));
                         break;
                 }
                 break;
index 67fb06f..0d72b2c 100644 (file)
@@ -90,13 +90,14 @@ if (! $plugin_instance = $DB->get_record("enrol", array("id"=>$data->instanceid,
 $plugin = enrol_get_plugin('paypal');
 
 /// Open a connection back to PayPal to validate the data
+$paypaladdr = empty($CFG->usepaypalsandbox) ? 'www.paypal.com' : 'www.sandbox.paypal.com';
 $c = new curl();
 $options = array(
     'returntransfer' => true,
-    'httpheader' => array('application/x-www-form-urlencoded'),
+    'httpheader' => array('application/x-www-form-urlencoded', "Host: $paypaladdr"),
     'timeout' => 30,
+    'CURLOPT_HTTP_VERSION' => CURL_HTTP_VERSION_1_1,
 );
-$paypaladdr = empty($CFG->usepaypalsandbox) ? 'www.paypal.com' : 'www.sandbox.paypal.com';
 $location = "https://$paypaladdr/cgi-bin/webscr";
 $result = $c->post($location, $req, $options);
 
index 69b9b39..1f354c1 100644 (file)
@@ -207,4 +207,23 @@ class enrol_paypal_plugin extends enrol_plugin {
         return $OUTPUT->box(ob_get_clean());
     }
 
+    /**
+     * Gets an array of the user enrolment actions
+     *
+     * @param course_enrolment_manager $manager
+     * @param stdClass $ue A user enrolment object
+     * @return array An array of user_enrolment_actions
+     */
+    public function get_user_enrolment_actions(course_enrolment_manager $manager, $ue) {
+        $actions = array();
+        $context = $manager->get_context();
+        $instance = $ue->enrolmentinstance;
+        $params = $manager->get_moodlepage()->url->params();
+        $params['ue'] = $ue->id;
+        if ($this->allow_unenrol($instance) && has_capability("enrol/paypal:unenrol", $context)) {
+            $url = new moodle_url('/enrol/unenroluser.php', $params);
+            $actions[] = new user_enrolment_action(new pix_icon('t/delete', ''), get_string('unenrol', 'enrol'), $url, array('class'=>'unenrollink', 'rel'=>$ue->id));
+        }
+        return $actions;
+    }
 }
index 62c5ad6..9b937c0 100644 (file)
@@ -223,7 +223,7 @@ border-color:#cecece;
 }
 
 .path-grade-report-grader th {
-padding:2px 10px;
+padding:1px 10px;
 }
 
 .path-grade-report-grader span.inclusion-links {
index 90ef60f..4b4e805 100644 (file)
@@ -352,17 +352,21 @@ abstract class grade_report {
         global $CFG, $DB;
         static $hiding_affected = null;//array of items in this course affected by hiding
 
-        //if we're dealing with multiple users we need to know when we've moved on to a new user
+        // If we're dealing with multiple users we need to know when we've moved on to a new user.
         static $previous_userid = null;
 
+        // If we're dealing with multiple courses we need to know when we've moved on to a new course.
+        static $previous_courseid = null;
+
         if( $this->showtotalsifcontainhidden==GRADE_REPORT_SHOW_REAL_TOTAL_IF_CONTAINS_HIDDEN ) {
             return $finalgrade;
         }
 
-        //if we've moved on to another user don't return the previous user's affected grades
-        if ($previous_userid!=$this->user->id) {
+        // If we've moved on to another course or user, reload the grades.
+        if ($previous_userid != $this->user->id || $previous_courseid != $courseid) {
             $hiding_affected = null;
             $previous_userid = $this->user->id;
+            $previous_courseid = $courseid;
         }
 
         if( !$hiding_affected ) {
diff --git a/grade/tests/reportlib_test.php b/grade/tests/reportlib_test.php
new file mode 100644 (file)
index 0000000..48b0eaa
--- /dev/null
@@ -0,0 +1,197 @@
+<?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/>.
+
+/**
+ * Unit tests for grade/report/lib.php.
+ *
+ * @pacakge  core_grade
+ * @category phpunit
+ * @author   Andrew Davis
+ * @license  http://www.gnu.org/copyleft/gpl.html GNU Public License
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+global $CFG;
+require_once($CFG->dirroot.'/grade/lib.php');
+require_once($CFG->dirroot.'/grade/report/lib.php');
+
+/**
+ * A test class used to test grade_report, the abstract grade report parent class
+ */
+class grade_report_test extends grade_report {
+    public function __construct($courseid, $gpr, $context, $user) {
+        parent::__construct($courseid, $gpr, $context);
+        $this->user = $user;
+    }
+
+    /**
+     * A wrapper around blank_hidden_total() to allow test code to call it directly
+     */
+    public function blank_hidden_total($courseid, $courseitem, $finalgrade) {
+        return parent::blank_hidden_total($courseid, $courseitem, $finalgrade);
+    }
+
+    /**
+     * Implementation of the abstract method process_data()
+     */
+    public function process_data($data) {
+    }
+
+    /**
+     * Implementation of the abstract method process_action()
+     */
+    public function process_action($target, $action) {
+    }
+}
+
+/**
+ * Tests grade_report, the parent class for all grade reports.
+ */
+class gradereportlib_testcase extends advanced_testcase {
+
+    /**
+     * Tests grade_report::blank_hidden_total()
+     */
+    public function test_blank_hidden_total() {
+        global $DB;
+
+        $this->resetAfterTest(true);
+
+        $student = $this->getDataGenerator()->create_user();
+        $this->setUser($student);
+
+        // Create a course and two activities.
+        // One activity will be hidden.
+        $course = $this->getDataGenerator()->create_course();
+        $coursegradeitem = grade_item::fetch_course_item($course->id);
+        $coursecontext = context_course::instance($course->id);
+
+        $data = $this->getDataGenerator()->create_module('data', array('assessed' => 1, 'scale' => 100, 'course' => $course->id));
+        $datacm = get_coursemodule_from_id('data', $data->cmid);
+
+        $forum = $this->getDataGenerator()->create_module('forum', array('assessed' => 1, 'scale' => 100, 'course' => $course->id));
+        $forumcm = get_coursemodule_from_id('forum', $forum->cmid);
+
+        // Insert student grades for the two activities.
+        $gi = grade_item::fetch(array('itemtype' => 'mod', 'itemmodule' => 'data', 'iteminstance' => $data->id, 'courseid' => $course->id));
+        $datagrade = 50;
+        $grade_grade = new grade_grade();
+        $grade_grade->itemid = $gi->id;
+        $grade_grade->userid = $student->id;
+        $grade_grade->rawgrade = $datagrade;
+        $grade_grade->finalgrade = $datagrade;
+        $grade_grade->rawgrademax = 100;
+        $grade_grade->rawgrademin = 0;
+        $grade_grade->timecreated = time();
+        $grade_grade->timemodified = time();
+        $grade_grade->insert();
+
+        $gi = grade_item::fetch(array('itemtype' => 'mod', 'itemmodule' => 'forum', 'iteminstance' => $forum->id, 'courseid' => $course->id));
+        $forumgrade = 70;
+        $grade_grade = new grade_grade();
+        $grade_grade->itemid = $gi->id;
+        $grade_grade->userid = $student->id;
+        $grade_grade->rawgrade = $forumgrade;
+        $grade_grade->finalgrade = $forumgrade;
+        $grade_grade->rawgrademax = 100;
+        $grade_grade->rawgrademin = 0;
+        $grade_grade->timecreated = time();
+        $grade_grade->timemodified = time();
+        $grade_grade->insert();
+
+        // Hide the database activity.
+        set_coursemodule_visible($datacm->id, 0);
+
+        $gpr = new grade_plugin_return(array('type' => 'report', 'courseid' => $course->id));
+        $report = new grade_report_test($course->id, $gpr, $coursecontext, $student);
+
+        // Should return the supplied student total grade regardless of hiding.
+        $report->showtotalsifcontainhidden = GRADE_REPORT_SHOW_REAL_TOTAL_IF_CONTAINS_HIDDEN;
+        $this->assertEquals($datagrade + $forumgrade, $report->blank_hidden_total($course->id, $coursegradeitem, $datagrade + $forumgrade));
+
+        // Should blank the student total as course grade depends on a hidden item.
+        $report->showtotalsifcontainhidden = GRADE_REPORT_HIDE_TOTAL_IF_CONTAINS_HIDDEN;
+        $this->assertEquals(null, $report->blank_hidden_total($course->id, $coursegradeitem, $datagrade + $forumgrade));
+
+        // Should return the course total minus the hidden database activity grade.
+        $report->showtotalsifcontainhidden = GRADE_REPORT_SHOW_TOTAL_IF_CONTAINS_HIDDEN;
+        $this->assertEquals($forumgrade, $report->blank_hidden_total($course->id, $coursegradeitem, $datagrade + $forumgrade));
+
+        // Note: we cannot simply hide modules and call $report->blank_hidden_total() again.
+        // It stores grades in a static variable so $report->blank_hidden_total() will return incorrect totals
+        // In practice this isn't a problem. Grade visibility isn't altered mid-request outside of the unit tests.
+
+        // Add a second course to test:
+        // 1) How a course with no visible activities behaves.
+        // 2) That $report->blank_hidden_total() correctly moves on to the new course.
+        $course = $this->getDataGenerator()->create_course();
+        $coursegradeitem = grade_item::fetch_course_item($course->id);
+        $coursecontext = context_course::instance($course->id);
+
+        $data = $this->getDataGenerator()->create_module('data', array('assessed' => 1, 'scale' => 100, 'course' => $course->id));
+        $datacm = get_coursemodule_from_id('data', $data->cmid);
+
+        $forum = $this->getDataGenerator()->create_module('forum', array('assessed' => 1, 'scale' => 100, 'course' => $course->id));
+        $forumcm = get_coursemodule_from_id('forum', $forum->cmid);
+
+        $gi = grade_item::fetch(array('itemtype' => 'mod', 'itemmodule' => 'data', 'iteminstance' => $data->id, 'courseid' => $course->id));
+        $datagrade = 50;
+        $grade_grade = new grade_grade();
+        $grade_grade->itemid = $gi->id;
+        $grade_grade->userid = $student->id;
+        $grade_grade->rawgrade = $datagrade;
+        $grade_grade->finalgrade = $datagrade;
+        $grade_grade->rawgrademax = 100;
+        $grade_grade->rawgrademin = 0;
+        $grade_grade->timecreated = time();
+        $grade_grade->timemodified = time();
+        $grade_grade->insert();
+
+        $gi = grade_item::fetch(array('itemtype' => 'mod', 'itemmodule' => 'forum', 'iteminstance' => $forum->id, 'courseid' => $course->id));
+        $forumgrade = 70;
+        $grade_grade = new grade_grade();
+        $grade_grade->itemid = $gi->id;
+        $grade_grade->userid = $student->id;
+        $grade_grade->rawgrade = $forumgrade;
+        $grade_grade->finalgrade = $forumgrade;
+        $grade_grade->rawgrademax = 100;
+        $grade_grade->rawgrademin = 0;
+        $grade_grade->timecreated = time();
+        $grade_grade->timemodified = time();
+        $grade_grade->insert();
+
+        // Hide both activities.
+        set_coursemodule_visible($datacm->id, 0);
+        set_coursemodule_visible($forumcm->id, 0);
+
+        $gpr = new grade_plugin_return(array('type' => 'report', 'courseid' => $course->id));
+        $report = new grade_report_test($course->id, $gpr, $coursecontext, $student);
+
+        // Should return the supplied student total grade regardless of hiding.
+        $report->showtotalsifcontainhidden = GRADE_REPORT_SHOW_REAL_TOTAL_IF_CONTAINS_HIDDEN;
+        $this->assertEquals($datagrade + $forumgrade, $report->blank_hidden_total($course->id, $coursegradeitem, $datagrade + $forumgrade));
+
+        // Should blank the student total as course grade depends on a hidden item.
+        $report->showtotalsifcontainhidden = GRADE_REPORT_HIDE_TOTAL_IF_CONTAINS_HIDDEN;
+        $this->assertEquals(null, $report->blank_hidden_total($course->id, $coursegradeitem, $datagrade + $forumgrade));
+
+        // Should return the course total minus the hidden activity grades.
+        // They are both hidden so should return null.
+        $report->showtotalsifcontainhidden = GRADE_REPORT_SHOW_TOTAL_IF_CONTAINS_HIDDEN;
+        $this->assertEquals(null, $report->blank_hidden_total($course->id, $coursegradeitem, $datagrade + $forumgrade));
+    }
+}
index e239a5f..93ea1f7 100644 (file)
@@ -41,6 +41,7 @@ $string['databasehost'] = 'Servidor de la base de datos';
 $string['databasename'] = 'Nombre de la base de datos';
 $string['databasetypehead'] = 'Seleccione el controlador de la base de datos';
 $string['dataroot'] = 'Directorio de Datos';
+$string['datarootpermission'] = 'Permiso directorios de datos';
 $string['dbprefix'] = 'Prefijo de tablas';
 $string['dirroot'] = 'Directorio Moodle';
 $string['environmenthead'] = 'Comprobando su entorno';
index f7c639b..eea0465 100644 (file)
@@ -32,4 +32,4 @@ defined('MOODLE_INTERNAL') || die();
 
 $string['parentlanguage'] = '';
 $string['thisdirection'] = 'ltr';
-$string['thislanguage'] = 'Español - Mexico';
+$string['thislanguage'] = 'Español - México';
index 1a2c751..6c8ae80 100644 (file)
@@ -48,7 +48,6 @@ $string['disableall_help'] = 'Temporarily disable all notifications except those
 $string['disabled'] = 'Messaging is disabled on this site';
 $string['disallowed'] = 'Disallowed';
 $string['discussion'] = 'Discussion';
-$string['editmymessage'] = 'Messaging';
 $string['emailmessages'] = 'Email messages when I am offline';
 $string['emailtagline'] = 'This is a copy of a message sent to you at "{$a->sitename}". Go to {$a->url} to reply.';
 $string['emptysearchstring'] = 'You must search for something';
index f21667f..4d4dd8c 100644 (file)
@@ -30,7 +30,9 @@ $string['availability'] = 'Availability';
 $string['checkforupdates'] = 'Check for available updates';
 $string['checkforupdateslast'] = 'Last check done on {$a}';
 $string['displayname'] = 'Plugin name';
+$string['err_response_curl'] = 'Unable to fetch available updates data - unexpected cURL error.';
 $string['err_response_format_version'] = 'Unexpected version of the response format. Please try to re-check for available updates.';
+$string['err_response_http_code'] = 'Unable to fetch available updates data - unexpected HTTP response code.';
 $string['filterall'] = 'Show all';
 $string['filtercontribonly'] = 'Show contributions only';
 $string['filtercontribonlyactive'] = 'Showing contributions only';
@@ -41,10 +43,14 @@ $string['nonehighlighted'] = 'No plugins require your attention now';
 $string['nonehighlightedinfo'] = 'Display the list of all installed plugins anyway';
 $string['noneinstalled'] = 'No plugins of this type are installed';
 $string['notes'] = 'Notes';
+$string['notdownloadable'] = 'Can not download the package';
+$string['notdownloadable_help'] = 'ZIP package with the update can not be downloaded automatically. Please refer to the documentation page for more help.';
+$string['notdownloadable_link'] = 'admin/mdeploy/notdownloadable';
 $string['notwritable'] = 'Plugin files not writable';
 $string['notwritable_help'] = 'You have enabled automatic updates deployment and there is available update for this plugin. However, the plugin files are not writable by the web server so the update can not be installed at the moment.
 
 Make the plugin folder and all its contents writable to be able to install the available update automatically.';
+$string['notwritable_link'] = 'admin/mdeploy/notwritable';
 $string['numtotal'] = 'Installed: {$a}';
 $string['numdisabled'] = 'Disabled: {$a}';
 $string['numextension'] = 'Contributions: {$a}';
index ec222d5..6bc53c2 100644 (file)
@@ -2956,8 +2956,13 @@ function get_user_roles_in_course($userid, $courseid) {
 function user_can_assign(context $context, $targetroleid) {
     global $DB;
 
-    // first check if user has override capability
-    // if not return false;
+    // First check to see if the user is a site administrator.
+    if (is_siteadmin()) {
+        return true;
+    }
+
+    // Check if user has override capability.
+    // If not return false.
     if (!has_capability('moodle/role:assign', $context)) {
         return false;
     }
index 041190a..470106d 100644 (file)
@@ -30,6 +30,7 @@ require_once(dirname(__FILE__) . '/../../config.php');
 $courseid = required_param('courseid', PARAM_INT);
 $pagelayout = required_param('pagelayout', PARAM_ALPHAEXT);
 $pagetype = required_param('pagetype', PARAM_ALPHAEXT);
+$subpage = optional_param('subpage', '', PARAM_ALPHANUMEXT);
 $cmid = optional_param('cmid', null, PARAM_INT);
 $action = optional_param('action', '', PARAM_ALPHA);
 // Params for blocks-move actions
@@ -51,6 +52,7 @@ require_sesskey();
 
 // Setting layout to replicate blocks configuration for the page we edit
 $PAGE->set_pagelayout($pagelayout);
+$PAGE->set_subpage($subpage);
 echo $OUTPUT->header(); // send headers
 
 switch ($action) {
index 454bc7e..bd917ba 100644 (file)
@@ -1802,7 +1802,7 @@ function add_to_log($courseid, $module, $action, $url='', $info='', $cm=0, $user
     $timenow = time();
     $info = $info;
     if (!empty($url)) { // could break doing html_entity_decode on an empty var.
-        $url = html_entity_decode($url);
+        $url = html_entity_decode($url, ENT_QUOTES, 'UTF-8');
     } else {
         $url = '';
     }
index 7242366..4b95964 100644 (file)
@@ -1501,5 +1501,17 @@ function xmldb_main_upgrade($oldversion) {
         upgrade_main_savepoint(true, 2012112100.00);
     }
 
+    if ($oldversion < 2012120300.01) {
+        // Make sure site-course has format='site' //MDL-36840
+
+        if ($SITE->format !== 'site') {
+            $DB->set_field('course', 'format', 'site', array('id' => $SITE->id));
+            $SITE->format = 'site';
+        }
+
+        // Main savepoint reached
+        upgrade_main_savepoint(true, 2012120300.01);
+    }
+
     return true;
 }
index e096c87..8deccf9 100644 (file)
@@ -172,7 +172,7 @@ class oracle_sql_generator extends sql_generator {
     public function getTypeSQL($xmldb_type, $xmldb_length=null, $xmldb_decimals=null) {
 
         switch ($xmldb_type) {
-            case XMLDB_TYPE_INTEGER:    // From http://www.postgresql.org/docs/7.4/interactive/datatype.html
+            case XMLDB_TYPE_INTEGER:    // See http://www.acs.ilstu.edu/docs/oracle/server.101/b10759/sql_elements001.htm#sthref86.
                 if (empty($xmldb_length)) {
                     $xmldb_length = 10;
                 }
index 4aae9ce..61b161c 100644 (file)
@@ -172,7 +172,7 @@ abstract class pdo_moodle_database extends moodle_database {
      * Function to print/save/ignore debugging messages related to SQL queries.
      */
     protected function debug_query($sql, $params = null) {
-        echo '<hr /> (', $this->get_dbtype(), '): ',  htmlentities($sql);
+        echo '<hr /> (', $this->get_dbtype(), '): ',  htmlentities($sql, ENT_QUOTES, 'UTF-8');
         if($params) {
             echo ' (parameters ';
             print_r($params);
index 6c935ef..ab120b3 100644 (file)
@@ -2286,7 +2286,7 @@ function send_file($path, $filename, $lifetime = 'default' , $filter=0, $pathiss
             $options = new stdClass();
             $options->newlines = false;
             $options->noclean = true;
-            $text = htmlentities($pathisstring ? $path : implode('', file($path)));
+            $text = htmlentities($pathisstring ? $path : implode('', file($path)), ENT_QUOTES, 'UTF-8');
             $output = '<pre>'. format_text($text, FORMAT_MOODLE, $options, $COURSE->id) .'</pre>';
 
             readstring_accel($output, $mimetype, false);
index d64b619..03c8c33 100644 (file)
@@ -1893,7 +1893,7 @@ function qf_errorHandler(element, _qfMsg) {
             list($jsArr,$element)=$jsandelement;
             //end of fix
             $escapedElementName = preg_replace_callback(
-                '/[_\[\]]/',
+                '/[_\[\]-]/',
                 create_function('$matches', 'return sprintf("_%2x",ord($matches[0]));'),
                 $elementName);
             $js .= '
index 5cd052d..87c494f 100644 (file)
@@ -886,7 +886,9 @@ class grade_category extends grade_object {
                 $droppedsomething = false;
 
                 $grade_keys = array_keys($grade_values);
-                if (count($grade_keys) === 0) {
+                $gradekeycount = count($grade_keys);
+
+                if ($gradekeycount === 0) {
                     //We've dropped all grade items
                     break;
                 }
@@ -912,7 +914,7 @@ class grade_category extends grade_object {
                 // Now iterate over the remaining grade items
                 // We're looking for other grade items with the same grade value but a higher grademax
                 $i = 1;
-                while ($originalindex+$i < count($grade_keys)) {
+                while ($originalindex + $i < $gradekeycount) {
 
                     $possibleitemid = $grade_keys[$originalindex+$i];
                     $i++;
index c0878b3..6572ecd 100644 (file)
@@ -426,6 +426,7 @@ M.util.init_select_autosubmit = function(Y, formid, selectid, nothing) {
                     if (e.button == 1) {
                         buttonflag = 1;
                     }
+                    paramobject.lastindex = select.get('selectedIndex');
                 };
 
                 var changedown = function(e, paramobject) {
@@ -433,6 +434,7 @@ M.util.init_select_autosubmit = function(Y, formid, selectid, nothing) {
                         if(e.keyCode == 13) {
                             form.submit();
                         }
+                        paramobject.lastindex = select.get('selectedIndex');
                     }
                 }
 
index 9236a11..9a8ddf1 100644 (file)
@@ -1134,7 +1134,7 @@ function clean_param($param, $type) {
 
         case PARAM_TIMEZONE:    //can be int, float(with .5 or .0) or string seperated by '/' and can have '-_'
             $param = fix_utf8($param);
-            $timezonepattern = '/^(([+-]?(0?[0-9](\.[5|0])?|1[0-3]|1[0-2]\.5))|(99)|[[:alnum:]]+(\/?[[:alpha:]_-])+)$/';
+            $timezonepattern = '/^(([+-]?(0?[0-9](\.[5|0])?|1[0-3](\.0)?|1[0-2]\.5))|(99)|[[:alnum:]]+(\/?[[:alpha:]_-])+)$/';
             if (preg_match($timezonepattern, $param)) {
                 return $param;
             } else {
index 1f2fa1d..b4e69c6 100644 (file)
@@ -3389,9 +3389,9 @@ class settings_navigation extends navigation_node {
                         continue;
                     }
                     if ($type->modclass == MOD_CLASS_RESOURCE) {
-                        $resources[html_entity_decode($type->type)] = $type->typestr;
+                        $resources[html_entity_decode($type->type, ENT_QUOTES, 'UTF-8')] = $type->typestr;
                     } else {
-                        $activities[html_entity_decode($type->type)] = $type->typestr;
+                        $activities[html_entity_decode($type->type, ENT_QUOTES, 'UTF-8')] = $type->typestr;
                     }
                 }
             } else {
@@ -3978,8 +3978,8 @@ class settings_navigation extends navigation_node {
 
         // Messaging
         if (($currentuser && has_capability('moodle/user:editownmessageprofile', $systemcontext)) || (!isguestuser($user) && has_capability('moodle/user:editmessageprofile', $usercontext) && !is_primary_admin($user->id))) {
-            $url = new moodle_url('/message/edit.php', array('id'=>$user->id, 'course'=>$course->id));
-            $usersetting->add(get_string('editmymessage', 'message'), $url, self::TYPE_SETTING);
+            $url = new moodle_url('/message/edit.php', array('id'=>$user->id));
+            $usersetting->add(get_string('messaging', 'message'), $url, self::TYPE_SETTING);
         }
 
         // Blogs
@@ -4275,7 +4275,7 @@ class navigation_json {
         }
 
         if ($child->forcetitle || $child->title !== $child->text) {
-            $attributes['title'] = htmlentities($child->title);
+            $attributes['title'] = htmlentities($child->title, ENT_QUOTES, 'UTF-8');
         }
         if (array_key_exists($child->key.':'.$child->type, $this->expandable)) {
             $attributes['expandable'] = $child->key;
index da1761b..dcd0875 100644 (file)
@@ -364,6 +364,9 @@ class theme_config {
         } else if ($themename == theme_config::DEFAULT_THEME) {
             throw new coding_exception('Default theme '.theme_config::DEFAULT_THEME.' not available or broken!');
 
+        } else if ($config = theme_config::find_theme_config($CFG->theme, $settings)) {
+            return new theme_config($config);
+
         } else {
             // bad luck, the requested theme has some problems - admin see details in theme config
             return new theme_config(theme_config::find_theme_config(theme_config::DEFAULT_THEME, $settings));
@@ -618,20 +621,34 @@ class theme_config {
 
         $urls = array();
 
+        $svg = $this->use_svg_icons();
+
         if ($rev > -1) {
+            $url = new moodle_url("$CFG->httpswwwroot/theme/styles.php");
             if (check_browser_version('MSIE', 5)) {
                 // We need to split the CSS files for IE
-                $urls[] = new moodle_url($CFG->httpswwwroot.'/theme/styles.php', array('theme'=>$this->name,'rev'=>$rev, 'type'=>'plugins'));
-                $urls[] = new moodle_url($CFG->httpswwwroot.'/theme/styles.php', array('theme'=>$this->name,'rev'=>$rev, 'type'=>'parents'));
-                $urls[] = new moodle_url($CFG->httpswwwroot.'/theme/styles.php', array('theme'=>$this->name,'rev'=>$rev, 'type'=>'theme'));
+                $urls[] = new moodle_url($url, array('theme' => $this->name,'rev' => $rev, 'type' => 'plugins', 'svg' => '0'));
+                $urls[] = new moodle_url($url, array('theme' => $this->name,'rev' => $rev, 'type' => 'parents', 'svg' => '0'));
+                $urls[] = new moodle_url($url, array('theme' => $this->name,'rev' => $rev, 'type' => 'theme', 'svg' => '0'));
             } else {
                 if (!empty($CFG->slasharguments)) {
-                    $url = new moodle_url("$CFG->httpswwwroot/theme/styles.php");
-                    $url->set_slashargument('/'.$this->name.'/'.$rev.'/all', 'noparam', true);
-                    $urls[] = $url;
+                    $slashargs = '/'.$this->name.'/'.$rev.'/all';
+                    if (!$svg) {
+                        // We add a simple /_s to the start of the path.
+                        // The underscore is used to ensure that it isn't a valid theme name.
+                        $slashargs = '/_s'.$slashargs;
+                    }
+                    $url->set_slashargument($slashargs, 'noparam', true);
                 } else {
-                    $urls[] = new moodle_url($CFG->httpswwwroot.'/theme/styles.php', array('theme'=>$this->name,'rev'=>$rev, 'type'=>'all'));
+                    $params = array('theme' => $this->name,'rev' => $rev, 'type' => 'all');
+                    if (!$svg) {
+                        // We add an SVG param so that we know not to serve SVG images.
+                        // We do this because all modern browsers support SVG and this param will one day be removed.
+                        $params['svg'] = '0';
+                    }
+                    $url->params($params);
                 }
+                $urls[] = $url;
             }
         } else {
             // find out the current CSS and cache it now for 5 seconds
@@ -641,7 +658,11 @@ class theme_config {
                 define('THEME_DESIGNER_CACHE_LIFETIME', 4); // this can be also set in config.php
             }
             $candidatedir = "$CFG->cachedir/theme/$this->name";
-            $candidatesheet = "$candidatedir/designer.ser";
+            if ($svg) {
+                $candidatesheet = "$candidatedir/designer.ser";
+            } else {
+                $candidatesheet = "$candidatedir/designer_nosvg.ser";
+            }
             $rebuild = true;
             if (file_exists($candidatesheet) and filemtime($candidatesheet) > time() - THEME_DESIGNER_CACHE_LIFETIME) {
                 if ($css = file_get_contents($candidatesheet)) {
@@ -674,8 +695,12 @@ class theme_config {
                 ignore_user_abort($prevabort);
             }
 
-            $baseurl = $CFG->httpswwwroot.'/theme/styles_debug.php';
-
+            $baseurl = new moodle_url($CFG->httpswwwroot.'/theme/styles_debug.php');
+            if (!$svg) {
+                // We add an SVG param so that we know not to serve SVG images.
+                // We do this because all modern browsers support SVG and this param will one day be removed.
+                $baseurl->param('svg', '0');
+            }
             if (check_browser_version('MSIE', 5)) {
                 // lalala, IE does not allow more than 31 linked CSS files from main document
                 $urls[] = new moodle_url($baseurl, array('theme'=>$this->name, 'type'=>'ie', 'subtype'=>'plugins'));
@@ -948,12 +973,6 @@ class theme_config {
     public function post_process($css) {
         // now resolve all image locations
         if (preg_match_all('/\[\[pix:([a-z_]+\|)?([^\]]+)\]\]/', $css, $matches, PREG_SET_ORDER)) {
-            // We are going to disable the use of SVG images when available in CSS background-image properties
-            // as support for it in browsers is at best quirky.
-            // When we choose to support SVG in background css we will need to remove this code and implement a solution that is
-            // either consistent or varies the URL for serving CSS depending upon SVG being used if available, or not.
-            $originalsvguse = $this->use_svg_icons();
-            $this->force_svg_use(false);
             $replaced = array();
             foreach ($matches as $match) {
                 if (isset($replaced[$match[0]])) {
@@ -967,7 +986,6 @@ class theme_config {
                 $imageurl = preg_replace('|^http.?://[^/]+|', '', $imageurl);
                 $css = str_replace($match[0], $imageurl, $css);
             }
-            $this->force_svg_use($originalsvguse);
         }
 
         // now resolve all theme settings or do any other postprocessing
@@ -1145,10 +1163,11 @@ class theme_config {
      * Forces the usesvg setting to either true or false, avoiding any decision making.
      *
      * This function should only ever be used when absolutely required, and before any generation of image URL's has occurred.
+     * DO NOT ABUSE THIS FUNCTION... not that you'd want to right ;)
      *
      * @param bool $setting True to force the use of svg when available, null otherwise.
      */
-    private function force_svg_use($setting) {
+    public function force_svg_use($setting) {
         $this->usesvg = (bool)$setting;
     }
 
index 3d7f410..0e8052d 100644 (file)
@@ -1565,9 +1565,15 @@ class core_renderer extends renderer_base {
             $output .= html_writer::label($select->label, $select->attributes['id'], false, $select->labelattributes);
         }
 
-        $select->attributes['class'] = 'autosubmit';
+        $classes = array();
+        if (!$select->showbutton) {
+            $classes[] = 'autosubmit';
+        }
         if ($select->class) {
-            $select->attributes['class'] .= ' ' . $select->class;
+            $classes[] = $select->class;
+        }
+        if (count($classes)) {
+            $select->attributes['class'] = implode(' ', $classes);
         }
 
         if ($select->helpicon instanceof help_icon) {
index 7383d7b..b740093 100644 (file)
@@ -826,7 +826,11 @@ class available_update_checker {
         require_once($CFG->libdir.'/filelib.php');
 
         $curl = new curl(array('proxy' => true));
-        $response = $curl->post($this->prepare_request_url(), $this->prepare_request_params());
+        $response = $curl->post($this->prepare_request_url(), $this->prepare_request_params(), $this->prepare_request_options());
+        $curlerrno = $curl->get_errno();
+        if (!empty($curlerrno)) {
+            throw new available_update_checker_exception('err_response_curl', 'cURL error '.$curlerrno.': '.$curl->error);
+        }
         $curlinfo = $curl->get_info();
         if ($curlinfo['http_code'] != 200) {
             throw new available_update_checker_exception('err_response_http_code', $curlinfo['http_code']);
@@ -1069,6 +1073,29 @@ class available_update_checker {
         return $params;
     }
 
+    /**
+     * Returns the list of cURL options to use when fetching available updates data
+     *
+     * @return array of (string)param => (string)value
+     */
+    protected function prepare_request_options() {
+        global $CFG;
+
+        $options = array(
+            'CURLOPT_SSL_VERIFYHOST' => 2,      // this is the default in {@link curl} class but just in case
+            'CURLOPT_SSL_VERIFYPEER' => true,
+        );
+
+        $cacertfile = $CFG->dataroot.'/moodleorgca.crt';
+        if (is_readable($cacertfile)) {
+            // Do not use CA certs provided by the operating system. Instead,
+            // use this CA cert to verify the updates provider.
+            $options['CURLOPT_CAINFO'] = $cacertfile;
+        }
+
+        return $options;
+    }
+
     /**
      * Returns the current timestamp
      *
@@ -1223,19 +1250,28 @@ class available_update_checker {
                 foreach ($componentupdates as $componentupdate) {
                     if ($componentupdate->version == $componentchange['version']) {
                         if ($component == 'core') {
-                            // in case of 'core' this is enough, we already know that the
-                            // $componentupdate is a real update with higher version
-                            $notifications[] = $componentupdate;
+                            // In case of 'core', we already know that the $componentupdate
+                            // is a real update with higher version ({@see self::get_update_info()}).
+                            // We just perform additional check for the release property as there
+                            // can be two Moodle releases having the same version (e.g. 2.4.0 and 2.5dev shortly
+                            // after the release). We can do that because we have the release info
+                            // always available for the core.
+                            if ((string)$componentupdate->release === (string)$componentchange['release']) {
+                                $notifications[] = $componentupdate;
+                            }
                         } else {
-                            // use the plugin_manager to check if the reported $componentchange
-                            // is a real update with higher version. such a real update must be
-                            // present in the 'availableupdates' property of one of the component's
-                            // available_update_info object
+                            // Use the plugin_manager to check if the detected $componentchange
+                            // is a real update with higher version. That is, the $componentchange
+                            // is present in the array of {@link available_update_info} objects
+                            // returned by the plugin's available_updates() method.
                             list($plugintype, $pluginname) = normalize_component($component);
-                            if (!empty($plugins[$plugintype][$pluginname]->availableupdates)) {
-                                foreach ($plugins[$plugintype][$pluginname]->availableupdates as $availableupdate) {
-                                    if ($availableupdate->version == $componentchange['version']) {
-                                        $notifications[] = $componentupdate;
+                            if (!empty($plugins[$plugintype][$pluginname])) {
+                                $availableupdates = $plugins[$plugintype][$pluginname]->available_updates();
+                                if (!empty($availableupdates)) {
+                                    foreach ($availableupdates as $availableupdate) {
+                                        if ($availableupdate->version == $componentchange['version']) {
+                                            $notifications[] = $componentupdate;
+                                        }
                                     }
                                 }
                             }
@@ -1562,6 +1598,10 @@ class available_update_deployer {
             $impediments['missingdownloadmd5'] = true;
         }
 
+        if (!empty($info->download) and !$this->update_downloadable($info->download)) {
+            $impediments['notdownloadable'] = true;
+        }
+
         if (!$this->component_writable($info->component)) {
             $impediments['notwritable'] = true;
         }
@@ -1660,6 +1700,28 @@ class available_update_deployer {
             'returnurl' => $upgradeurl->out(true),
         );
 
+        if (!empty($CFG->proxyhost)) {
+            // MDL-36973 - Beware - we should call just !is_proxybypass() here. But currently, our
+            // cURL wrapper class does not do it. So, to have consistent behaviour, we pass proxy
+            // setting regardless the $CFG->proxybypass setting. Once the {@link curl} class is
+            // fixed, the condition should be amended.
+            if (true or !is_proxybypass($info->download)) {
+                if (empty($CFG->proxyport)) {
+                    $params['proxy'] = $CFG->proxyhost;
+                } else {
+                    $params['proxy'] = $CFG->proxyhost.':'.$CFG->proxyport;
+                }
+
+                if (!empty($CFG->proxyuser) and !empty($CFG->proxypassword)) {
+                    $params['proxyuserpwd'] = $CFG->proxyuser.':'.$CFG->proxypassword;
+                }
+
+                if (!empty($CFG->proxytype)) {
+                    $params['proxytype'] = $CFG->proxytype;
+                }
+            }
+        }
+
         $widget = new single_button(
             new moodle_url('/mdeploy.php', $params),
             get_string('updateavailableinstall', 'core_admin'),
@@ -1890,6 +1952,40 @@ class available_update_deployer {
         return $this->directory_writable($directory);
     }
 
+    /**
+     * Checks if the mdeploy.php will be able to fetch the ZIP from the given URL
+     *
+     * This is mainly supposed to check if the transmission over HTTPS would
+     * work. That is, if the CA certificates are present at the server.
+     *
+     * @param string $downloadurl the URL of the ZIP package to download
+     * @return bool
+     */
+    protected function update_downloadable($downloadurl) {
+        global $CFG;
+
+        $curloptions = array(
+            'CURLOPT_SSL_VERIFYHOST' => 2,      // this is the default in {@link curl} class but just in case
+            'CURLOPT_SSL_VERIFYPEER' => true,
+        );
+
+        $cacertfile = $CFG->dataroot.'/moodleorgca.crt';
+        if (is_readable($cacertfile)) {
+            // Do not use CA certs provided by the operating system. Instead,
+            // use this CA cert to verify the updates provider.
+            $curloptions['CURLOPT_CAINFO'] = $cacertfile;
+        }
+
+        $curl = new curl(array('proxy' => true));
+        $result = $curl->head($downloadurl, $curloptions);
+        $errno = $curl->get_errno();
+        if (empty($errno)) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
     /**
      * Checks if the directory and all its contents (recursively) is writable
      *
index 123c70e..2fb6f32 100644 (file)
@@ -1122,6 +1122,10 @@ function get_moodle_cookie() {
 function session_set_user($user) {
     $_SESSION['USER'] = $user;
     unset($_SESSION['USER']->description); // conserve memory
+    if (isset($_SESSION['USER']->lang)) {
+        // Make sure it is a valid lang pack name.
+        $_SESSION['USER']->lang = clean_param($_SESSION['USER']->lang, PARAM_LANG);
+    }
     sesskey(); // init session key
 
     if (PHPUNIT_TEST) {
index 33c014c..731d725 100644 (file)
@@ -943,9 +943,23 @@ class moodlelib_testcase extends advanced_testcase {
             '0'                              => '0',
             '0.0'                            => '0.0',
             '0.5'                            => '0.5',
+            '9.0'                            => '9.0',
+            '-9.0'                           => '-9.0',
+            '+9.0'                           => '+9.0',
+            '9.5'                            => '9.5',
+            '-9.5'                           => '-9.5',
+            '+9.5'                           => '+9.5',
+            '12.0'                           => '12.0',
+            '-12.0'                          => '-12.0',
+            '+12.0'                          => '+12.0',
+            '12.5'                           => '12.5',
             '-12.5'                          => '-12.5',
             '+12.5'                          => '+12.5',
+            '13.0'                           => '13.0',
+            '-13.0'                          => '-13.0',
+            '+13.0'                          => '+13.0',
             '13.5'                           => '',
+            '+13.5'                          => '',
             '-13.5'                          => '',
             '0.2'                            => '');
 
index d36095e..c1d1d31 100644 (file)
@@ -265,15 +265,17 @@ class webdav_client {
      * Public method get
      *
      * Gets a file from a webdav collection.
-     * @param string path, string &buffer
-     * @return status code and &$buffer (by reference) with response data from server on success. False on error.
+     * @param string $path the path to the file on the webdav server
+     * @param string &$buffer the buffer to store the data in
+     * @param resource $fp optional if included, the data is written directly to this resource and not to the buffer
+     * @return string|bool status code and &$buffer (by reference) with response data from server on success. False on error.
      */
-    function get($path, &$buffer) {
+    function get($path, &$buffer, $fp = null) {
         $this->_path = $this->translate_uri($path);
         $this->header_unset();
         $this->create_basic_request('GET');
         $this->send_request();
-        $this->get_respond();
+        $this->get_respond($fp);
         $response = $this->process_respond();
 
         $http_version = $response['status']['http-version'];
@@ -283,8 +285,13 @@ class webdav_client {
                 // seems to be http ... proceed
                 // We expect a 200 code
                 if ($response['status']['status-code'] == 200 ) {
-                    $this->_error_log('returning buffer with ' . strlen($response['body']) . ' bytes.');
-                    $buffer = $response['body'];
+                    if (!is_null($fp)) {
+                        $stat = fstat($fp);
+                        $this->_error_log('file created with ' . $stat['size'] . ' bytes.');
+                    } else {
+                        $this->_error_log('returning buffer with ' . strlen($response['body']) . ' bytes.');
+                        $buffer = $response['body'];
+                    }
                 }
                 return $response['status']['status-code'];
             }
@@ -387,27 +394,24 @@ class webdav_client {
      * Gets a file from a collection into local filesystem.
      *
      * fopen() is used.
-     * @param string srcpath, string localpath
-     * @return true on success. false on error.
+     * @param string $srcpath
+     * @param string $localpath
+     * @return bool true on success. false on error.
      */
     function get_file($srcpath, $localpath) {
 
-        if ($this->get($srcpath, $buffer)) {
-            // convert utf-8 filename to iso-8859-1
+        $localpath = $this->utf_decode_path($localpath);
 
-            $localpath = $this->utf_decode_path($localpath);
-
-            $handle = fopen ($localpath, 'w');
-            if ($handle) {
-                fwrite($handle, $buffer);
-                fclose($handle);
+        $handle = fopen($localpath, 'wb');
+        if ($handle) {
+            $unused = '';
+            $ret = $this->get($srcpath, $unused, $handle);
+            fclose($handle);
+            if ($ret) {
                 return true;
-            } else {
-                return false;
             }
-        } else {
-            return false;
         }
+        return false;
     }
 
     /**
@@ -1447,8 +1451,9 @@ EOD;
      * This routine is the weakest part of this class, because it very depends how php does handle a socket stream.
      * If the stream is blocked for some reason php is blocked as well.
      * @access private
+     * @param resource $fp optional the file handle to write the body content to (stored internally in the '_body' if not set)
      */
-    private function get_respond() {
+    private function get_respond($fp = null) {
         $this->_error_log('get_respond()');
         // init vars (good coding style ;-)
         $buffer = '';
@@ -1509,7 +1514,8 @@ EOD;
                     $read = 0;
                     // Reading the chunk in one bite is not secure, we read it byte by byte.
                     while ($read < $chunk_size) {
-                        $buffer .= fread($this->sock, 1);
+                        $chunk = fread($this->sock, 1);
+                        self::update_file_or_buffer($chunk, $fp, $buffer);
                         $read++;
                     }
                 }
@@ -1525,21 +1531,20 @@ EOD;
             if ($matches[1] <= $max_chunk_size ) {
                 // only read something if Content-Length is bigger than 0
                 if ($matches[1] > 0 ) {
-                    $buffer = fread($this->sock, $matches[1]);
-                    $loadsize = strlen($buffer);
+                    $chunk = fread($this->sock, $matches[1]);
+                    $loadsize = strlen($chunk);
                     //did we realy get the full length?
                     if ($loadsize < $matches[1]) {
                         $max_chunk_size = $loadsize;
                         do {
-                            $mod = $max_chunk_size % ($matches[1] - strlen($buffer));
-                            $chunk_size = ($mod == $max_chunk_size ? $max_chunk_size : $matches[1] - strlen($buffer));
-                            $buffer .= fread($this->sock, $chunk_size);
-                            $this->_error_log('mod: ' . $mod . ' chunk: ' . $chunk_size . ' total: ' . strlen($buffer));
+                            $mod = $max_chunk_size % ($matches[1] - strlen($chunk));
+                            $chunk_size = ($mod == $max_chunk_size ? $max_chunk_size : $matches[1] - strlen($chunk));
+                            $chunk .= fread($this->sock, $chunk_size);
+                            $this->_error_log('mod: ' . $mod . ' chunk: ' . $chunk_size . ' total: ' . strlen($chunk));
                         } while ($mod == $max_chunk_size);
-                        break;
-                    } else {
-                        break;
                     }
+                    self::update_file_or_buffer($chunk, $fp, $buffer);
+                    break;
                 } else {
                     $buffer = '';
                     break;
@@ -1548,20 +1553,23 @@ EOD;
 
             // data is to big to handle it as one. Get it chunk per chunk...
             //trying to get the full length of max_chunk_size
-            $buffer = fread($this->sock, $max_chunk_size);
-            $loadsize = strlen($buffer);
+            $chunk = fread($this->sock, $max_chunk_size);
+            $loadsize = strlen($chunk);
+            self::update_file_or_buffer($chunk, $fp, $buffer);
             if ($loadsize < $max_chunk_size) {
                 $max_chunk_size = $loadsize;
             }
             do {
-                $mod = $max_chunk_size % ($matches[1] - strlen($buffer));
-                $chunk_size = ($mod == $max_chunk_size ? $max_chunk_size : $matches[1] - strlen($buffer));
-                $buffer .= fread($this->sock, $chunk_size);
-                $this->_error_log('mod: ' . $mod . ' chunk: ' . $chunk_size . ' total: ' . strlen($buffer));
+                $mod = $max_chunk_size % ($matches[1] - $loadsize);
+                $chunk_size = ($mod == $max_chunk_size ? $max_chunk_size : $matches[1] - $loadsize);
+                $chunk = fread($this->sock, $chunk_size);
+                self::update_file_or_buffer($chunk, $fp, $buffer);
+                $loadsize += strlen($chunk);
+                $this->_error_log('mod: ' . $mod . ' chunk: ' . $chunk_size . ' total: ' . $loadsize);
             } while ($mod == $max_chunk_size);
-            $loadsize = strlen($buffer);
             if ($loadsize < $matches[1]) {
-                $buffer .= fread($this->sock, $matches[1] - $loadsize);
+                $chunk = fread($this->sock, $matches[1] - $loadsize);
+                self::update_file_or_buffer($chunk, $fp, $buffer);
             }
             break;
 
@@ -1577,7 +1585,8 @@ EOD;
             $this->_error_log('reading until feof...' . $header);
             socket_set_timeout($this->sock, 0, 0);
             while (!feof($this->sock)) {
-                $buffer .= fread($this->sock, 4096);
+                $chunk = fread($this->sock, 4096);
+                self::update_file_or_buffer($chunk, $fp, $buffer);
             }
             // renew the socket timeout...does it do something ???? Is it needed. More debugging needed...
             socket_set_timeout($this->sock, $this->_socket_timeout, 0);
@@ -1591,6 +1600,19 @@ EOD;
 
     }
 
+    /**
+     * Write the chunk to the file if $fp is set, otherwise append the data to the buffer
+     * @param string $chunk the data to add
+     * @param resource $fp the file handle to write to (or null)
+     * @param string &$buffer the buffer to append to (if $fp is null)
+     */
+    static private function update_file_or_buffer($chunk, $fp, &$buffer) {
+        if ($fp) {
+            fwrite($fp, $chunk);
+        } else {
+            $buffer .= $chunk;
+        }
+    }
 
     /**
      * Private method process_respond
index 0975b87..edb655f 100644 (file)
@@ -99,7 +99,13 @@ YUI.add('moodle-core-blocks', function(Y) {
         },
 
         get_block_region : function(node) {
-            return node.ancestor('div.'+CSS.BLOCKREGION).get('id').replace(/region/i, 'side');
+            var region = node.ancestor('div.'+CSS.BLOCKREGION).get('id').replace(/region-/i, '');
+            if (Y.Array.indexOf(this.get('regions'), region) === -1) {
+                // Must be standard side-X
+                return 'side-' + region;
+            }
+            // Perhaps custom region
+            return region;
         },
 
         get_region_id : function(node) {
@@ -207,6 +213,7 @@ YUI.add('moodle-core-blocks', function(Y) {
                 courseid : this.get('courseid'),
                 pagelayout : this.get('pagelayout'),
                 pagetype : this.get('pagetype'),
+                subpage : this.get('subpage'),
                 action : 'move',
                 bui_moveid : this.get_block_id(dragnode),
                 bui_newregion : this.get_block_region(dropnode)
@@ -262,6 +269,9 @@ YUI.add('moodle-core-blocks', function(Y) {
             pagetype : {
                 value : null
             },
+            subpage : {
+                value : null
+            },
             regions : {
                 value : null
             }
index 9fba3ba..8d7884b 100644 (file)
@@ -171,6 +171,9 @@ class input_manager extends singleton_pattern {
         $supportedoptions = array(
             array('', 'passfile', input_manager::TYPE_FILE, 'File name of the passphrase file (HTTP access only)'),
             array('', 'password', input_manager::TYPE_RAW, 'Session passphrase (HTTP access only)'),
+            array('', 'proxy', input_manager::TYPE_RAW, 'HTTP proxy host and port (e.g. \'our.proxy.edu:8888\')'),
+            array('', 'proxytype', input_manager::TYPE_RAW, 'Proxy type (HTTP or SOCKS5)'),
+            array('', 'proxyuserpwd', input_manager::TYPE_RAW, 'Proxy username and password (e.g. \'username:password\')'),
             array('', 'returnurl', input_manager::TYPE_URL, 'Return URL (HTTP access only)'),
             array('d', 'dataroot', input_manager::TYPE_PATH, 'Full path to the dataroot (moodledata) directory'),
             array('h', 'help', input_manager::TYPE_FLAG, 'Prints usage information'),
@@ -618,9 +621,12 @@ class output_http_provider extends output_provider {
      * @param Exception $e uncaught exception
      */
     public function exception(Exception $e) {
+
+        $docslink = 'http://docs.moodle.org/en/admin/mdeploy/'.get_class($e);
         $this->start_output();
         echo('<h1>Oops! It did it again</h1>');
-        echo('<p><strong>Moodle deployment utility had a trouble with your request. See the debugging information for more details.</strong></p>');
+        echo('<p><strong>Moodle deployment utility had a trouble with your request.
+            See <a href="'.$docslink.'">the docs page</a> and the debugging information for more details.</strong></p>');
         echo('<pre>');
         echo exception_handlers::format_exception_info($e);
         echo('</pre>');
@@ -748,7 +754,7 @@ class worker extends singleton_pattern {
             }
 
             // Looking good, let's try it.
-            if (!$this->move_directory($sourcelocation, $backuplocation)) {
+            if (!$this->move_directory($sourcelocation, $backuplocation, true)) {
                 throw new backup_folder_exception('Unable to backup the current version of the plugin (moving failed)');
             }
 
@@ -967,6 +973,36 @@ class worker extends singleton_pattern {
         curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 20); // nah, moodle.org is never unavailable! :-p
         curl_setopt($ch, CURLOPT_URL, $source);
 
+        $dataroot = $this->input->get_option('dataroot');
+        $cacertfile = $dataroot.'/moodleorgca.crt';
+        if (is_readable($cacertfile)) {
+            // Do not use CA certs provided by the operating system. Instead,
+            // use this CA cert to verify the ZIP provider.
+            $this->log('Using custom CA certificate '.$cacertfile);
+            curl_setopt($ch, CURLOPT_CAINFO, $cacertfile);
+        }
+
+        $proxy = $this->input->get_option('proxy', false);
+        if (!empty($proxy)) {
+            curl_setopt($ch, CURLOPT_PROXY, $proxy);
+
+            $proxytype = $this->input->get_option('proxytype', false);
+            if (strtoupper($proxytype) === 'SOCKS5') {
+                $this->log('Using SOCKS5 proxy');
+                curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);
+            } else if (!empty($proxytype)) {
+                $this->log('Using HTTP proxy');
+                curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
+                curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, false);
+            }
+
+            $proxyuserpwd = $this->input->get_option('proxyuserpwd', false);
+            if (!empty($proxyuserpwd)) {
+                curl_setopt($ch, CURLOPT_PROXYUSERPWD, $proxyuserpwd);
+                curl_setopt($ch, CURLOPT_PROXYAUTH, CURLAUTH_BASIC | CURLAUTH_NTLM);
+            }
+        }
+
         $targetfile = fopen($target, 'w');
 
         if (!$targetfile) {
@@ -1100,23 +1136,45 @@ class worker extends singleton_pattern {
     /**
      * Moves the given source into a new location recursively
      *
+     * The target location can not exist.
+     *
      * @param string $source full path to the existing directory
      * @param string $destination full path to the new location of the folder
+     * @param bool $keepsourceroot should the root of the $source be kept or removed at the end
      * @return bool
      */
-    protected function move_directory($source, $target) {
+    protected function move_directory($source, $target, $keepsourceroot = false) {
 
         if (file_exists($target)) {
             throw new filesystem_exception('Unable to move the directory - target location already exists');
         }
 
+        return $this->move_directory_into($source, $target, $keepsourceroot);
+    }
+
+    /**
+     * Moves the given source into a new location recursively
+     *
+     * If the target already exists, files are moved into it. The target is created otherwise.
+     *
+     * @param string $source full path to the existing directory
+     * @param string $destination full path to the new location of the folder
+     * @param bool $keepsourceroot should the root of the $source be kept or removed at the end
+     * @return bool
+     */
+    protected function move_directory_into($source, $target, $keepsourceroot = false) {
+
         if (is_dir($source)) {
             $handle = opendir($source);
         } else {
             throw new filesystem_exception('Source location is not a directory');
         }
 
-        mkdir($target, 02777);
+        if (is_dir($target)) {
+            $result = true;
+        } else {
+            $result = mkdir($target, 02777);
+        }
 
         while ($filename = readdir($handle)) {
             $sourcepath = $source.'/'.$filename;
@@ -1127,26 +1185,37 @@ class worker extends singleton_pattern {
             }
 
             if (is_dir($sourcepath)) {
-                $this->move_directory($sourcepath, $targetpath);
+                $result = $result && $this->move_directory($sourcepath, $targetpath, false);
 
             } else {
-                rename($sourcepath, $targetpath);
+                $result = $result && rename($sourcepath, $targetpath);
             }
         }
 
         closedir($handle);
-        return rmdir($source);
+
+        if (!$keepsourceroot) {
+            $result = $result && rmdir($source);
+        }
+
+        clearstatcache();
+
+        return $result;
     }
 
     /**
      * Deletes the given directory recursively
      *
      * @param string $path full path to the directory
+     * @param bool $keeppathroot should the root of the $path be kept (i.e. remove the content only) or removed too
+     * @return bool
      */
-    protected function remove_directory($path) {
+    protected function remove_directory($path, $keeppathroot = false) {
+
+        $result = true;
 
         if (!file_exists($path)) {
-            return;
+            return $result;
         }
 
         if (is_dir($path)) {
@@ -1163,15 +1232,22 @@ class worker extends singleton_pattern {
             }
 
             if (is_dir($filepath)) {
-                $this->remove_directory($filepath);
+                $result = $result && $this->remove_directory($filepath, false);
 
             } else {
-                unlink($filepath);
+                $result = $result && unlink($filepath);
             }
         }
 
         closedir($handle);
-        return rmdir($path);
+
+        if (!$keeppathroot) {
+            $result = $result && rmdir($path);
+        }
+
+        clearstatcache();
+
+        return $result;
     }
 
     /**
@@ -1206,8 +1282,8 @@ class worker extends singleton_pattern {
 
         if (!$zip->extractTo($plugintyperoot)) {
             $zip->close();
-            $this->remove_directory($expectedlocation); // just in case something was created
-            $this->move_directory($backuplocation, $expectedlocation);
+            $this->remove_directory($expectedlocation, true); // just in case something was created
+            $this->move_directory_into($backuplocation, $expectedlocation);
             throw new zip_exception('Unable to extract the zip package');
         }
 
index 471a9d3..4724172 100644 (file)
@@ -85,6 +85,30 @@ class testable_input_manager extends input_manager {
 }
 
 
+/**
+ * Testable subclass
+ *
+ * @copyright 2012 David Mudrak <david@moodle.com>
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class testable_worker extends worker {
+
+    /**
+     * Provides access to the protected method.
+     */
+    public function move_directory($source, $target, $keepsourceroot = false) {
+        return parent::move_directory($source, $target, $keepsourceroot);
+    }
+
+    /**
+     * Provides access to the protected method.
+     */
+    public function remove_directory($path, $keeppathroot = false) {
+        return parent::remove_directory($path, $keeppathroot);
+    }
+}
+
+
 /**
  * Test cases for the mdeploy utility
  *
@@ -212,4 +236,26 @@ class mdeploytest extends PHPUnit_Framework_TestCase {
             $this->assertTrue(true);
         }
     }
+
+    public function test_moving_and_removing_directories() {
+        $worker = testable_worker::instance();
+
+        $root = sys_get_temp_dir().'/'.uniqid('mdeploytest', true);
+        mkdir($root.'/a', 0777, true);
+        touch($root.'/a/a.txt');
+
+        $this->assertTrue(file_exists($root.'/a/a.txt'));
+        $this->assertFalse(file_exists($root.'/b/a.txt'));
+        $this->assertTrue($worker->move_directory($root.'/a', $root.'/b'));
+        $this->assertFalse(is_dir($root.'/a'));
+        $this->assertTrue(file_exists($root.'/b/a.txt'));
+        $this->assertTrue($worker->move_directory($root.'/b', $root.'/c', true));
+        $this->assertTrue(file_exists($root.'/c/a.txt'));
+        $this->assertFalse(file_exists($root.'/b/a.txt'));
+        $this->assertTrue(is_dir($root.'/b'));
+        $this->assertTrue($worker->remove_directory($root.'/c', true));
+        $this->assertFalse(file_exists($root.'/c/a.txt'));
+        $this->assertTrue($worker->remove_directory($root.'/c'));
+        $this->assertFalse(is_dir($root.'/c'));
+    }
 }
index 2d78553..89c4373 100644 (file)
@@ -26,31 +26,15 @@ require_once(dirname(__FILE__) . '/../config.php');
 require_once($CFG->dirroot . '/message/lib.php');
 
 $userid = optional_param('id', $USER->id, PARAM_INT);    // user id
-$course = optional_param('course', SITEID, PARAM_INT);   // course id (defaults to Site)
 $disableall = optional_param('disableall', 0, PARAM_BOOL); //disable all of this user's notifications
 
 $url = new moodle_url('/message/edit.php');
 $url->param('id', $userid);
-$url->param('course', $course);
 
 $PAGE->set_url($url);
 $PAGE->set_popup_notification_allowed(false); // We are within the messaging system so don't show message popups
 
-if (!$course = $DB->get_record('course', array('id' => $course))) {
-    print_error('invalidcourseid');
-}
-
-if ($course->id != SITEID) {
-    require_login($course);
-
-} else {
-    if (!isloggedin()) {
-        if (empty($SESSION->wantsurl)) {
-            $SESSION->wantsurl = $CFG->httpswwwroot.'/message/edit.php';
-        }
-        redirect(get_login_url());
-    }
-}
+require_login();
 
 if (isguestuser()) {
     print_error('guestnoeditmessage', 'message');
@@ -71,10 +55,6 @@ $PAGE->requires->js_init_call('M.core_message.init_editsettings');
 if ($user->id == $USER->id) {
     //editing own message profile
     require_capability('moodle/user:editownmessageprofile', $systemcontext);
-    if ($course->id != SITEID && $node = $PAGE->navigation->find($course->id, navigation_node::TYPE_COURSE)) {
-        $node->make_active();
-        $PAGE->navbar->includesettingsbase = true;
-    }
 } else {
     // teachers, parents, etc.
     require_capability('moodle/user:editmessageprofile', $personalcontext);
@@ -144,7 +124,7 @@ if (($form = data_submitted()) && confirm_sesskey()) {
         print_error('cannotupdateusermsgpref');
     }
 
-    redirect("$CFG->wwwroot/message/edit.php?id=$user->id&course=$course->id");
+    redirect("$CFG->wwwroot/message/edit.php?id=$user->id");
 }
 
 /// Load preferences
@@ -178,15 +158,9 @@ $preferences->blocknoncontacts  =  get_user_preferences( 'message_blocknoncontac
 //$preferences->beepnewmessage    =  get_user_preferences( 'message_beepnewmessage', '', $user->id);
 
 /// Display page header
-$streditmymessage = get_string('editmymessage', 'message');
-$strparticipants  = get_string('participants');
-
-$PAGE->set_title("$course->shortname: $streditmymessage");
-if ($course->id != SITEID) {
-    $PAGE->set_heading("$course->fullname: $streditmymessage");
-} else {
-    $PAGE->set_heading($course->fullname);
-}
+$strmessaging = get_string('messaging', 'message');
+$PAGE->set_title($strmessaging);
+$PAGE->set_heading($strmessaging);
 
 // Grab the renderer
 $renderer = $PAGE->get_renderer('core', 'message');
index 1d50651..686bf0a 100644 (file)
@@ -592,7 +592,7 @@ abstract class assign_plugin {
 
     /**
      * If this plugin should not include a column in the grading table or a row on the summary page
-     * return false
+     * then return false
      *
      * @return bool
      */
index c3338b3..a5aad69 100644 (file)
@@ -83,7 +83,7 @@ class assignfeedback_file_import_zip_form extends moodleform implements renderab
                     $userdesc = fullname($user);
                     if ($assignment->is_blind_marking()) {
                         $userdesc = get_string('hiddenuser', 'assign') .
-                                    $assignment->get_unique_id_for_user($user->id);
+                                    $assignment->get_uniqueid_for_user($user->id);
                     }
                     $grade = $assignment->get_user_grade($user->id, false);
 
index 326dc5a..baba18d 100644 (file)
@@ -92,7 +92,7 @@ class assignfeedback_offline_import_grades_form extends moodleform implements re
             $modified = $record->modified;
             $userdesc = fullname($user);
             if ($assignment->is_blind_marking()) {
-                $userdesc = get_string('hiddenuser', 'assign') . $assignment->get_unique_id_for_user($user->id);
+                $userdesc = get_string('hiddenuser', 'assign') . $assignment->get_uniqueid_for_user($user->id);
             }
 
             $usergrade = $assignment->get_user_grade($user->id, false);
index b24f4fa..8eb7ce3 100644 (file)
@@ -59,7 +59,7 @@ class mod_assign_grading_options_form extends moodleform {
 
         // quickgrading
         if ($instance['showquickgrading']) {
-            $mform->addElement('checkbox', 'quickgrading', get_string('quickgrading', 'assign'), '');
+            $mform->addElement('checkbox', 'quickgrading', get_string('quickgrading', 'assign'), '', $dirtyclass);
             $mform->addHelpButton('quickgrading', 'quickgrading', 'assign');
             $mform->setDefault('quickgrading', $instance['quickgrading']);
         }
index e9747e6..c565d7b 100644 (file)
@@ -772,7 +772,7 @@ class assign_grading_table extends table_sql implements renderable {
         $edit .= html_writer::start_tag('ul');
         $edit .= html_writer::start_tag('li', array('class'=>'menuicon'));
 
-        $menuicon = $this->output->pix_icon('i/menu', get_string('actions'));
+        $menuicon = $this->output->pix_icon('t/contextmenu', get_string('actions'));
         $edit .= $this->output->action_link('#menu' . $row->id, $menuicon, null, array('class'=>'yui3-menu-label'));
         $edit .= $this->output->container_start(array('yui3-menu', 'yui3-loading'), 'menu' . $row->id);
         $edit .= $this->output->container_start(array('yui3-menu-content'));
index 7c5a925..8bf1962 100644 (file)
@@ -1022,6 +1022,8 @@ class assign {
 
         static $scalegrades = array();
 
+        $o = '';
+
         if ($this->get_instance()->grade >= 0) {
             // Normal number
             if ($editing && $this->get_instance()->grade > 0) {
@@ -1030,17 +1032,20 @@ class assign {
                 } else {
                     $displaygrade = format_float($grade);
                 }
-                $o = '<label class="accesshide" for="quickgrade_' . $userid . '">' . get_string('usergrade', 'assign') . '</label>';
-                $o .= '<input type="text" id="quickgrade_' . $userid . '" name="quickgrade_' . $userid . '" value="' . $displaygrade
-                        . '" size="6" maxlength="10" class="quickgrade"/>';
+                $o .= '<label class="accesshide" for="quickgrade_' . $userid . '">' . get_string('usergrade', 'assign') . '</label>';
+                $o .= '<input type="text" id="quickgrade_' . $userid . '" name="quickgrade_' . $userid . '" value="' .
+                      $displaygrade . '" size="6" maxlength="10" class="quickgrade"/>';
                 $o .= '&nbsp;/&nbsp;' . format_float($this->get_instance()->grade,2);
                 $o .= '<input type="hidden" name="grademodified_' . $userid . '" value="' . $modified . '"/>';
                 return $o;
             } else {
+                $o .= '<input type="hidden" name="grademodified_' . $userid . '" value="' . $modified . '"/>';
                 if ($grade == -1 || $grade === null) {
-                    return '-';
+                    $o .= '-';
+                    return $o;
                 } else {
-                    return format_float(($grade),2) .'&nbsp;/&nbsp;'. format_float($this->get_instance()->grade,2);
+                    $o .= format_float(($grade),2) .'&nbsp;/&nbsp;'. format_float($this->get_instance()->grade,2);
+                    return $o;
                 }
             }
 
@@ -1050,11 +1055,12 @@ class assign {
                 if ($scale = $DB->get_record('scale', array('id'=>-($this->get_instance()->grade)))) {
                     $this->cache['scale'] = make_menu_from_list($scale->scale);
                 } else {
-                    return '-';
+                    $o .= '-';
+                    return $o;
                 }
             }
             if ($editing) {
-                $o = '<label class="accesshide" for="quickgrade_' . $userid . '">' . get_string('usergrade', 'assign') . '</label>';
+                $o .= '<label class="accesshide" for="quickgrade_' . $userid . '">' . get_string('usergrade', 'assign') . '</label>';
                 $o .= '<select name="quickgrade_' . $userid . '" class="quickgrade">';
                 $o .= '<option value="-1">' . get_string('nograde') . '</option>';
                 foreach ($this->cache['scale'] as $optionid => $option) {
@@ -1070,9 +1076,11 @@ class assign {
             } else {
                 $scaleid = (int)$grade;
                 if (isset($this->cache['scale'][$scaleid])) {
-                    return $this->cache['scale'][$scaleid];
+                    $o .= $this->cache['scale'][$scaleid];
+                    return $o;
                 }
-                return '-';
+                $o .= '-';
+                return $o;
             }
         }
     }
@@ -1123,22 +1131,37 @@ class assign {
     /**
      * Load a count of users submissions in the current module that require grading
      * This means the submission modification time is more recent than the
-     * grading modification time.
+     * grading modification time and the status is SUBMITTED.
      *
      * @return int number of matching submissions
      */
     public function count_submissions_need_grading() {
         global $DB;
 
-        $params = array($this->get_course_module()->instance);
+        if ($this->get_instance()->teamsubmission) {
+            // This does not make sense for group assignment because the submission is shared.
+            return 0;
+        }
+
+        $currentgroup = groups_get_activity_group($this->get_course_module(), true);
+        list($esql, $params) = get_enrolled_sql($this->get_context(), 'mod/assign:submit', $currentgroup, false);
+
+        $params['assignid'] = $this->get_instance()->id;
+        $params['submitted'] = ASSIGN_SUBMISSION_STATUS_SUBMITTED;
+
+        $sql = 'SELECT COUNT(s.userid)
+                   FROM {assign_submission} s
+                   LEFT JOIN {assign_grades} g ON
+                        s.assignment = g.assignment AND
+                        s.userid = g.userid
+                   JOIN(' . $esql . ') AS e ON e.id = s.userid
+                   WHERE
+                        s.assignment = :assignid AND
+                        s.timemodified IS NOT NULL AND
+                        s.status = :submitted AND
+                        (s.timemodified > g.timemodified OR g.timemodified IS NULL)';
 
-        return $DB->count_records_sql("SELECT COUNT('x')
-                                       FROM {assign_submission} s
-                                       LEFT JOIN {assign_grades} g ON s.assignment = g.assignment AND s.userid = g.userid
-                                       WHERE s.assignment = ?
-                                           AND s.timemodified IS NOT NULL
-                                           AND (s.timemodified > g.timemodified OR g.timemodified IS NULL)",
-                                       $params);
+        return $DB->count_records_sql($sql, $params);
     }
 
     /**
@@ -1153,8 +1176,15 @@ class assign {
             return 0;
         }
 
-        $sql = 'SELECT COUNT(id) FROM {assign_grades} WHERE assignment = ?';
-        $params = array($this->get_course_module()->instance);
+        $currentgroup = groups_get_activity_group($this->get_course_module(), true);
+        list($esql, $params) = get_enrolled_sql($this->get_context(), 'mod/assign:submit', $currentgroup, false);
+
+        $params['assignid'] = $this->get_instance()->id;
+
+        $sql = 'SELECT COUNT(g.userid)
+                   FROM {assign_grades} g
+                   JOIN(' . $esql . ') AS e ON e.id = g.userid
+                   WHERE g.assignment = :assignid';
 
         return $DB->count_records_sql($sql, $params);
     }
@@ -1171,14 +1201,33 @@ class assign {
             return 0;
         }
 
-        $sql = 'SELECT COUNT(id) FROM {assign_submission} WHERE assignment = ?';
-        $params = array($this->get_course_module()->instance);
+        $params = array();
 
         if ($this->get_instance()->teamsubmission) {
-            // only look at team submissions
-            $sql .= ' AND userid = ?';
-            $params[] = 0;
+            // We cannot join on the enrolment tables for group submissions (no userid).
+            $sql = 'SELECT COUNT(s.groupid)
+                        FROM {assign_submission} s
+                        WHERE
+                            s.assignment = :assignid AND
+                            s.timemodified IS NOT NULL AND
+                            s.userid = :groupuserid';
+
+            $params['assignid'] = $this->get_instance()->id;
+            $params['groupuserid'] = 0;
+        } else {
+            $currentgroup = groups_get_activity_group($this->get_course_module(), true);
+            list($esql, $params) = get_enrolled_sql($this->get_context(), 'mod/assign:submit', $currentgroup, false);
+
+            $params['assignid'] = $this->get_instance()->id;
+
+            $sql = 'SELECT COUNT(s.userid)
+                       FROM {assign_submission} s
+                       JOIN(' . $esql . ') AS e ON e.id = s.userid
+                       WHERE
+                            s.assignment = :assignid AND
+                            s.timemodified IS NOT NULL';
         }
+
         return $DB->count_records_sql($sql, $params);
     }
 
@@ -1190,14 +1239,32 @@ class assign {
      */
     public function count_submissions_with_status($status) {
         global $DB;
-        $sql = 'SELECT COUNT(id) FROM {assign_submission} WHERE assignment = ? AND status = ?';
-        $params = array($this->get_course_module()->instance, $status);
+
+        $currentgroup = groups_get_activity_group($this->get_course_module(), true);
+        list($esql, $params) = get_enrolled_sql($this->get_context(), 'mod/assign:submit', $currentgroup, false);
+
+        $params['assignid'] = $this->get_instance()->id;
+        $params['submissionstatus'] = $status;
 
         if ($this->get_instance()->teamsubmission) {
-            // only look at team submissions
-            $sql .= ' AND userid = ?';
-            $params[] = 0;
+            $sql = 'SELECT COUNT(s.groupid)
+                        FROM {assign_submission} s
+                        WHERE
+                            s.assignment = :assignid AND
+                            s.timemodified IS NOT NULL AND
+                            s.userid = :groupuserid AND
+                            s.status = :submissionstatus';
+            $params['groupuserid'] = 0;
+        } else {
+            $sql = 'SELECT COUNT(s.userid)
+                        FROM {assign_submission} s
+                        JOIN(' . $esql . ') AS e ON e.id = s.userid
+                        WHERE
+                            s.assignment = :assignid AND
+                            s.timemodified IS NOT NULL AND
+                            s.status = :submissionstatus';
         }
+
         return $DB->count_records_sql($sql, $params);
     }
 
@@ -1964,12 +2031,7 @@ class assign {
             $submission->userid       = $userid;
             $submission->timecreated = time();
             $submission->timemodified = $submission->timecreated;
-
-            if ($this->get_instance()->submissiondrafts) {
-                $submission->status = ASSIGN_SUBMISSION_STATUS_DRAFT;
-            } else {
-                $submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED;
-            }
+            $submission->status = ASSIGN_SUBMISSION_STATUS_DRAFT;
             $sid = $DB->insert_record('assign_submission', $submission);
             $submission->id = $sid;
             return $submission;
@@ -2114,6 +2176,9 @@ class assign {
             } else {
                 $showsubmit = $showedit && $submission && ($submission->status == ASSIGN_SUBMISSION_STATUS_DRAFT);
             }
+            if (!$this->get_instance()->submissiondrafts) {
+                $showsubmit = false;
+            }
             $viewfullnames = has_capability('moodle/site:viewfullnames', $this->get_course_context());
 
             $o .= $this->get_renderer()->render(new assign_submission_status($this->get_instance()->allowsubmissionsfromdate,
@@ -2653,6 +2718,9 @@ class assign {
             if ($submission && ($submission->status == ASSIGN_SUBMISSION_STATUS_SUBMITTED)) {
                 $showsubmit = false;
             }
+            if (!$this->get_instance()->submissiondrafts) {
+                $showsubmit = false;
+            }
             $extensionduedate = null;
             if ($grade) {
                 $extensionduedate = $grade->extensionduedate;
@@ -3448,19 +3516,16 @@ class assign {
         // gets a list of possible users and look for values based upon that.
         foreach ($participants as $userid => $unused) {
             $modified = optional_param('grademodified_' . $userid, -1, PARAM_INT);
-            if ($modified >= 0) {
-                // gather the userid, updated grade and last modified value
-                $record = new stdClass();
-                $record->userid = $userid;
-                $record->grade = unformat_float(required_param('quickgrade_' . $record->userid, PARAM_TEXT));
-                $record->lastmodified = $modified;
-                $record->gradinginfo = grade_get_grades($this->get_course()->id, 'mod', 'assign', $this->get_instance()->id, array($userid));
-                $users[$userid] = $record;
+            // Gather the userid, updated grade and last modified value.
+            $record = new stdClass();
+            $record->userid = $userid;
+            $gradevalue = optional_param('quickgrade_' . $userid, '', PARAM_TEXT);
+            if($modified >= 0) {
+                $record->grade = unformat_float(optional_param('quickgrade_' . $record->userid, -1, PARAM_TEXT));
             }
-        }
-        if (empty($users)) {
-            // Quick check to see whether we have any users to update and we don't
-            return get_string('quickgradingchangessaved', 'assign'); // Technical lie
+            $record->lastmodified = $modified;
+            $record->gradinginfo = grade_get_grades($this->get_course()->id, 'mod', 'assign', $this->get_instance()->id, array($userid));
+            $users[$userid] = $record;
         }
 
         list($userids, $params) = $DB->get_in_or_equal(array_keys($users), SQL_PARAMS_NAMED);
diff --git a/mod/assign/pix/gradefeedback.png b/mod/assign/pix/gradefeedback.png
new file mode 100644 (file)
index 0000000..3264934
Binary files /dev/null and b/mod/assign/pix/gradefeedback.png differ
diff --git a/mod/assign/pix/gradefeedback.svg b/mod/assign/pix/gradefeedback.svg
new file mode 100644 (file)
index 0000000..f6b8252
--- /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="12px" height="12px" viewBox="0 0 12 12" style="overflow:visible;enable-background:new 0 0 12 12;"\r
+        xml:space="preserve" preserveAspectRatio="xMinYMid meet">\r
+<defs>\r
+</defs>\r
+<path style="fill:#999999;" d="M11,5.2V11c0,0.5-0.5,1-1,1H1c-0.5,0-1-0.5-1-1V2c0-0.5,0.5-1,1-1h5.8l-1,1H2C1.5,2,1,2.4,1,3v3.8V10\r
+       v1h1h3.2H9c0.5,0,1-0.5,1-1V6.2L11,5.2z M6.8,2.3L2,7.1V10h2.8l4.8-4.8L6.8,2.3z M11.4,0.6L11.4,0.6c-0.8-0.8-2.1-0.8-2.8,0L7.8,1.3\r
+       l2.8,2.8l0.7-0.7C12.2,2.6,12.2,1.4,11.4,0.6z"/>\r
+</svg>\r
index a2f94da..c8b83e5 100644 (file)
@@ -254,8 +254,10 @@ class mod_assign_renderer extends plugin_renderer_base {
         if ($summary->submissionsenabled) {
             $this->add_table_row_tuple($t, get_string('numberofsubmittedassignments', 'assign'),
                                        $summary->submissionssubmittedcount);
-            $this->add_table_row_tuple($t, get_string('numberofsubmissionsneedgrading', 'assign'),
-                                       $summary->submissionsneedgradingcount);
+            if (!$summary->teamsubmission) {
+                $this->add_table_row_tuple($t, get_string('numberofsubmissionsneedgrading', 'assign'),
+                                           $summary->submissionsneedgradingcount);
+            }
         }
 
         $time = time();
@@ -572,10 +574,11 @@ class mod_assign_renderer extends plugin_renderer_base {
             $t->data[] = $row;
 
             foreach ($status->submissionplugins as $plugin) {
+                $pluginshowsummary = !$plugin->is_empty($submission) || !$plugin->allow_submissions();
                 if ($plugin->is_enabled() &&
                     $plugin->is_visible() &&
                     $plugin->has_user_summary() &&
-                    !$plugin->is_empty($submission)) {
+                    $pluginshowsummary) {
 
                     $row = new html_table_row();
                     $cell1 = new html_table_cell($plugin->get_name());
index 45fd7e4..aa3c880 100644 (file)
@@ -114,7 +114,9 @@ div.earlysubmission {
 
 .gradingtable .yui3-menu-label {
     padding-left: 0px;
+    line-height: 12px;
 }
+.gradingtable .yui3-menu-label img { padding: 0 3px; }
 .gradingtable .yui3-menu li {
     list-style-type: none;
 }
@@ -125,6 +127,7 @@ div.earlysubmission {
 
 .gradingtable .yui3-menu .yui3-menu-content {
     border: 0px;
+    padding-top: 0;
 }
 
 #page-mod-assign-view div.gradingtable tr .quickgrademodified {
index 29a1d5e..513dca9 100644 (file)
@@ -78,12 +78,13 @@ class assign_submission_comments extends assign_submission_plugin {
     }
 
     /**
-     * Always return false because at a minimum there is the comments control
+     * Always return true because the submission comments are not part of the submission form.
+     *
      * @param stdClass $submission
      * @return bool
      */
     public function is_empty(stdClass $submission) {
-        return false;
+        return true;
     }
 
   /**
index a94cc85..26ab289 100644 (file)
@@ -422,7 +422,9 @@ class assign_submission_onlinetext extends assign_submission_plugin {
      * @return bool
      */
     public function is_empty(stdClass $submission) {
-        return $this->view($submission) == '';
+        $onlinetextsubmission = $this->get_onlinetext_submission($submission->id);
+
+        return empty($onlinetextsubmission->onlinetext);
     }
 
     /**
index ff6ee6d..38e243d 100644 (file)
@@ -238,14 +238,12 @@ class assign_upgrade_manager {
 
             $newassignment->update_calendar($newcoursemodule->id);
 
-            // copy the grades from the old assignment to the new one
+            // Reassociate grade_items from the old assignment instance to the new assign instance.
+            // This includes outcome linked grade_items.
+            $params = array('assign', $newassignment->get_instance()->id, 'assignment', $oldassignment->id);
+            $sql = 'UPDATE {grade_items} SET itemmodule = ?, iteminstance = ? WHERE itemmodule = ? AND iteminstance = ?';
+            $DB->execute($sql, $params);
 
-            $gradeitem = $DB->get_record('grade_items', array('iteminstance'=>$oldassignment->id, 'itemmodule'=>'assignment'), 'id', IGNORE_MISSING);
-            if ($gradeitem) {
-                $gradeitem->iteminstance = $newassignment->get_instance()->id;
-                $gradeitem->itemmodule = 'assign';
-                $DB->update_record('grade_items', $gradeitem);
-            }
             $gradesdone = true;
 
         } catch (Exception $exception) {
@@ -256,13 +254,10 @@ class assign_upgrade_manager {
         if ($rollback) {
             // roll back the grades changes
             if ($gradesdone) {
-                // copy the grades from the old assignment to the new one
-                $gradeitem = $DB->get_record('grade_items', array('iteminstance'=>$newassignment->get_instance()->id, 'itemmodule'=>'assign'), 'id', IGNORE_MISSING);
-                if ($gradeitem) {
-                    $gradeitem->iteminstance = $oldassignment->id;
-                    $gradeitem->itemmodule = 'assignment';
-                    $DB->update_record('grade_items', $gradeitem);
-                }
+                // Reassociate grade_items from the new assign instance to the old assignment instance.
+                $params = array('assignment', $oldassignment->id, 'assign', $newassignment->get_instance()->id);
+                $sql = 'UPDATE {grade_items} SET itemmodule = ?, iteminstance = ? WHERE itemmodule = ? AND iteminstance = ?';
+                $DB->execute($sql, $params);
             }
             // roll back the completion changes
             if ($completiondone) {
index 6e36814..2a68d4c 100644 (file)
@@ -75,8 +75,10 @@ if ($rid) {
 
 require_course_login($course, true, $cm);
 
+$context = context_module::instance($cm->id);
+
 /// If it's hidden then it's don't show anything.  :)
-if (empty($cm->visible) and !has_capability('moodle/course:viewhiddenactivities',context_module::instance($cm->id))) {
+if (empty($cm->visible) and !has_capability('moodle/course:viewhiddenactivities', $context)) {
     $PAGE->set_title($data->name);
     echo $OUTPUT->header();
     notice(get_string("activityiscurrentlyhidden"));
index 992b8cf..332fbbe 100644 (file)
@@ -762,7 +762,7 @@ if ($showactivity) {
         $records = array();
     }
 
-    if ($mode == '' && !empty($CFG->enableportfolios)) {
+    if ($mode == '' && !empty($CFG->enableportfolios) && !empty($records)) {
         require_once($CFG->libdir . '/portfoliolib.php');
         $button = new portfolio_add_button();
         $button->set_callback_options('data_portfolio_caller', array('id' => $cm->id), 'mod_data');
index 8dd1bf7..a1c8196 100644 (file)
@@ -29,7 +29,7 @@ class feedback_captcha_form extends feedback_item_form {
         $mform =& $this->_form;
 
         $mform->addElement('header', 'general', get_string($this->type, 'feedback'));
-        $mform->addElement('checkbox', 'required', get_string('required', 'feedback'));
+        $mform->addElement('advcheckbox', 'required', get_string('required', 'feedback'), '' , null , array(0, 1));
         $mform->addElement('text',
                             'name',
                             get_string('item_name', 'feedback'),
index 25074fd..6dd192d 100644 (file)
@@ -29,7 +29,7 @@ class feedback_multichoice_form extends feedback_item_form {
 
         $mform->addElement('header', 'general', get_string($this->type, 'feedback'));
 
-        $mform->addElement('checkbox', 'required', get_string('required', 'feedback'));
+        $mform->addElement('advcheckbox', 'required', get_string('required', 'feedback'), '' , null , array(0, 1));
 
         $mform->addElement('text',
                             'name',
index e95fb44..0c1632a 100644 (file)
@@ -29,7 +29,7 @@ class feedback_multichoicerated_form extends feedback_item_form {
 
         $mform->addElement('header', 'general', get_string($this->type, 'feedback'));
 
-        $mform->addElement('checkbox', 'required', get_string('required', 'feedback'));
+        $mform->addElement('advcheckbox', 'required', get_string('required', 'feedback'), '' , null , array(0, 1));
 
         $mform->addElement('text',
                             'name',
index 1252870..5abbea0 100644 (file)
@@ -29,7 +29,7 @@ class feedback_numeric_form extends feedback_item_form {
         $mform =& $this->_form;
 
         $mform->addElement('header', 'general', get_string($this->type, 'feedback'));
-        $mform->addElement('checkbox', 'required', get_string('required', 'feedback'));
+        $mform->addElement('advcheckbox', 'required', get_string('required', 'feedback'), '' , null , array(0, 1));
 
         $mform->addElement('text',
                             'name',
index d498241..0a777e7 100644 (file)
@@ -28,7 +28,7 @@ class feedback_textarea_form extends feedback_item_form {
         $mform =& $this->_form;
 
         $mform->addElement('header', 'general', get_string($this->type, 'feedback'));
-        $mform->addElement('checkbox', 'required', get_string('required', 'feedback'));
+        $mform->addElement('advcheckbox', 'required', get_string('required', 'feedback'), '' , null , array(0, 1));
 
         $mform->addElement('text',
                             'name',
index 59c25ce..9361dff 100644 (file)
@@ -28,7 +28,7 @@ class feedback_textfield_form extends feedback_item_form {
         $mform =& $this->_form;
 
         $mform->addElement('header', 'general', get_string($this->type, 'feedback'));
-        $mform->addElement('checkbox', 'required', get_string('required', 'feedback'));
+        $mform->addElement('advcheckbox', 'required', get_string('required', 'feedback'), '' , null , array(0, 1));
 
         $mform->addElement('text',
                             'name',
index 6e70243..c4dc634 100644 (file)
@@ -338,6 +338,7 @@ if ($pageid != LESSON_EOL) {
         if (lesson_display_teacher_warning($lesson)) {
             // This is the warning msg for teachers to inform them that cluster
             // and unseen does not work while logged in as a teacher
+            $warningvars = new stdClass();
             $warningvars->cluster = get_string('clusterjump', 'lesson');
             $warningvars->unseen = get_string('unseenpageinbranch', 'lesson');
             $lesson->add_message(get_string('teacherjumpwarning', 'lesson', $warningvars));
index b728116..2c0b038 100644 (file)
@@ -70,6 +70,7 @@ class backup_lti_activity_structure_step extends backup_activity_structure_step
             'timemodified',
             'typeid',
             'toolurl',
+            'securetoolurl',
             'preferheight',
             'launchcontainer',
             'instructorchoicesendname',
@@ -79,8 +80,11 @@ class backup_lti_activity_structure_step extends backup_activity_structure_step
             'instructorchoiceallowsetting',
             'grade',
             'instructorcustomparameters',
+            'debuglaunch',
             'showtitlelaunch',
-            'showdescriptionlaunch'
+            'showdescriptionlaunch',
+            'icon',
+            'secureicon',
             )
         );
 
index a8d94ff..df17c03 100644 (file)
@@ -2,11 +2,9 @@ This files describes API changes for quiz access rule plugins.
 
 Overview of this plugin type at http://docs.moodle.org/dev/Quiz_access_rules
 
+=== 2.4 ===
 
-=== 2.2 ===
-
-* This plugin type was new in Moodle 2.2!
-
+* Replaced time_left() with new time_left_display() and end_time() functions.
 
 === 2.3 ===
 
@@ -14,6 +12,8 @@ Overview of this plugin type at http://docs.moodle.org/dev/Quiz_access_rules
   lib.php file containing
 function quizaccess_mypluginname_cron() {};
 
-=== 2.4 ===
+=== 2.2 ===
+
+* This plugin type was new in Moodle 2.2!
+
 
-* Replaced time_left() with new time_left_display() and end_time() functions.
\ No newline at end of file
index 2616c4f..507c4c7 100644 (file)
@@ -656,7 +656,7 @@ class page_wiki_comments extends page_wiki {
                     $parsedcontent = wiki_parse_content('nwiki', $comment->content, $options);
                 }
 
-                $cell4->text = format_text(html_entity_decode($parsedcontent['parsed_text']), FORMAT_HTML);
+                $cell4->text = format_text(html_entity_decode($parsedcontent['parsed_text'], ENT_QUOTES, 'UTF-8'), FORMAT_HTML);
             } else {
                 $cell4->text = format_text($comment->content, FORMAT_HTML);
             }
index eb14bc0..f777f28 100644 (file)
@@ -14,9 +14,9 @@ require_once($CFG->dirroot . "/lib/outputcomponents.php");
 class parser_utils {
         
     public static function h($tag, $text = null, $options = array(), $escape_text = false) {
-        $tag = htmlentities($tag);
+        $tag = htmlentities($tag, ENT_COMPAT, 'UTF-8');
         if(!empty($text) && $escape_text) {
-                $text = htmlentities($text);
+                $text = htmlentities($text, ENT_COMPAT, 'UTF-8');
             }
         return html_writer::tag($tag, $text, $options);
     }
index b9d93c6..f927ac2 100644 (file)
@@ -1046,7 +1046,7 @@ function workshop_get_extra_capabilities() {
  * Needed by grade_update_mod_grades() in lib/gradelib.php. Also used by
  * {@link workshop_update_grades()}.
  *
- * @param stdClass $workshop instance object with extra cmidnumber and modname property
+ * @param stdClass $workshop instance object with extra cmidnumber property
  * @param stdClass $submissiongrades data for the first grade item
  * @param stdClass $assessmentgrades data for the second grade item
  * @return void
diff --git a/pix/c/course.png b/pix/c/course.png
new file mode 100644 (file)
index 0000000..4f86f2c
Binary files /dev/null and b/pix/c/course.png differ
diff --git a/pix/c/course.svg b/pix/c/course.svg
new file mode 100644 (file)
index 0000000..e60475f
--- /dev/null
@@ -0,0 +1,19 @@
+<?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.2 0 16 16" style="overflow:visible;enable-background:new -0.2 0 16 16;"\r
+        xml:space="preserve" preserveAspectRatio="xMinYMid meet">\r
+<defs>\r
+</defs>\r
+<path style="fill:#999999;" d="M6,0.4c0.4-0.1,0.8-0.1,1.3-0.1c1.5,0,3,0.5,4.2,1.4c-0.6,0.2-1.2,0.5-1.7,1C9.7,2.7,9.6,2.8,9.6,2.8\r
+       C8.9,2.5,8.1,2.2,7.2,2.2c-0.1,0-0.2,0-0.3,0C6.8,1.6,6.5,0.9,6,0.4z M11.7,9.4c-0.2,0.5-0.5,1-1,1.4c-0.3,0.3-0.8,0.6-1.2,0.8\r
+       c0.2,0.7,0.3,1.4,0.1,2.2c0.9-0.3,1.8-0.9,2.5-1.6c0.9-0.9,1.4-1.9,1.8-3C13.2,9.5,12.5,9.5,11.7,9.4z M3,10.1C3,10,3.1,10,3,10.1\r
+       C2.5,9.1,2.2,8,2.3,6.9C1.6,6.8,0.9,6.5,0.4,6C0,8,0.5,10.2,2,11.9C2.2,11.2,2.5,10.6,3,10.1z M10.4,3.4c-1.2,1.2-1.2,3.1,0,4.2\r
+       c1.2,1.2,3.1,1.2,4.2,0s1.2-3.1,0-4.2C13.5,2.2,11.6,2.2,10.4,3.4z M3.7,10.8c-1.2,1.2-1.2,3.1,0,4.2c1.2,1.2,3.1,1.2,4.2,0\r
+       c1.2-1.2,1.2-3.1,0-4.2C6.8,9.6,4.9,9.6,3.7,10.8z M0.9,0.9c-1.2,1.2-1.2,3.1,0,4.2C2,6.3,4,6.3,5.1,5.1c1.2-1.2,1.2-3.1,0-4.2\r
+       C4-0.3,2-0.3,0.9,0.9z"/>\r
+</svg>\r
diff --git a/pix/c/group.png b/pix/c/group.png
new file mode 100644 (file)
index 0000000..393371b
Binary files /dev/null and b/pix/c/group.png differ
diff --git a/pix/c/group.svg b/pix/c/group.svg
new file mode 100644 (file)
index 0000000..7107000
--- /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" preserveAspectRatio="xMinYMid meet">\r
+<defs>\r
+</defs>\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
diff --git a/pix/c/site.png b/pix/c/site.png
new file mode 100644 (file)
index 0000000..02a18b5
Binary files /dev/null and b/pix/c/site.png differ
diff --git a/pix/c/site.svg b/pix/c/site.svg
new file mode 100644 (file)
index 0000000..23f6975
--- /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 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="M14,1h-2v1.5C12,3.3,11.3,4,10.5,4S9,3.3,9,2.5V1H6v1.5C6,3.3,5.3,4,4.5,4S3,3.3,3,2.5V1H1\r
+       C0.4,1,0,1.4,0,2v13c0,0.6,0.4,1,1,1h13c0.6,0,1-0.4,1-1V2C15,1.4,14.6,1,14,1z M4,14H2v-2h2V14z M4,11H2V9h2V11z M4,8H2V6h2V8z\r
+        M7,14H5v-2h2V14z M7,11H5V9h2V11z M7,8H5V6h2V8z M10,14H8v-2h2V14z M10,11H8V9h2V11z M10,8H8V6h2V8z M13,14h-2v-2h2V14z M13,11h-2\r
+       V9h2V11z M13,8h-2V6h2V8z M5,2.5C5,2.8,4.8,3,4.5,3l0,0C4.2,3,4,2.8,4,2.5v-2C4,0.2,4.2,0,4.5,0l0,0C4.8,0,5,0.2,5,0.5V2.5z M11,2.5\r
+       C11,2.8,10.8,3,10.5,3l0,0C10.2,3,10,2.8,10,2.5v-2C10,0.2,10.2,0,10.5,0l0,0C10.8,0,11,0.2,11,0.5V2.5z"/>\r
+</svg>\r
diff --git a/pix/c/user.png b/pix/c/user.png
new file mode 100644 (file)
index 0000000..f803c86
Binary files /dev/null and b/pix/c/user.png differ
diff --git a/pix/c/user.svg b/pix/c/user.svg
new file mode 100644 (file)
index 0000000..9fc0081
--- /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" preserveAspectRatio="xMinYMid meet">\r
+<defs>\r
+</defs>\r
+<path style="fill:#999999;" d="M5.2,10.3L0,13.1V16h16v-3l-5.2-2.7C10.3,10,10.2,9.4,10.6,9c0,0,1.4-1.8,1.4-3.8C12,2.3,10.2,0,8,0\r
+       S4,2.3,4,5.2C4,7.2,5.4,9,5.4,9C5.8,9.5,5.7,10,5.2,10.3z"/>\r
+</svg>\r
diff --git a/pix/i/approve.png b/pix/i/approve.png
new file mode 100644 (file)
index 0000000..43540a5
Binary files /dev/null and b/pix/i/approve.png differ
diff --git a/pix/i/approve.svg b/pix/i/approve.svg
new file mode 100644 (file)
index 0000000..5c768d1
--- /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="12px" height="12px" viewBox="0 0 12 12" style="overflow:visible;enable-background:new 0 0 12 12;"\r
+        xml:space="preserve" preserveAspectRatio="xMinYMid meet">\r
+<defs>\r
+</defs>\r
+<path style="fill:#999999;" d="M11.4,0.6l-0.9-0.5C10.1-0.1,9.5,0,9.2,0.5L4.7,8.2L2,6.6C1.5,6.3,0.9,6.5,0.6,7L0.1,7.8\r
+       C-0.1,8.3,0,8.9,0.5,9.2L5,11.8c0.1,0.1,0.3,0.1,0.4,0.1c0.4,0.1,0.8-0.1,1-0.5L11.8,2C12.1,1.5,11.9,0.9,11.4,0.6z"/>\r
+</svg>\r
diff --git a/pix/i/calendar.png b/pix/i/calendar.png
new file mode 100644 (file)
index 0000000..02a18b5
Binary files /dev/null and b/pix/i/calendar.png differ
diff --git a/pix/i/calendar.svg b/pix/i/calendar.svg
new file mode 100644 (file)
index 0000000..23f6975
--- /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 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="M14,1h-2v1.5C12,3.3,11.3,4,10.5,4S9,3.3,9,2.5V1H6v1.5C6,3.3,5.3,4,4.5,4S3,3.3,3,2.5V1H1\r
+       C0.4,1,0,1.4,0,2v13c0,0.6,0.4,1,1,1h13c0.6,0,1-0.4,1-1V2C15,1.4,14.6,1,14,1z M4,14H2v-2h2V14z M4,11H2V9h2V11z M4,8H2V6h2V8z\r
+        M7,14H5v-2h2V14z M7,11H5V9h2V11z M7,8H5V6h2V8z M10,14H8v-2h2V14z M10,11H8V9h2V11z M10,8H8V6h2V8z M13,14h-2v-2h2V14z M13,11h-2\r
+       V9h2V11z M13,8h-2V6h2V8z M5,2.5C5,2.8,4.8,3,4.5,3l0,0C4.2,3,4,2.8,4,2.5v-2C4,0.2,4.2,0,4.5,0l0,0C4.8,0,5,0.2,5,0.5V2.5z M11,2.5\r
+       C11,2.8,10.8,3,10.5,3l0,0C10.2,3,10,2.8,10,2.5v-2C10,0.2,10.2,0,10.5,0l0,0C10.8,0,11,0.2,11,0.5V2.5z"/>\r
+</svg>\r
diff --git a/pix/i/configlock.png b/pix/i/configlock.png
new file mode 100644 (file)
index 0000000..5d2ee7c
Binary files /dev/null and b/pix/i/configlock.png differ
diff --git a/pix/i/configlock.svg b/pix/i/configlock.svg
new file mode 100644 (file)
index 0000000..05600a9
--- /dev/null
@@ -0,0 +1,21 @@
+<?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="M6,13.7c0-0.1-0.6-0.2-0.9-0.4l-1.8,1.2C2.6,14,2,13.4,1.5,12.6l1.2-1.8c-0.2-0.4-0.4-0.8-0.5-1.2\r
+       L0.1,9.3C0,8.9,0,8.4,0,8c0-0.4,0-0.9,0.1-1.3l2.1-0.4c0.1-0.4,0.3-0.8,0.5-1.2L1.5,3.4C2,2.6,2.6,2,3.4,1.5l1.8,1.2\r
+       c0.4-0.2,0.8-0.4,1.2-0.5l0.4-2.1C7.1,0,7.6,0,8,0s0.9,0,1.3,0.1l0.4,2.1c0.4,0.1,0.8,0.3,1.2,0.5l1.8-1.2C13.4,2,14,2.6,14.5,3.4\r
+       l-1.2,1.8c0.2,0.4,0.4,0.8,0.5,1.2l2.1,0.4C16,7.1,16,7.6,16,8s0,0.9-0.1,1.3l-0.4,0.1c-0.1-0.8-0.5-1.6-1.1-2.2\r
+       C13.6,6.4,12.6,6,11.6,6c-0.8,0-1.5,0.2-2.1,0.6C9.1,6.2,8.6,6,8,6C6.9,6,6.1,6.9,6.1,8c0,1,0.6,1.7,1.5,1.9c0,0,0,0.2,0,0.2\r
+       c-0.4,0.1-0.7,0.3-1,0.5C6.2,11,6,11.5,6,12V13.7z M14.5,10v1H15c0.5,0,1,0.5,1,1v3c0,0.5-0.5,1-1,1l-7,0c-0.5,0-1-0.5-1-1v-3\r
+       c0-0.5,0.4-1,1-1h0.6v-1c0-1.6,1.3-3,2.9-3C13.2,7,14.5,8.4,14.5,10z M11.5,12c-0.5,0-1,0.4-1,1c0,0.4,0.2,0.7,0.6,0.9L11,14l-0.5,1\r
+       l1,0l1,0L12,14L12,13.9c0.3-0.2,0.6-0.5,0.6-0.9C12.5,12.5,12.1,12,11.5,12z M11.5,9c-0.5,0-1,0.4-1,1v1h1.9v-1\r
+       C12.5,9.5,12.1,9,11.5,9z"/>\r
+</svg>\r
diff --git a/pix/i/cross_red_big.png b/pix/i/cross_red_big.png
new file mode 100644 (file)
index 0000000..0f5cfe0
Binary files /dev/null and b/pix/i/cross_red_big.png differ
diff --git a/pix/i/cross_red_big.svg b/pix/i/cross_red_big.svg
new file mode 100644 (file)
index 0000000..de6808d
--- /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" preserveAspectRatio="xMinYMid meet">\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/pix/i/cross_red_small.png b/pix/i/cross_red_small.png
new file mode 100644 (file)
index 0000000..0f5cfe0
Binary files /dev/null and b/pix/i/cross_red_small.png differ
diff --git a/pix/i/cross_red_small.svg b/pix/i/cross_red_small.svg
new file mode 100644 (file)
index 0000000..de6808d
--- /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" preserveAspectRatio="xMinYMid meet">\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/pix/i/db.png b/pix/i/db.png
new file mode 100644 (file)
index 0000000..3e51209
Binary files /dev/null and b/pix/i/db.png differ
diff --git a/pix/i/db.svg b/pix/i/db.svg
new file mode 100644 (file)
index 0000000..7adaaab
--- /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="-2 -1 16 16" style="overflow:visible;enable-background:new -2 -1 16 16;"\r
+        xml:space="preserve" preserveAspectRatio="xMinYMid meet">\r
+<defs>\r
+</defs>\r
+<path style="fill:#999999;" d="M12,11c0,1.2,0,2,0,2c0,1-2.7,1.9-6,1.9c-3.3,0-6-0.8-6-1.9c0,0,0-0.8,0-2c0,1,2.7,1.9,6,1.9\r
+       C9.3,12.9,12,12.1,12,11z M6,9.9C2.7,9.9,0,9.1,0,8c0,1.2,0,2,0,2c0,1,2.7,1.9,6,1.9c3.3,0,6-0.8,6-1.9c0,0,0-0.8,0-2\r
+       C12,9.1,9.3,9.9,6,9.9z M6,6.9C2.7,6.9,0,6.1,0,5c0,1.2,0,2,0,2c0,1,2.7,1.9,6,1.9c3.3,0,6-0.8,6-1.9c0,0,0-0.8,0-2\r
+       C12,6.1,9.3,6.9,6,6.9z M12,1.9C12,0.8,9.3,0,6,0C2.7,0,0,0.8,0,1.9C0,1.9,0,4,0,4c0,1,2.7,1.9,6,1.9c3.3,0,6-0.8,6-1.9\r
+       C12,4,12,1.9,12,1.9z"/>\r
+</svg>\r
diff --git a/pix/i/files.png b/pix/i/files.png
new file mode 100644 (file)
index 0000000..9d7534b
Binary files /dev/null and b/pix/i/files.png differ
diff --git a/pix/i/files.svg b/pix/i/files.svg
new file mode 100644 (file)
index 0000000..22966d6
--- /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.3 16 16" style="overflow:visible;enable-background:new 0 -1.3 16 16;"\r
+        xml:space="preserve" preserveAspectRatio="xMinYMid meet">\r
+<defs>\r
+</defs>\r
+<path style="fill:#999999;" d="M8,2.5c-0.5,0-1-0.5-1-1V1c0-0.5-0.5-1-1-1H1C0.5,0,0,0.5,0,1v0.5c0,0.5,0,11,0,11c0,0.5,0.5,1,1,1\r
+       h14c0.5,0,1-0.5,1-1v-9c0-0.5-0.5-1-1-1H8z"/>\r
+</svg>\r
diff --git a/pix/i/hierarchylock.png b/pix/i/hierarchylock.png
new file mode 100644 (file)
index 0000000..c3cffd4
Binary files /dev/null and b/pix/i/hierarchylock.png differ
diff --git a/pix/i/hierarchylock.svg b/pix/i/hierarchylock.svg
new file mode 100644 (file)
index 0000000..188fce3
--- /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" preserveAspectRatio="xMinYMid meet">\r
+<defs>\r
+</defs>\r
+<path style="fill:#999999;" d="M5.9,15c0,0.3,0.1,1,0.3,1H0.6c-0.5,0-0.8-0.4-0.5-0.9L1.7,12h4.3c0,0,0,0,0,0V15z M4.2,7l-2,4h4.1\r
+       c0.1-0.2,0.2-0.3,0.4-0.5C7,10.2,7.5,10,7.5,10c0-1.2,0.3-2.1,1.3-3c0,0,0,0,0.1-0.1H4.2z M11.3,6L8.4,0.4c-0.2-0.5-0.7-0.5-0.9,0\r
+       L4.7,6H11.3z M14.4,10v1H15c0.5,0,1,0.5,1,1v3c0,0.5-0.5,1-1,1l-7,0c-0.5,0-1-0.5-1-1v-3c0-0.5,0.4-1,1-1h0.6v-1c0-1.6,1.3-3,2.9-3\r
+       C13.1,7,14.4,8.3,14.4,10z M11.5,12c-0.5,0-1,0.4-1,1c0,0.4,0.2,0.7,0.6,0.9L11,14l-0.5,1l1,0l1,0L12,14l-0.1-0.1\r
+       c0.3-0.2,0.6-0.5,0.6-0.9C12.5,12.5,12,12,11.5,12z M11.5,9c-0.5,0-1,0.4-1,1v1h1.9v-1C12.4,9.4,12,9,11.5,9z"/>\r
+</svg>\r
diff --git a/pix/i/permissionlock.png b/pix/i/permissionlock.png
new file mode 100644 (file)
index 0000000..ce2dafe
Binary files /dev/null and b/pix/i/permissionlock.png differ
diff --git a/pix/i/permissionlock.svg b/pix/i/permissionlock.svg
new file mode 100644 (file)
index 0000000..e0798e9
--- /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 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="M2.4,9C2.4,9,1,7.2,1,5.2C1,2.3,2.8,0,5,0s4,2.3,4,5.2C9,7.2,7.6,9,7.6,9c-0.3,0.3-0.2,0.7,0,1\r
+       c-0.4,0.1-0.7,0.3-1,0.5C6.2,10.9,6,11.4,6,12v3c0,0.3,0.1,0.7,0.3,1H0v-4.5l2.2-1.2C2.7,10,2.8,9.5,2.4,9z M14.5,10v1H15\r
+       c0.5,0,1,0.5,1,1v3c0,0.5-0.5,1-1,1l-7,0c-0.5,0-1-0.5-1-1v-3c0-0.5,0.4-1,1-1h0.6v-1c0-1.6,1.3-3,2.9-3C13.2,7,14.5,8.3,14.5,10z\r
+        M11.5,12c-0.5,0-1,0.4-1,1c0,0.4,0.2,0.7,0.6,0.9L11,14l-0.5,1l1,0l1,0L12,14L12,13.9c0.3-0.2,0.6-0.5,0.6-0.9\r
+       C12.5,12.4,12.1,12,11.5,12z M11.5,9c-0.5,0-1,0.4-1,1v1h1.9v-1C12.5,9.4,12.1,9,11.5,9z"/>\r
+</svg>\r
diff --git a/pix/i/reload.png b/pix/i/reload.png
new file mode 100644 (file)
index 0000000..9c849d1
Binary files /dev/null and b/pix/i/reload.png differ
diff --git a/pix/i/reload.svg b/pix/i/reload.svg
new file mode 100644 (file)
index 0000000..6f86fba
--- /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="M7.9,16c4,0,7.4-3,7.8-7h-3c-0.5,2-2.5,4-4.9,4c-2.8,0-5-2.2-5-5c0-2.8,2.2-5,5-5c1.1,0,2.1,0,3,1h-1\r
+       C9.3,4,9,4.5,9,5.1v1C9,6.6,9.3,7,9.8,7h4h1C15.4,7,16,6.6,16,6.1v-1v-4C16,0.5,15.4,0,14.8,0h-1C13.3,0,13,0.5,13,1.1v0.9\r
+       c-1-1.1-3.1-1.8-5-1.8C3.6,0.2,0,3.7,0,8.1C0,12.4,3.5,16,7.9,16z"/>\r
+</svg>\r
diff --git a/pix/i/risk_config.png b/pix/i/risk_config.png
new file mode 100644 (file)
index 0000000..00d0d83
Binary files /dev/null and b/pix/i/risk_config.png differ
diff --git a/pix/i/risk_config.svg b/pix/i/risk_config.svg
new file mode 100644 (file)
index 0000000..9945d51
--- /dev/null
@@ -0,0 +1,19 @@
+<?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.1 16 16"\r
+        style="overflow:visible;enable-background:new -0.1 -0.1 16 16;" xml:space="preserve" preserveAspectRatio="xMinYMid meet">\r
+<defs>\r
+</defs>\r
+<path style="fill:#99CC33;" d="M15.6,14.1L8.8,0.7c-0.5-1-1.3-1-1.8,0L0.2,14.1c-0.5,1,0,1.8,1.1,1.8h13.2\r
+       C15.6,15.9,16.1,15.1,15.6,14.1z M12.3,11.1l-1.2,0.2c-0.1,0.2-0.2,0.4-0.3,0.7l0.7,1c-0.3,0.4-0.6,0.8-1,1l-1-0.7\r
+       c-0.2,0.1-0.4,0.2-0.6,0.3l-0.2,1.2c-0.2,0-0.5,0.1-0.7,0.1c-0.3,0-0.5,0-0.7-0.1L7,13.6c-0.2-0.1-0.4-0.2-0.6-0.3l-1,0.7\r
+       c-0.4-0.3-0.8-0.6-1-1L5,12c-0.1-0.2-0.2-0.4-0.3-0.7l-1.2-0.2c0-0.2-0.1-0.5-0.1-0.7c0-0.3,0-0.5,0.1-0.7l1.2-0.2\r
+       C4.8,9.2,4.8,9,5,8.8l-0.7-1c0.3-0.4,0.6-0.8,1-1l1,0.7C6.5,7.3,6.7,7.2,7,7.2L7.2,6c0.2,0,0.5-0.1,0.7-0.1c0.3,0,0.5,0,0.7,0.1\r
+       l0.2,1.2c0.2,0.1,0.4,0.2,0.6,0.3l1-0.7c0.4,0.3,0.8,0.6,1,1l-0.7,1C11,9,11.1,9.2,11.1,9.4l1.2,0.2c0,0.2,0.1,0.5,0.1,0.7\r
+       C12.4,10.6,12.4,10.9,12.3,11.1z M9,10.4c0,0.6-0.5,1.1-1.1,1.1S6.8,11,6.8,10.4c0-0.6,0.5-1.1,1.1-1.1S9,9.8,9,10.4z"/>\r
+</svg>\r
diff --git a/pix/i/risk_dataloss.png b/pix/i/risk_dataloss.png
new file mode 100644 (file)
index 0000000..11ce695
Binary files /dev/null and b/pix/i/risk_dataloss.png differ
diff --git a/pix/i/risk_dataloss.svg b/pix/i/risk_dataloss.svg
new file mode 100644 (file)
index 0000000..02c3c4a
--- /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.1 -0.2 16 16"\r
+        style="overflow:visible;enable-background:new -0.1 -0.2 16 16;" xml:space="preserve" preserveAspectRatio="xMinYMid meet">\r
+<defs>\r
+</defs>\r
+<path style="fill:#CC6AFF;" d="M7,0.7L0.2,14.1c-0.5,1,0,1.8,1.1,1.8h13.2c1.1,0,1.6-0.8,1.1-1.8L8.8,0.7C8.3-0.2,7.5-0.2,7,0.7z\r
+        M11.9,9.4h-0.5l-1,5.5h-5l-1-5.5H3.9l0-1h0.3l0-0.1c0,0,0.8-0.7,2.5-1V6.9c0-0.5,0.5-1,1-1h0.5c0.5,0,1,0.5,1,1v0.4\r
+       c1.7,0.3,2.5,1,2.5,1l0,0.1h0.3V9.4z M7.4,9.4v4.5h-1V9.4H7.4z M8.4,9.4h1v4.5h-1V9.4z M7.9,7.1c-0.2,0-0.3,0-0.5,0c0,0,0-0.1,0-0.1\r
+       c0-0.3,0.2-0.5,0.5-0.5c0.3,0,0.5,0.2,0.5,0.5c0,0,0,0.1,0,0.1C8.3,7.1,8.1,7.1,7.9,7.1z"/>\r
+</svg>\r
diff --git a/pix/i/risk_managetrust.png b/pix/i/risk_managetrust.png
new file mode 100644 (file)
index 0000000..4f3203d
Binary files /dev/null and b/pix/i/risk_managetrust.png differ
diff --git a/pix/i/risk_managetrust.svg b/pix/i/risk_managetrust.svg
new file mode 100644 (file)
index 0000000..beb87d3
--- /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.1 -0.1 16 16"\r
+        style="overflow:visible;enable-background:new -0.1 -0.1 16 16;" xml:space="preserve" preserveAspectRatio="xMinYMid meet">\r
+<defs>\r
+</defs>\r
+<path style="fill:#999999;" d="M15.6,14.1l-2.5-4.9c-0.5-1-1.3-2.6-1.8-3.6L8.8,0.7c-0.5-1-1.3-1-1.8,0L4.5,5.6\r
+       C4,6.6,3.2,8.2,2.7,9.2l-2.5,4.9c-0.5,1,0,1.8,1.1,1.8h4.6c1.1,0,2.9,0,4,0h4.6C15.6,15.9,16.1,15.1,15.6,14.1z M7.9,12.9H4.1L6,9.4\r
+       l1.9-3.5l1.9,3.5l1.9,3.5H7.9z"/>\r
+</svg>\r
diff --git a/pix/i/risk_personal.png b/pix/i/risk_personal.png
new file mode 100644 (file)
index 0000000..6d518d9
Binary files /dev/null and b/pix/i/risk_personal.png differ
diff --git a/pix/i/risk_personal.svg b/pix/i/risk_personal.svg
new file mode 100644 (file)
index 0000000..03b5c61
--- /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.1 -0.1 16 16"\r
+        style="overflow:visible;enable-background:new -0.1 -0.1 16 16;" xml:space="preserve" preserveAspectRatio="xMinYMid meet">\r
+<defs>\r
+</defs>\r
+<path style="fill:#76A1F0;" d="M7,0.7L0.2,14.1c-0.5,1,0,1.8,1.1,1.8l13.2,0c1.1,0,1.6-0.8,1.1-1.8L8.8,0.7C8.3-0.2,7.5-0.2,7,0.7z\r
+        M10.6,9c0,1.2-0.7,2.1-1.8,2.5L9,11.9l1.1,2.4l-2.2,0l-2.2,0l1.1-2.4L7,11.5C6,11.1,5.2,10.1,5.2,9c0-1.5,1.2-2.7,2.7-2.7\r
+       C9.4,6.3,10.6,7.5,10.6,9z"/>\r
+</svg>\r
diff --git a/pix/i/risk_spam.png b/pix/i/risk_spam.png
new file mode 100644 (file)
index 0000000..46b6bd6
Binary files /dev/null and b/pix/i/risk_spam.png differ
diff --git a/pix/i/risk_spam.svg b/pix/i/risk_spam.svg
new file mode 100644 (file)
index 0000000..235d2e2
--- /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.1 -0.1 16 16"\r
+        style="overflow:visible;enable-background:new -0.1 -0.1 16 16;" xml:space="preserve" preserveAspectRatio="xMinYMid meet">\r
+<defs>\r
+</defs>\r
+<path style="fill:#FFB844;" d="M15.6,14.1L8.8,0.7c-0.5-1-1.3-1-1.8,0L0.2,14.1c-0.5,1,0,1.8,1.1,1.8h13.2\r
+       C15.6,15.9,16.1,15.1,15.6,14.1z M8.3,6.5c0.6-0.6,1.5-0.6,2.1,0s0.6,1.5,0,2.1l-1,1L7.3,7.5L8.3,6.5z M5,13.9H2.9v-2.1l3.6-3.6\r
+       l2.1,2.1L5,13.9z M11.9,13.9h-5v-1h5V13.9z"/>\r
+</svg>\r
diff --git a/pix/i/risk_xss.png b/pix/i/risk_xss.png
new file mode 100644 (file)
index 0000000..345f999
Binary files /dev/null and b/pix/i/risk_xss.png differ
diff --git a/pix/i/risk_xss.svg b/pix/i/risk_xss.svg
new file mode 100644 (file)
index 0000000..178135d
--- /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.1 -0.1 16 16"\r
+        style="overflow:visible;enable-background:new -0.1 -0.1 16 16;" xml:space="preserve" preserveAspectRatio="xMinYMid meet">\r
+<defs>\r
+</defs>\r
+<path style="fill:#FF403C;" d="M7,0.7L0.2,14.1c-0.5,1,0,1.8,1.1,1.8l13.2,0c1.1,0,1.6-0.8,1.1-1.8L8.8,0.7C8.3-0.2,7.5-0.2,7,0.7z\r
+        M9.4,13.4c0,0.8-0.7,1.5-1.5,1.5c-0.8,0-1.5-0.7-1.5-1.5c0-0.8,0.7-1.5,1.5-1.5C8.7,11.9,9.4,12.5,9.4,13.4z M9.2,5.9v4\r
+       c0,0.5-0.5,1-1,1l-0.6,0c-0.5,0-1-0.5-1-1v-4c0-0.6,0.5-1,1-1l0.6,0C8.8,4.9,9.2,5.3,9.2,5.9z"/>\r
+</svg>\r
diff --git a/pix/i/roles.png b/pix/i/roles.png
new file mode 100644 (file)
index 0000000..f803c86
Binary files /dev/null and b/pix/i/roles.png differ
diff --git a/pix/i/roles.svg b/pix/i/roles.svg
new file mode 100644 (file)
index 0000000..9fc0081
--- /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" preserveAspectRatio="xMinYMid meet">\r
+<defs>\r
+</defs>\r
+<path style="fill:#999999;" d="M5.2,10.3L0,13.1V16h16v-3l-5.2-2.7C10.3,10,10.2,9.4,10.6,9c0,0,1.4-1.8,1.4-3.8C12,2.3,10.2,0,8,0\r
+       S4,2.3,4,5.2C4,7.2,5.4,9,5.4,9C5.8,9.5,5.7,10,5.2,10.3z"/>\r
+</svg>\r
diff --git a/pix/i/search.png b/pix/i/search.png
new file mode 100644 (file)
index 0000000..fc2aa28
Binary files /dev/null and b/pix/i/search.png differ
diff --git a/pix/i/search.svg b/pix/i/search.svg
new file mode 100644 (file)
index 0000000..0f55507
--- /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="M15.5,13.4l-2.1-2.1c-0.2-0.2-0.4-0.3-0.7-0.4C13.5,9.8,14,8.5,14,7c0-3.9-3.1-7-7-7C3.1,0,0,3.1,0,7\r
+       s3.1,7,7,7c1.5,0,2.8-0.5,4-1.2c0.1,0.3,0.2,0.5,0.4,0.7l2.1,2.1c0.6,0.6,1.5,0.6,2.1,0S16.1,14,15.5,13.4z M7,11c-2.2,0-4-1.8-4-4\r
+       s1.8-4,4-4c2.2,0,4,1.8,4,4S9.2,11,7,11z"/>\r
+</svg>\r
index 77011db..f803c86 100644 (file)
Binary files a/pix/i/switchrole.png and b/pix/i/switchrole.png differ
index 8e383de..9fc0081 100644 (file)
@@ -9,7 +9,6 @@
         xml:space="preserve" preserveAspectRatio="xMinYMid meet">\r
 <defs>\r
 </defs>\r
-<path style="fill:#999999;" d="M10.8,10.3C10.3,10,10.2,9.4,10.6,9c0,0,1.4-1.8,1.4-3.8C12,2.3,10.2,0,8,0S4,2.3,4,5.2\r
-       C4,7.2,5.4,9,5.4,9c0.3,0.4,0.2,1-0.3,1.3L0,13.1V16h6.6L7,14.2l0.5-1.8l-0.6-0.6L7.7,11h0.6l0.8,0.8l-0.6,0.6L9,14.2L9.5,16H16v-3\r
-       L10.8,10.3z"/>\r
+<path style="fill:#999999;" d="M5.2,10.3L0,13.1V16h16v-3l-5.2-2.7C10.3,10,10.2,9.4,10.6,9c0,0,1.4-1.8,1.4-3.8C12,2.3,10.2,0,8,0\r
+       S4,2.3,4,5.2C4,7.2,5.4,9,5.4,9C5.8,9.5,5.7,10,5.2,10.3z"/>\r
 </svg>\r
diff --git a/pix/i/tick_amber_big.png b/pix/i/tick_amber_big.png
new file mode 100644 (file)
index 0000000..1733b8a
Binary files /dev/null and b/pix/i/tick_amber_big.png differ
diff --git a/pix/i/tick_amber_big.svg b/pix/i/tick_amber_big.svg
new file mode 100644 (file)
index 0000000..4e2bb31
--- /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" preserveAspectRatio="xMinYMid meet">\r
+<defs>\r
+</defs>\r
+<path style="fill:#FFB844;" 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/pix/i/tick_amber_small.png b/pix/i/tick_amber_small.png
new file mode 100644 (file)
index 0000000..1733b8a
Binary files /dev/null and b/pix/i/tick_amber_small.png differ
diff --git a/pix/i/tick_amber_small.svg b/pix/i/tick_amber_small.svg
new file mode 100644 (file)
index 0000000..4e2bb31
--- /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" preserveAspectRatio="xMinYMid meet">\r
+<defs>\r
+</defs>\r
+<path style="fill:#FFB844;" 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/pix/i/tick_green_big.png b/pix/i/tick_green_big.png
new file mode 100644 (file)
index 0000000..11ef29b
Binary files /dev/null and b/pix/i/tick_green_big.png differ
diff --git a/pix/i/tick_green_big.svg b/pix/i/tick_green_big.svg
new file mode 100644 (file)
index 0000000..c5156f3
--- /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" preserveAspectRatio="xMinYMid meet">\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/pix/i/tick_green_small.png b/pix/i/tick_green_small.png
new file mode 100644 (file)
index 0000000..11ef29b
Binary files /dev/null and b/pix/i/tick_green_small.png differ
diff --git a/pix/i/tick_green_small.svg b/pix/i/tick_green_small.svg
new file mode 100644 (file)
index 0000000..c5156f3
--- /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" preserveAspectRatio="xMinYMid meet">\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/pix/t/addgreen.png b/pix/t/addgreen.png
new file mode 100644 (file)
index 0000000..fd8cbbe
Binary files /dev/null and b/pix/t/addgreen.png differ
diff --git a/pix/t/addgreen.svg b/pix/t/addgreen.svg
new file mode 100644 (file)
index 0000000..9197663
--- /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="12px" height="12px" viewBox="0 0 12 12" style="overflow:visible;enable-background:new 0 0 12 12;"\r
+        xml:space="preserve" preserveAspectRatio="xMinYMid meet">\r
+<defs>\r
+</defs>\r
+<path style="fill:#999999;" d="M11,4.5H7.5V1c0-0.5-0.5-1-1-1h-1c-0.5,0-1,0.5-1,1v3.5L1,4.5c-0.5,0-1,0.5-1,1v1c0,0.5,0.5,1,1,1\r
+       h3.5V11c0,0.5,0.5,1,1,1h1c0.5,0,1-0.5,1-1V7.5H11c0.6,0,1-0.5,1-1l0-1C12,5,11.6,4.5,11,4.5z"/>\r
+</svg>\r
diff --git a/pix/t/clear.png b/pix/t/clear.png
new file mode 100644 (file)
index 0000000..43540a5
Binary files /dev/null and b/pix/t/clear.png differ
diff --git a/pix/t/clear.svg b/pix/t/clear.svg
new file mode 100644 (file)
index 0000000..5c768d1
--- /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="12px" height="12px" viewBox="0 0 12 12" style="overflow:visible;enable-background:new 0 0 12 12;"\r
+        xml:space="preserve" preserveAspectRatio="xMinYMid meet">\r
+<defs>\r
+</defs>\r
+<path style="fill:#999999;" d="M11.4,0.6l-0.9-0.5C10.1-0.1,9.5,0,9.2,0.5L4.7,8.2L2,6.6C1.5,6.3,0.9,6.5,0.6,7L0.1,7.8\r
+       C-0.1,8.3,0,8.9,0.5,9.2L5,11.8c0.1,0.1,0.3,0.1,0.4,0.1c0.4,0.1,0.8-0.1,1-0.5L11.8,2C12.1,1.5,11.9,0.9,11.4,0.6z"/>\r
+</svg>\r
diff --git a/pix/t/contextmenu.png b/pix/t/contextmenu.png
new file mode 100644 (file)
index 0000000..e9b81e4
Binary files /dev/null and b/pix/t/contextmenu.png differ
diff --git a/pix/t/contextmenu.svg b/pix/t/contextmenu.svg
new file mode 100644 (file)
index 0000000..e9eb130
--- /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" preserveAspectRatio="xMinYMid meet">\r
+<defs>\r
+</defs>\r
+<path style="fill:#999999;" d="M4.4,12H0V0h12v4.4C11.8,4.2,11.5,4,11,4V3H1v2h3.3C4.1,5.3,4,5.6,4,6v0H1v2h3v1H1v2h3\r
+       C4,11.4,4.2,11.8,4.4,12z M8.5,12l-1-1H7.3l-0.9,0.9c0,0-0.1,0-0.1,0.1H8.5z M11,7.5l1,1V6.3c0,0,0,0.1-0.1,0.1L11,7.3V7.5z\r
+        M11.7,9.5L9.5,7.4l1.7-1.7C11.6,5.3,11.5,5,10.9,5H6C5.4,5,5,5.4,5,6v4.9c0,0.5,0.3,0.7,0.7,0.3l1.7-1.7l2.1,2.1\r
+       c0.4,0.4,1,0.4,1.4,0l0.7-0.7C12,10.6,12,9.9,11.7,9.5z"/>\r
+</svg>\r
diff --git a/pix/t/manual_item.png b/pix/t/manual_item.png
new file mode 100644 (file)
index 0000000..830c426
Binary files /dev/null and b/pix/t/manual_item.png differ
diff --git a/pix/t/manual_item.svg b/pix/t/manual_item.svg
new file mode 100644 (file)
index 0000000..ecbbb58
--- /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="M15,5.2V15c0,0.5-0.5,1-1,1H1c-0.5,0-1-0.5-1-1V2c0-0.5,0.5-1,1-1h9.8l-2,2H3C2.5,3,2,3.4,2,4v9\r
+       c0,0.5,0.5,1,1,1h9c0.5,0,1-0.5,1-1V7.2L15,5.2z M15.4,0.6L15.4,0.6c-0.8-0.8-2.1-0.8-2.8,0l-1,1l2.8,2.8l1-1\r
+       C16.2,2.6,16.2,1.4,15.4,0.6z M10.6,2.6L4,9.1V12h2.8c0,0,1.8-1.8,1.8-1.8l4.8-4.8L10.6,2.6z"/>\r
+</svg>\r
diff --git a/pix/t/unlock_gray.png b/pix/t/unlock_gray.png
new file mode 100644 (file)
index 0000000..04b8c5b
Binary files /dev/null and b/pix/t/unlock_gray.png differ
diff --git a/pix/t/unlock_gray.svg b/pix/t/unlock_gray.svg
new file mode 100644 (file)
index 0000000..72eb809
--- /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="12px" height="12px" viewBox="0 0 12 12" style="overflow:visible;enable-background:new 0 0 12 12;"\r
+        xml:space="preserve" preserveAspectRatio="xMinYMid meet">\r
+<defs>\r
+</defs>\r
+<path style="fill:#999999;" d="M6.5,0l-1,0c-1.7,0-3,1.3-3,3v2H1C0.5,5,0,5.5,0,6l0,5c0,0.6,0.4,1,1,1h10c0.5,0,1-0.5,1-1l0-5\r
+       c0-0.6-0.5-1-1-1H9.5l0-2C9.5,1.3,8.2,0,6.5,0z M7,8c0,0.4-0.2,0.7-0.6,0.9L6.5,9L7,10H6H5l0.5-1l0.1-0.1C5.2,8.7,5,8.4,5,8\r
+       c0-0.5,0.4-1,1-1S7,7.5,7,8z M7.5,3v2l-3,0V3c0-0.6,0.5-1,1-1h1C7.1,2,7.5,2.4,7.5,3z"/>\r
+</svg>\r
diff --git a/pix/t/user.png b/pix/t/user.png
new file mode 100644 (file)
index 0000000..e7ca8cc
Binary files /dev/null and b/pix/t/user.png differ
diff --git a/pix/t/user.svg b/pix/t/user.svg
new file mode 100644 (file)
index 0000000..a1220af
--- /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="12px" height="12px" viewBox="0 0 12 12" style="overflow:visible;enable-background:new 0 0 12 12;"\r
+        xml:space="preserve" preserveAspectRatio="xMinYMid meet">\r
+<defs>\r
+</defs>\r
+<path style="fill:#999999;" d="M3.7,7.6L0.1,9.4c0,0-0.1,0-0.1,0.1V12h12V9.3c0,0-0.1-0.1-0.1-0.1L8.3,7.5C7.8,7.3,7.7,6.7,8,6.3\r
+       c0,0,0.9-1.1,0.9-2.5C8.9,1.7,7.6,0,6,0C4.4,0,3.1,1.7,3.1,3.8C3.1,5.2,4,6.3,4,6.3C4.3,6.7,4.2,7.3,3.7,7.6z"/>\r
+</svg>\r
diff --git a/pix/t/userblue.png b/pix/t/userblue.png
new file mode 100644 (file)
index 0000000..e7ca8cc
Binary files /dev/null and b/pix/t/userblue.png differ
diff --git a/pix/t/userblue.svg b/pix/t/userblue.svg
new file mode 100644 (file)
index 0000000..a1220af
--- /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="12px" height="12px" viewBox="0 0 12 12" style="overflow:visible;enable-background:new 0 0 12 12;"\r
+        xml:space="preserve" preserveAspectRatio="xMinYMid meet">\r
+<defs>\r
+</defs>\r
+<path style="fill:#999999;" d="M3.7,7.6L0.1,9.4c0,0-0.1,0-0.1,0.1V12h12V9.3c0,0-0.1-0.1-0.1-0.1L8.3,7.5C7.8,7.3,7.7,6.7,8,6.3\r
+       c0,0,0.9-1.1,0.9-2.5C8.9,1.7,7.6,0,6,0C4.4,0,3.1,1.7,3.1,3.8C3.1,5.2,4,6.3,4,6.3C4.3,6.7,4.2,7.3,3.7,7.6z"/>\r
+</svg>\r
index 5f51d0a..abe0b39 100644 (file)
@@ -1,5 +1,11 @@
 This files describes API changes for question behaviour plugins.
 
+=== 2.3 ===
+
+* This plugin type now supports cron in the standard way. If required, Create a
+  lib.php file containing
+function qbehaviour_mypluginname_cron() {};
+
 === 2.2 ===
 
 1) The old
@@ -14,10 +20,3 @@ $plugin->dependencies = array(
 is_compatible_question method. You should change your behaviour to override the
 new method, not the old one. This change has been implemented in a
 backwards-compatible way, so behaviours will not break.
-
-
-=== 2.3 ===
-
-* This plugin type now supports cron in the standard way. If required, Create a
-  lib.php file containing
-function qbehaviour_mypluginname_cron() {};
index e28fe30..8f2396e 100644 (file)
@@ -73,7 +73,7 @@ if ($from_form = $export_form->get_data()) {
     echo get_string('yourfileshoulddownload', 'question', $export_url->out());
     echo $OUTPUT->box_end();
 
-    $PAGE->requires->js_function_call('document.location.replace', array($export_url->out()), false, 1);
+    $PAGE->requires->js_function_call('document.location.replace', array($export_url->out(false)), false, 1);
 
     echo $OUTPUT->continue_button(new moodle_url('edit.php', $thispageurl->params()));
     echo $OUTPUT->footer();
index b31a7a0..527526d 100644 (file)
@@ -1,5 +1,11 @@
 This files describes API changes for question import/export format plugins.
 
+=== 2.3 ===
+
+* This plugin type now supports cron in the standard way. If required, Create a
+  lib.php file containing
+function qformat_mypluginname_cron() {};
+
 === 2.1.5 / 2.2.3 / 2.3 ===
 
 * The readquestions method used to take a second argument $context. However, at
@@ -24,9 +30,3 @@ $string['pluginname'] = 'Aiken format';
 $string['pluginname_help'] = 'This is a simple format ...';
 $string['pluginname_link'] = 'qformat/aiken';
 
-
-=== 2.3 ===
-
-* This plugin type now supports cron in the standard way. If required, Create a
-  lib.php file containing
-function qformat_mypluginname_cron() {};
index 5afe4ff..a24a4fd 100644 (file)
@@ -118,10 +118,6 @@ abstract class qtype_multianswer_subq_renderer_base extends qtype_renderer {
     protected function feedback_popup(question_graded_automatically $subq,
             $fraction, $feedbacktext, $rightanswer, question_display_options $options) {
 
-        if (!$options->feedback) {
-            return '';
-        }
-
         $feedback = array();
         if ($options->correctness) {
             if (is_null($fraction)) {
@@ -132,7 +128,7 @@ abstract class qtype_multianswer_subq_renderer_base extends qtype_renderer {
             $feedback[] = $state->default_string(true);
         }
 
-        if ($feedbacktext) { // Note $options->feedback is already checked above.
+        if ($options->feedback && $feedbacktext) {
             $feedback[] = $feedbacktext;
         }
 
@@ -141,7 +137,8 @@ abstract class qtype_multianswer_subq_renderer_base extends qtype_renderer {
         }
 
         $subfraction = '';
-        if ($options->marks >= question_display_options::MARK_AND_MAX && $subq->maxmark > 0) {
+        if ($options->marks >= question_display_options::MARK_AND_MAX && $subq->maxmark > 0
+                && (!is_null($fraction) || $feedback)) {
             $a = new stdClass();
             $a->mark = format_float($fraction * $subq->maxmark, $options->markdp);
             $a->max =  format_float($subq->maxmark, $options->markdp);
index 5fda822..7647c8e 100644 (file)
@@ -280,7 +280,10 @@ function report_log_print_mnet_selector_form($hostid, $course, $selecteduser=0,
     $timemidnight = $today = usergetmidnight($timenow);
 
     // Put today up the top of the list
-    $dates = array("$timemidnight" => get_string("today").", ".userdate($timenow, $strftimedate) );
+    $dates = array(
+        "0" => get_string('alldays'),
+        "$timemidnight" => get_string("today").", ".userdate($timenow, $strftimedate)
+    );
 
     if (!$course->startdate or ($course->startdate > $timenow)) {
         $course->startdate = $course->timecreated;
@@ -294,7 +297,7 @@ function report_log_print_mnet_selector_form($hostid, $course, $selecteduser=0,
         $numdates++;
     }
 
-    if ($selecteddate == "today") {
+    if ($selecteddate === "today") {
         $selecteddate = $today;
     }
 
@@ -354,7 +357,7 @@ function report_log_print_mnet_selector_form($hostid, $course, $selecteduser=0,
     }
 
     echo html_writer::label(get_string('date'), 'menudate', false, array('class' => 'accesshide'));
-    echo html_writer::select($dates, "date", $selecteddate, get_string("alldays"));
+    echo html_writer::select($dates, "date", $selecteddate, false);
     echo html_writer::label(get_string('showreports'), 'menumodid', false, array('class' => 'accesshide'));
     echo html_writer::select($activities, "modid", $selectedactivity, get_string("allactivities"));
     echo html_writer::label(get_string('actions'), 'menumodaction', false, array('class' => 'accesshide'));
index aa35dfe..e467b23 100644 (file)
@@ -71,17 +71,13 @@ class repository_webdav extends repository {
         return true;
     }
     public function get_file($url, $title = '') {
-        global $CFG;
         $url = urldecode($url);
         $path = $this->prepare_file($title);
-        $buffer = '';
         if (!$this->dav->open()) {
             return false;
         }
         $webdavpath = rtrim('/'.ltrim($this->options['webdav_path'], '/ '), '/ '); // without slash in the end
-        $this->dav->get($webdavpath. $url, $buffer);
-        $fp = fopen($path, 'wb');
-        fwrite($fp, $buffer);
+        $this->dav->get_file($webdavpath. $url, $path);
         return array('path'=>$path);
     }
     public function global_search() {
index b1827bb..5774931 100644 (file)
@@ -504,6 +504,9 @@ body.tag .managelink {padding: 5px;}
 .path-backup .backup_progress span.backup_stage.backup_stage_complete {color:inherit;}
 #page-backup-restore .filealiasesfailures {background-color:#ffd3d9}
 #page-backup-restore .filealiasesfailures .aliaseslist {width:90%;margin:0.8em auto;background-color:white;border:1px dotted #666;}
+.path-backup .fitemtitle .iconlarge.icon-post { padding-left: 6px; }
+.path-backup.dir-rtl .fitemtitle .iconlarge.icon-post { padding-right: 6px; padding-right: 0; }
+.path-backup .fitem .smallicon { vertical-align: text-bottom; }
 
 /**
  * Web Service
index a5fb7ff..e4175af 100644 (file)
@@ -42,3 +42,6 @@ body.has_dock {margin-left:30px;}
 .dir-rtl #dock {left:auto;right: 0%; border-left: 1px solid #DDD;}
 .dir-rtl #dock .dockedtitle { border-bottom: 1px solid #DDD;border-top: 1px solid #EEE;  cursor: pointer;}
 body.dir-rtl.has_dock  {margin-left: 0px; margin-right: 30px}
+
+/* Test span used to calculate positioning of docked item labels */
+.transform-test-node { position:absolute;line-height:normal; }
\ No newline at end of file
index 32102d3..d4cb500 100644 (file)
@@ -7,8 +7,11 @@
 
 .user-box {margin:8px;width:115px;height:160px;text-align:center;float:left;clear: none;}
 
+.userlist .main .action-icon img {vertical-align: middle;}
+
 .userlist #showall {margin: 10px 0px;}
 .userlist .buttons {text-align: center;}
+.userlist .buttons label {padding: 0 3px;}
 .userlist table#participants {text-align:center;}
 .userlist table#participants td,
 .userlist table#participants th {vertical-align: middle;text-align: left;padding: 4px;}
index bb572db..3529df6 100644 (file)
@@ -844,6 +844,11 @@ table#categoryquestions th a {
     padding: 5px;
 }
 
+.generaltable .header,
+.generaltable .header a {
+    padding: 0;
+}
+
 tr.r1 td {
     background-color: #f9f9f9;
 }
index 6642157..0c2ddb2 100644 (file)
@@ -89,11 +89,10 @@ $(document).ready(function() {
 
 
     //course page only js
-    $('div.path-course-view, .path-course-view div.generalpage').live('pagebeforecreate', function(event, ui) {
+    $('div.path-site, div.path-course-view, .path-course-view div.generalpage').live('pagebeforecreate', function(event, ui) {
         //course listing
-        $('.section li img').addClass("ui-li-icon");
-        $('.course-content ul.section').attr("data-role", "listview").attr("data-inset", "true").attr("data-theme", mythemeb);
-        $('.sitetopic ul.section').attr("data-role", "listview").attr("data-inset", "true").attr("data-theme", mythemeb);
+        $('.section li img.activityicon').addClass("ui-li-icon");
+        $('.course-content ul.section, .sitetopic ul.section').attr("data-role", "listview").attr("data-inset", "true").attr("data-theme", mythemeb);
         $('.topics div.left.side').addClass("ui-bar-" + mytheme);
         $('.section.hidden div.headingwrap').attr("data-theme", mythemeb);
         //$('.topics #section-0 div.left.side').removeClass("ui-li ui-li-divider ui-btn ui-bar-a");
@@ -108,6 +107,12 @@ $(document).ready(function() {
             this.form.submit();
             return false;
         });
+
+        // Force the class ui-li-desc on non-detected elements.
+        $('ul.section div.availabilityinfo, ul.section div.contentafterlink').addClass('ui-li-desc');
+
+        // Force some classes on dimmed elements.
+        $('ul.section div.dimmed_text > span').addClass('instancename');
     });
 
     //forum listing only stuff
index 058936c..891f6a9 100644 (file)
@@ -5048,7 +5048,15 @@ $.widget( "mobile.listview", $.mobile.widget, {
                        // If we're creating the element, we update it regardless
                        if ( create || !item.hasClass( "ui-li" ) ) {
                                itemTheme = item.jqmData("theme") || o.theme;
-                               a = this._getChildrenByTagName( item[ 0 ], "a", "A" );
+
+                               // Moodle Hack to nicely display the activities on the course page.
+                               // Activities <a> is not a children, we need to find it.
+                               if (item.hasClass( "activity" ) && (!item.hasClass( "label" ))) {
+                                       a = item.find( "a" );
+                               } else {
+                                       a = this._getChildrenByTagName( item[ 0 ], "a", "A" );
+                               }
+
                                var isDivider = ( item.jqmData( "role" ) === "list-divider" );
 
                                if ( a.length && !isDivider ) {
diff --git a/theme/mymobile/readme_moodle.txt b/theme/mymobile/readme_moodle.txt
new file mode 100644 (file)
index 0000000..99d4fcf
--- /dev/null
@@ -0,0 +1,16 @@
+MyMobile Theme
+==============
+
+jQuery Mobile listview hack
+---------------------------
+
+The jQuery Mobile library (jquery.mobile-[...].js) includes a custom hack to
+allow lisview elements to have a their <a> not as direct child of <li>. This
+is used for activities which encapsulate the <a> in several divs.
+
+Run the following command to view the hack:
+    git show 3b84abce6ab7ff3862cd92c7d74ce0e8578004b3
+
+Remember to place this hack in the library when you update it. Also, we often
+forget that activities can be listed on the front page too, please test the
+theme in both a course and the front page.
index ef45f30..b333b1d 100644 (file)
@@ -301,9 +301,28 @@ li a.dimmed span {
     padding-left: 10px;
 }
 */
-.course-content li.activity.ui-btn .ui-btn-text a {
-    padding-left: 35px;
+.sitetopic li.activity.ui-li-static div.activityinstance,
+.course-content li.activity.ui-li-static div.activityinstance,
+.sitetopic li.activity.ui-btn .ui-btn-text a,
+.course-content li.activity.ui-btn .ui-btn-text a,
+.sitetopic .section .activity .availabilityinfo,
+.sitetopic .section .activity .contentafterlink,
+.course-content .section .activity .availabilityinfo,
+.course-content .section .activity .contentafterlink {
+    padding-left: 45px;
     padding-right: 60px;
+    margin-left: 0;
+    margin-right: 0;
+    position: relative;
+}
+.sitetopic .section li.activity p.ui-li-desc a.autolink,
+.course-content .section li.activity p.ui-li-desc a.autolink {
+    padding: 0;
+    margin: 0;
+}
+.path-site li.activity.label > div,
+.path-course-view li.activity.label > div {
+    position: static;
 }
 .topics #section-0 div.left.side {
     display: none;
@@ -316,13 +335,9 @@ li a.dimmed span {
 .topics li.activity span.accesshide, .weeks li.activity span.accesshide, .ui-navbar span.accesshide {
     display: none;
 }
-.topics li.activity span.autocompletion, .weeks li.activity span.autocompletion {
-    display: block;
-    right: 70px;
-    top: -5px;
-}
+.sitetopic .section .activity img.activityicon,
 .course-content .section .activity img.activityicon {
-    margin-top: -.2em;
+    margin-top: -.5em;
 }
 li.activity.ui-li-static span, li.activity div.availabilityinfo {
     white-space: normal;
@@ -344,19 +359,21 @@ form.togglecompletion div {
 form.togglecompletion input {
     visibility: hidden;
 }
-.togglecompletion input[type="image"] {
+
+.path-course-view li.activity span.autocompletion {
+    position: static;
+}
+.path-course-view li.activity span.autocompletion img,
+.path-course-view li.activity form.togglecompletion [type="image"] {
     display: block !important;
     position: absolute !important;
     top: 21%;
-    right: 2em !important;
+    right: 4em !important;
     left:auto !important;
     visibility: visible;
     width: 26px;
     height: 23px;
 }
-li.activity.ui-li-static span, li.activity div.availabilityinfo{
-    margin-left: 1.3em;
-}
 .topics .content, .weeks .content {
     padding-left: 0px !important;
     padding-right: 0px !important;
@@ -410,6 +427,11 @@ li.activity.label {
     padding: .6em !important;
     cursor:default;
 }
+li.activity.label form.togglecompletion { position: relative; }
+.sitetopic .section .activity .activityinstance,
+.course-content .section .activity .activityinstance,
+.sitetopic .section .activity .activityinstance div,
+.course-content .section .activity .activityinstance div { display: block; }
 li.label .no-overflow ul, li.label .no-overflow ul li {
     list-style-position: inside;
 }
index 0cf29a7..949de96 100644 (file)
@@ -1,10 +1,5 @@
 /** Admin layout **/
 
-body.pagelayout-admin {
-    background-image: none;
-    background-color: #fff;
-}
-
 body.pagelayout-admin.has_dock {
     margin-left: 30px;
 }
@@ -13,7 +8,6 @@ body.pagelayout-admin.has_dock {
     margin: 0 auto;
     position: relative;
 }
-.pagelayout-admin #page-header,
 .pagelayout-admin #page-footer {
     float: none;
     background: #f3f3f3 none;
@@ -22,13 +16,6 @@ body.pagelayout-admin.has_dock {
     padding: 0;
     text-align: left;
 }
-.pagelayout-admin #page-header {
-    background:#97d3f4 url([[pix:theme|header]]) no-repeat top right;
-    margin-bottom: 0px;
-    height: 105px;
-    border-bottom: 1px solid #FFF;
-}
-
 .pagelayout-admin #page-header #custommenu {
     display: none;
 }
@@ -38,7 +25,6 @@ body.pagelayout-admin.has_dock {
     margin: 0;
     padding: 5px 0;
 }
-
 .pagelayout-admin #page-footer {
     text-align: center;
     height: auto;
@@ -49,7 +35,6 @@ body.pagelayout-admin.has_dock {
     padding: 0;
     text-align: center;
 }
-
 .pagelayout-admin #page-content {
     background: #FFF url([[pix:theme|top_bg]]) repeat-x center top;
     float: none;
index 670b1f0..05abd37 100644 (file)
@@ -49,12 +49,13 @@ echo $OUTPUT->doctype() ?>
     <div id="page-content">
         <table id="region-main-box" class="layout-table" summary="layout">
             <tr id="region-post-box">
+                <?php if ($hassidepre) { ?>
                 <td id="region-pre" class="block-region">
                     <div class="region-content">
                             <?php echo $OUTPUT->blocks_for_region('side-pre') ?>
                     </div>
                 </td>
-                <?php if ($hassidepre) { ?>
+                <?php } ?>
                 <td id="region-main-wrap">
                     <div id="region-main">
                         <div class="region-content">
@@ -62,9 +63,7 @@ echo $OUTPUT->doctype() ?>
                         </div>
                     </div>
                 </td>
-                <?php
-                }
-                if ($hassidepost) { ?>
+                <?php if ($hassidepost) { ?>
                 <td id="region-post" class="block-region">
                     <div class="region-content">
                         <?php echo $OUTPUT->blocks_for_region('side-post') ?>
index 0e74a17..1d15639 100644 (file)
@@ -38,6 +38,15 @@ if ($slashargument = min_get_slash_argument()) {
     if (substr_count($slashargument, '/') < 2) {
         image_not_found();
     }
+
+    if (strpos($slashargument, '_s/') === 0) {
+        // Can't use SVG
+        $slashargument = substr($slashargument, 3);
+        $usesvg = false;
+    } else {
+        $usesvg = true;
+    }
+
     // image must be last because it may contain "/"
     list($themename, $rev, $type) = explode('/', $slashargument, 3);
     $themename = min_clean_param($themename, 'SAFEDIR');
@@ -48,6 +57,7 @@ if ($slashargument = min_get_slash_argument()) {
     $themename = min_optional_param('theme', 'standard', 'SAFEDIR');
     $rev       = min_optional_param('rev', 0, 'INT');
     $type      = min_optional_param('type', 'all', 'SAFEDIR');
+    $usesvg    = (bool)min_optional_param('svg', '1', 'INT');
 }
 
 if (!in_array($type, array('all', 'ie', 'editor', 'plugins', 'parents', 'theme'))) {
@@ -68,8 +78,15 @@ if ($type === 'ie') {
     css_send_ie_css($themename, $rev, $etag, !empty($slashargument));
 }
 
-$candidatesheet = "$CFG->cachedir/theme/$themename/css/$type.css";
-$etag = sha1("$themename/$rev/$type");
+$candidatedir = "$CFG->cachedir/theme/$themename/css";
+$etag = "$themename/$rev/$type";
+if (!$usesvg) {
+    // Add to the sheet name, one day we'll be able to just drop this.
+    $candidatedir .= '/nosvg';
+    $etag .= '/nosvg';
+}
+$candidatesheet = "$candidatedir/$type.css";
+$etag = sha1($etag);
 
 if (file_exists($candidatesheet)) {
     if (!empty($_SERVER['HTTP_IF_NONE_MATCH']) || !empty($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
@@ -90,14 +107,25 @@ define('NO_UPGRADE_CHECK', true);  // Ignore upgrade check
 require("$CFG->dirroot/lib/setup.php");
 
 $theme = theme_config::load($themename);
+$theme->force_svg_use($usesvg);
 
 $rev = theme_get_revision();
-$etag = sha1("$themename/$rev/$type");
+
+$etag = "$themename/$rev/$type";
+if (!$usesvg) {
+    // Add to the etag, one day we'll be able to just delete svg nonsense this.
+    $etag .= '/nosvg';
+}
+$etag = sha1($etag);
 
 if ($type === 'editor') {
     $cssfiles = $theme->editor_css_files();
     css_store_css($theme, $candidatesheet, $cssfiles);
 } else {
+    $basedir = "$CFG->cachedir/theme/$themename/css";
+    if (!$usesvg) {
+        $basedir .= '/nosvg';
+    }
     $css = $theme->css_files();
     $allfiles = array();
     foreach ($css as $key=>$value) {
@@ -111,11 +139,11 @@ if ($type === 'editor') {
                 $cssfiles[] = $val;
             }
         }
-        $cssfile = "$CFG->cachedir/theme/$themename/css/$key.css";
+        $cssfile = "$basedir/$key.css";
         css_store_css($theme, $cssfile, $cssfiles);
         $allfiles = array_merge($allfiles, $cssfiles);
     }
-    $cssfile = "$CFG->cachedir/theme/$themename/css/all.css";
+    $cssfile = "$basedir/all.css";
     css_store_css($theme, $cssfile, $allfiles);
 }
 
index ea47305..140fefd 100644 (file)
@@ -32,6 +32,7 @@ $themename = min_optional_param('theme', 'standard', 'SAFEDIR');
 $type      = min_optional_param('type', '', 'SAFEDIR');
 $subtype   = min_optional_param('subtype', '', 'SAFEDIR');
 $sheet     = min_optional_param('sheet', '', 'SAFEDIR');
+$usesvg    = (bool)min_optional_param('svg', '1', 'INT');
 
 if (!defined('THEME_DESIGNER_CACHE_LIFETIME')) {
     define('THEME_DESIGNER_CACHE_LIFETIME', 4); // this can be also set in config.php
@@ -47,9 +48,15 @@ if (file_exists("$CFG->dirroot/theme/$themename/config.php")) {
 
 // no gzip compression when debugging
 
-$candidatesheet = "$CFG->cachedir/theme/$themename/designer.ser";
+if ($usesvg) {
+    $candidatesheet = "$CFG->cachedir/theme/$themename/designer.ser";
+} else {
+    // Add to the sheet name, one day we'll be able to just drop this.
+    $candidatesheet = "$CFG->cachedir/theme/$themename/designer_nosvg.ser";
+}
 
 if (!file_exists($candidatesheet)) {
+
     css_send_css_not_found();
 }
 
index 8e2e316..a869d16 100644 (file)
@@ -46,6 +46,7 @@ optional changes:
 * new icons i/valid, i/caution and i/invalid for generic statuses.
 * new icons i/grade_correct, i/grade_partiallycorrect and i/grade_incorrect for grades.
 * new icon t/approve (12x12).
+* new icon t/contextmenu (12x12) for a monochrome version of i/menu.
 
 === 2.3 ===
 
index 73fe0ee..68a1bca 100644 (file)
         $heading .= ": $a->number";
 
         if (user_can_assign($context, $roleid)) {
-            $heading .= ' <a href="'.$CFG->wwwroot.'/'.$CFG->admin.'/roles/assign.php?roleid='.$roleid.'&amp;contextid='.$context->id.'">';
-            $heading .= '<img src="'.$OUTPUT->pix_url('i/edit') . '" class="icon" alt="" /></a>';
+            $headingurl = new moodle_url($CFG->wwwroot . '/' . $CFG->admin . '/roles/assign.php',
+                    array('roleid' => $roleid, 'contextid' => $context->id));
+            $heading .= $OUTPUT->action_icon($headingurl, new pix_icon('t/edit', get_string('edit')));
         }
         echo $OUTPUT->heading($heading, 3);
     } else {
         if ($course->id != SITEID && has_capability('moodle/course:enrolreview', $context)) {
             $editlink = $OUTPUT->action_icon(new moodle_url('/enrol/users.php', array('id' => $course->id)),
-                                             new pix_icon('i/edit', get_string('edit')));
+                                             new pix_icon('t/edit', get_string('edit')));
         } else {
             $editlink = '';
         }
index 861a8c7..2a4b214 100644 (file)
 defined('MOODLE_INTERNAL') || die();
 
 
-$version  = 2012113000.00;              // YYYYMMDD      = weekly release date of this DEV branch
+$version  = 2012120300.02;              // YYYYMMDD      = weekly release date of this DEV branch
                                         //         RR    = release increments - 00 in DEV branches
                                         //           .XX = incremental changes
 
-$release  = '2.4rc1 (Build: 20121130)'; // Human-friendly version name
+$release  = '2.5dev (Build: 20121208)'; // Human-friendly version name
 
-$branch   = '24';                       // this version's branch
-$maturity = MATURITY_RC;                // this version's maturity level
+$branch   = '25';                       // this version's branch
+$maturity = MATURITY_ALPHA;             // this version's maturity level