Merge branch 'MDL-52843-master-paramsignup' of git://github.com/mudrd8mz/moodle
authorEloy Lafuente (stronk7) <stronk7@moodle.org>
Mon, 25 Jan 2016 23:38:08 +0000 (00:38 +0100)
committerDavid Monllao <davidm@moodle.com>
Fri, 29 Jan 2016 02:15:19 +0000 (10:15 +0800)
422 files changed:
Gruntfile.js
admin/index.php
admin/renderer.php
admin/settings/courses.php
admin/tool/langimport/index.php
admin/tool/log/classes/log/manager.php
admin/tool/uploadcourse/classes/course.php
admin/tool/uploadcourse/tests/course_test.php
admin/tool/uploaduser/index.php
admin/webservice/testclient.php
backup/moodle2/restore_stepslib.php
backup/util/dbops/restore_dbops.class.php
backup/util/helper/restore_structure_parser_processor.class.php
badges/tests/badgeslib_test.php
blocks/activity_results/tests/behat/highscoreswithscales.feature [new file with mode: 0644]
blocks/activity_results/tests/behat/highscoreswithscalesandgroups.feature [new file with mode: 0644]
blocks/activity_results/tests/behat/highscoreswithseperategroups.feature
blocks/activity_results/tests/behat/highscoreswithvisiblegroups.feature
blocks/activity_results/tests/behat/lowscoreswithscales.feature [new file with mode: 0644]
blocks/activity_results/tests/behat/lowscoreswithscalesandgroups.feature [new file with mode: 0644]
blocks/activity_results/tests/behat/lowscoreswithseperategroups.feature
blocks/activity_results/tests/behat/lowscoreswithvisiblegroups.feature
blocks/admin_bookmarks/tests/behat/bookmark_admin_pages.feature [new file with mode: 0644]
blocks/blog_menu/tests/behat/block_blog_menu.feature [new file with mode: 0644]
blocks/blog_menu/tests/behat/block_blog_menu_course.feature [new file with mode: 0644]
blocks/blog_menu/tests/behat/block_blog_menu_frontpage.feature [new file with mode: 0644]
blocks/blog_tags/block_blog_tags.php
blocks/moodleblock.class.php
blocks/navigation/amd/build/ajax_response_renderer.min.js [new file with mode: 0644]
blocks/navigation/amd/build/nav_loader.min.js [new file with mode: 0644]
blocks/navigation/amd/build/navblock.min.js [new file with mode: 0644]
blocks/navigation/amd/build/site_admin_loader.min.js [new file with mode: 0644]
blocks/navigation/amd/src/ajax_response_renderer.js [new file with mode: 0644]
blocks/navigation/amd/src/nav_loader.js [new file with mode: 0644]
blocks/navigation/amd/src/navblock.js [moved from webservice/amf/lang/en/webservice_amf.php with 70% similarity]
blocks/navigation/amd/src/site_admin_loader.js [new file with mode: 0644]
blocks/navigation/block_navigation.php
blocks/navigation/renderer.php
blocks/navigation/styles.css
blocks/navigation/yui/build/moodle-block_navigation-navigation/moodle-block_navigation-navigation-debug.js [deleted file]
blocks/navigation/yui/build/moodle-block_navigation-navigation/moodle-block_navigation-navigation-min.js [deleted file]
blocks/navigation/yui/build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js [deleted file]
blocks/navigation/yui/src/navigation/build.json [deleted file]
blocks/navigation/yui/src/navigation/js/navigation.js [deleted file]
blocks/navigation/yui/src/navigation/meta/navigation.json [deleted file]
blocks/news_items/block_news_items.php
blocks/rss_client/block_rss_client.php
blocks/rss_client/classes/output/block.php [new file with mode: 0644]
blocks/rss_client/classes/output/channel_image.php [new file with mode: 0644]
blocks/rss_client/classes/output/feed.php [new file with mode: 0644]
blocks/rss_client/classes/output/footer.php [new file with mode: 0644]
blocks/rss_client/classes/output/item.php [new file with mode: 0644]
blocks/rss_client/classes/output/renderer.php [new file with mode: 0644]
blocks/rss_client/templates/block.mustache [new file with mode: 0644]
blocks/rss_client/templates/channel_image.mustache [new file with mode: 0644]
blocks/rss_client/templates/feed.mustache [new file with mode: 0644]
blocks/rss_client/templates/footer.mustache [new file with mode: 0644]
blocks/rss_client/templates/item.mustache [new file with mode: 0644]
blocks/settings/amd/build/settingsblock.min.js [new file with mode: 0644]
blocks/settings/amd/src/settingsblock.js [moved from webservice/amf/version.php with 66% similarity]
blocks/settings/block_settings.php
blocks/settings/renderer.php
blocks/settings/styles.css
blocks/tag_flickr/block_tag_flickr.php
blocks/tag_flickr/edit_form.php
blocks/tag_youtube/block_tag_youtube.php
blocks/tags/backup/moodle2/restore_tags_block_task.class.php [new file with mode: 0644]
blocks/tags/block_tags.php
blocks/tags/edit_form.php
blocks/tags/lang/en/block_tags.php
blocks/tags/tests/behat/tagcloud.feature
blocks/tests/behat/configure_block_throughout_site.feature
blocks/upgrade.txt
blog/edit.php
blog/edit_form.php
blog/external_blog_edit.php
blog/external_blog_edit_form.php
blog/index.php
blog/lib.php
blog/locallib.php
blog/renderer.php
blog/rsslib.php
blog/tests/lib_test.php [moved from blog/tests/bloglib_test.php with 78% similarity]
calendar/lib.php
calendar/preferences_form.php
calendar/tests/behat/calendar_lookahead.feature [new file with mode: 0644]
cohort/externallib.php
cohort/upgrade.txt
completion/criteria/completion_criteria_grade.php
completion/tests/behat/behat_completion.php
composer.json
composer.lock
course/classes/management_renderer.php
course/edit.php
course/edit_form.php
course/format/renderer.php
course/lib.php
course/renderer.php
course/tags.php
course/tags_form.php
course/tests/courselib_test.php
course/tests/externallib_test.php
enrol/externallib.php
enrol/ldap/tests/ldap_test.php
enrol/manual/yui/quickenrolment/quickenrolment.js
enrol/paypal/ipn.php
enrol/self/externallib.php
enrol/self/tests/externallib_test.php
enrol/tests/behat/manage_enrolments_from_participants.feature [new file with mode: 0644]
enrol/tests/externallib_test.php
grade/grading/form/guide/amd/build/comment_chooser.min.js [new file with mode: 0644]
grade/grading/form/guide/amd/src/comment_chooser.js [new file with mode: 0644]
grade/grading/form/guide/edit_form.php
grade/grading/form/guide/guideeditor.php
grade/grading/form/guide/js/guideeditor.js
grade/grading/form/guide/lang/en/gradingform_guide.php
grade/grading/form/guide/lib.php
grade/grading/form/guide/renderer.php
grade/grading/form/guide/templates/comment_chooser.mustache [new file with mode: 0644]
grade/grading/form/guide/tests/behat/behat_gradingform_guide.php [new file with mode: 0644]
grade/grading/form/guide/tests/behat/edit_guide.feature [new file with mode: 0644]
grade/grading/form/rubric/edit_form.php
grade/grading/form/rubric/js/rubric.js
grade/grading/form/rubric/js/rubriceditor.js
grade/grading/form/rubric/lang/en/gradingform_rubric.php
grade/grading/form/rubric/lib.php
grade/grading/form/rubric/renderer.php
grade/grading/form/rubric/rubriceditor.php
grade/grading/form/rubric/tests/behat/behat_gradingform_rubric.php
grade/grading/form/rubric/tests/behat/edit_rubric.feature
grade/grading/form/rubric/tests/behat/reuse_own_rubrics.feature
grade/report/grader/lib.php
grade/report/grader/tests/behat/switch_views.feature [new file with mode: 0644]
grade/report/history/index.php
grade/report/history/tests/behat/basic_functionality.feature
grade/report/user/tests/lib_test.php [new file with mode: 0644]
grade/tests/behat/grade_hidden_items.feature [new file with mode: 0644]
install/lang/cs/install.php
install/lang/hi/admin.php
install/lang/hr/admin.php
install/lang/hr/error.php
install/lang/hr/install.php
install/lang/lt/moodle.php
install/lang/pt/admin.php
install/lang/pt/moodle.php
lang/en/admin.php
lang/en/backup.php
lang/en/cache.php
lang/en/deprecated.txt
lang/en/moodle.php
lang/en/question.php
lang/en/tag.php
lang/en/webservice.php
lib/adminlib.php
lib/amd/build/str.min.js
lib/amd/build/tag.min.js
lib/amd/build/tree.min.js [new file with mode: 0644]
lib/amd/src/str.js
lib/amd/src/tag.js
lib/amd/src/tree.js [new file with mode: 0644]
lib/behat/lib.php
lib/bennu/readme_moodle.txt
lib/blocklib.php
lib/classes/event/tag_added.php
lib/classes/event/tag_collection_created.php [new file with mode: 0644]
lib/classes/event/tag_collection_deleted.php [new file with mode: 0644]
lib/classes/event/tag_collection_updated.php [new file with mode: 0644]
lib/classes/event/tag_created.php
lib/classes/event/tag_removed.php
lib/classes/log/sql_internal_reader.php [deleted file]
lib/classes/log/sql_select_reader.php [deleted file]
lib/classes/plugin_manager.php
lib/classes/plugininfo/cachestore.php
lib/classes/string_manager_standard.php
lib/classes/task/tag_cron_task.php
lib/coursecatlib.php
lib/db/caches.php
lib/db/install.xml
lib/db/services.php
lib/db/tag.php [new file with mode: 0644]
lib/db/tasks.php
lib/db/upgrade.php
lib/ddl/mysql_sql_generator.php
lib/deprecatedlib.php
lib/dml/moodle_database.php
lib/editor/atto/yui/build/moodle-editor_atto-editor/moodle-editor_atto-editor-debug.js
lib/editor/atto/yui/build/moodle-editor_atto-editor/moodle-editor_atto-editor-min.js
lib/editor/atto/yui/build/moodle-editor_atto-editor/moodle-editor_atto-editor.js
lib/editor/atto/yui/src/editor/js/selection.js
lib/eventslib.php
lib/form/tags.php
lib/formslib.php
lib/grade/grade_category.php
lib/grade/grade_grade.php
lib/grade/tests/grade_category_test.php
lib/modinfolib.php
lib/moodlelib.php
lib/myprofilelib.php
lib/navigationlib.php
lib/outputrenderers.php
lib/pagelib.php
lib/pear/HTML/QuickForm.php
lib/pear/HTML/QuickForm/Renderer/Tableless.php
lib/pear/README_MOODLE.txt
lib/phpunit/classes/advanced_testcase.php
lib/phpunit/tests/advanced_test.php
lib/plagiarismlib.php
lib/questionlib.php
lib/rsslib.php
lib/testing/classes/tests_finder.php
lib/testing/classes/util.php
lib/testing/generator/data_generator.php
lib/testing/tests/generator_test.php
lib/tests/behat/behat_navigation.php
lib/tests/event_test.php
lib/tests/eventslib_test.php
lib/tests/myprofilelib_test.php [new file with mode: 0644]
lib/tests/questionlib_test.php
lib/upgrade.txt
lib/upgradelib.php
lib/weblib.php
lib/wiki_to_markdown.php
local/upgrade.txt
login/token.php
message/externallib.php
message/lib.php
message/tests/externallib_test.php
message/upgrade.txt
mod/assign/feedback/editpdf/tests/behat/annotate_pdf.feature
mod/assign/feedback/editpdf/yui/build/moodle-assignfeedback_editpdf-editor/moodle-assignfeedback_editpdf-editor-debug.js
mod/assign/feedback/editpdf/yui/build/moodle-assignfeedback_editpdf-editor/moodle-assignfeedback_editpdf-editor-min.js
mod/assign/feedback/editpdf/yui/build/moodle-assignfeedback_editpdf-editor/moodle-assignfeedback_editpdf-editor.js
mod/assign/feedback/editpdf/yui/src/editor/js/editor.js
mod/assign/gradingtable.php
mod/assign/lang/en/assign.php
mod/assign/locallib.php
mod/assign/tests/behat/reopen_locked_submission.feature [new file with mode: 0644]
mod/assign/tests/locallib_test.php
mod/chat/lib.php
mod/chat/locallib.php
mod/chat/tests/behat/chat_course_reset.feature [new file with mode: 0644]
mod/data/js.php
mod/forum/backup/moodle2/backup_forum_stepslib.php
mod/forum/classes/event/discussion_pinned.php [new file with mode: 0644]
mod/forum/classes/event/discussion_unpinned.php [new file with mode: 0644]
mod/forum/classes/output/forum_post.php
mod/forum/classes/post_form.php
mod/forum/db/access.php
mod/forum/db/install.xml
mod/forum/db/log.php
mod/forum/db/upgrade.php
mod/forum/discuss.php
mod/forum/externallib.php
mod/forum/lang/en/deprecated.txt
mod/forum/lang/en/forum.php
mod/forum/lib.php
mod/forum/markposts.php
mod/forum/pix/i/pinned.png [new file with mode: 0644]
mod/forum/pix/i/pinned.svg [new file with mode: 0644]
mod/forum/post.php
mod/forum/styles.css
mod/forum/templates/forum_post_emaildigestbasic_htmlemail.mustache
mod/forum/tests/behat/discussion_navigation.feature
mod/forum/tests/behat/move_discussion.feature
mod/forum/tests/behat/posts_ordering_blog.feature
mod/forum/tests/behat/posts_ordering_general.feature
mod/forum/tests/externallib_test.php
mod/forum/tests/generator/lib.php
mod/forum/tests/generator_test.php
mod/forum/tests/lib_test.php
mod/forum/version.php
mod/forum/view.php
mod/glossary/classes/entry_query_builder.php [new file with mode: 0644]
mod/glossary/classes/external.php
mod/glossary/db/services.php
mod/glossary/lib.php
mod/glossary/print.php
mod/glossary/showentry.php
mod/glossary/showentry_ajax.php
mod/glossary/sql.php
mod/glossary/tests/external_test.php
mod/glossary/tests/lib_test.php [new file with mode: 0644]
mod/glossary/version.php
mod/glossary/view.php
mod/lesson/lang/en/lesson.php
mod/lesson/lib.php
mod/lesson/reformat.php [deleted file]
mod/lesson/tests/behat/lesson_complete_report.feature [new file with mode: 0644]
mod/lesson/tests/behat/lesson_outline_report.feature [new file with mode: 0644]
mod/lesson/upgrade.txt
mod/quiz/accessmanager.php
mod/quiz/accessmanager_form.php
mod/quiz/accessrule/timelimit/lang/en/quizaccess_timelimit.php
mod/quiz/accessrule/timelimit/rule.php
mod/quiz/amd/build/preflightcheck.min.js [new file with mode: 0644]
mod/quiz/amd/src/preflightcheck.js [new file with mode: 0644]
mod/quiz/attemptlib.php
mod/quiz/classes/structure.php
mod/quiz/comment.php
mod/quiz/index.php
mod/quiz/lang/en/quiz.php
mod/quiz/locallib.php
mod/quiz/module.js
mod/quiz/processattempt.php
mod/quiz/renderer.php
mod/quiz/review.php
mod/quiz/reviewquestion.php
mod/quiz/startattempt.php
mod/quiz/styles.css
mod/quiz/tests/behat/add_quiz.feature
mod/quiz/tests/behat/attempt_basic.feature
mod/quiz/tests/behat/attempt_begin.feature [new file with mode: 0644]
mod/quiz/tests/behat/attempt_redo_questions.feature
mod/quiz/tests/behat/attempt_require_previous.feature
mod/quiz/tests/behat/completion_condition_attempts_used.feature
mod/quiz/tests/behat/completion_condition_passing_grade.feature
mod/quiz/tests/behat/quiz_reset.feature
mod/quiz/upgrade.txt
mod/quiz/view.php
mod/scorm/lib.php
mod/scorm/locallib.php
mod/scorm/report/userreport.php
mod/scorm/report/userreportinteractions.php
mod/scorm/report/userreporttracks.php
mod/scorm/tests/lib_test.php
mod/scorm/upgrade.txt
mod/wiki/backup/moodle2/backup_wiki_stepslib.php
mod/wiki/backup/moodle2/restore_wiki_stepslib.php
mod/wiki/db/tag.php [moved from webservice/amf/db/access.php with 59% similarity]
mod/wiki/edit_form.php
mod/wiki/lang/en/wiki.php
mod/wiki/lib.php
mod/wiki/locallib.php
mod/wiki/pagelib.php
mod/wiki/styles.css
mod/wiki/tests/behat/edit_tags.feature
mod/wiki/version.php
mod/workshop/form/rubric/styles.css
mod/workshop/styles.css
notes/lib.php
notes/tests/lib_test.php [new file with mode: 0644]
plagiarism/lib.php
plagiarism/upgrade.txt [new file with mode: 0644]
question/format.php
question/format/xml/format.php
question/format/xml/tests/xmlformat_test.php
question/question.php
question/type/edit_question_form.php
report/log/classes/table_log.php
report/log/tests/lib_test.php
report/outline/tests/lib_test.php
report/stats/tests/lib_test.php
report/usersessions/tests/lib_test.php [new file with mode: 0644]
repository/s3/lib.php
tag/classes/area.php [new file with mode: 0644]
tag/classes/areas_table.php [new file with mode: 0644]
tag/classes/collection.php [new file with mode: 0644]
tag/classes/collection_form.php [new file with mode: 0644]
tag/classes/collections_table.php [new file with mode: 0644]
tag/classes/external.php
tag/classes/manage_table.php
tag/classes/output/tag.php
tag/classes/output/tagcloud.php [new file with mode: 0644]
tag/classes/output/tagfeed.php [new file with mode: 0644]
tag/classes/output/tagindex.php [new file with mode: 0644]
tag/classes/output/taglist.php [new file with mode: 0644]
tag/classes/renderer.php [new file with mode: 0644]
tag/classes/tag.php [new file with mode: 0644]
tag/edit.php
tag/edit_form.php
tag/index.php
tag/lib.php
tag/locallib.php
tag/manage.php
tag/search.php
tag/templates/index.mustache [new file with mode: 0644]
tag/templates/tagcloud.mustache [new file with mode: 0644]
tag/templates/tagfeed.mustache [new file with mode: 0644]
tag/templates/taglist.mustache [new file with mode: 0644]
tag/tests/behat/collections.feature [new file with mode: 0644]
tag/tests/behat/delete_tag.feature
tag/tests/behat/edit_tag.feature
tag/tests/behat/flag_tags.feature
tag/tests/behat/official_tags.feature
tag/tests/behat/tagindex.feature [new file with mode: 0644]
tag/tests/events_test.php
tag/tests/external_test.php
tag/tests/taglib_test.php
tag/upgrade.txt
tag/user.php
theme/base/style/core.css
theme/bootstrapbase/less/moodle/calendar.less
theme/bootstrapbase/less/moodle/core.less
theme/bootstrapbase/less/moodle/debug.less
theme/bootstrapbase/style/moodle.css
theme/canvas/style/core.css
theme/clean/lang/en/theme_clean.php
theme/more/lang/en/theme_more.php
user/edit.php
user/editadvanced.php
user/editlib.php
user/externallib.php
user/index.php
user/lib.php
user/profile.php
user/renderer.php
user/tests/externallib_test.php
user/view.php
version.php
webservice/amf/introspector.php [deleted file]
webservice/amf/locallib.php [deleted file]
webservice/amf/server.php [deleted file]
webservice/amf/simpleserver.php [deleted file]
webservice/amf/testclient/AMFTester.mxml [deleted file]
webservice/amf/testclient/AMFTester.swf [deleted file]
webservice/amf/testclient/customValidators/JSONValidator.as [deleted file]
webservice/amf/testclient/flashcompilationinstructions.txt [deleted file]
webservice/amf/testclient/index.php [deleted file]
webservice/externallib.php
webservice/lib.php
webservice/tests/externallib_test.php
webservice/upgrade.txt

index 665bb44..3dd3ef0 100644 (file)
@@ -26,13 +26,14 @@ module.exports = function(grunt) {
     var path = require('path'),
         fs = require('fs'),
         tasks = {},
-        cwd = process.env.PWD || process.cwd();
+        cwd = process.env.PWD || process.cwd(),
+        inAMD = path.basename(cwd) == 'amd';
 
     // Project configuration.
     grunt.initConfig({
         jshint: {
             options: {jshintrc: '.jshintrc'},
-            files: ['**/amd/src/*.js']
+            files: [inAMD ? cwd + '/src/*.js' : '**/amd/src/*.js']
         },
         uglify: {
             dynamic_mappings: {
@@ -222,7 +223,7 @@ module.exports = function(grunt) {
         if (path.basename(path.resolve(cwd, '../../')) == 'yui') {
             grunt.task.run('shifter');
         // Are we in an AMD directory?
-        } else if (path.basename(cwd) == 'amd') {
+        } else if (inAMD) {
             grunt.task.run('amd');
         } else {
             // Run them all!.
index b8de2e6..1000f93 100644 (file)
@@ -843,6 +843,8 @@ $buggyiconvnomb = (!function_exists('mb_convert_encoding') and @iconv('UTF-8', '
 $registered = $DB->count_records('registration_hubs', array('huburl' => HUB_MOODLEORGHUBURL, 'confirmed' => 1));
 // Check if there are any cache warnings.
 $cachewarnings = cache_helper::warnings();
+// Check if there are events 1 API handlers.
+$eventshandlers = $DB->get_records_sql('SELECT DISTINCT component FROM {events_handlers}');
 
 admin_externalpage_setup('adminnotifications');
 
@@ -850,4 +852,4 @@ $output = $PAGE->get_renderer('core', 'admin');
 
 echo $output->admin_notifications_page($maturity, $insecuredataroot, $errorsdisplayed, $cronoverdue, $dbproblems,
                                        $maintenancemode, $availableupdates, $availableupdatesfetch, $buggyiconvnomb,
-                                       $registered, $cachewarnings);
+                                       $registered, $cachewarnings, $eventshandlers);
index 12d9dc3..7c0dfe2 100644 (file)
@@ -275,12 +275,13 @@ class core_admin_renderer extends plugin_renderer_base {
      * @param array|null $availableupdates array of \core\update\info objects or null
      * @param int|null $availableupdatesfetch timestamp of the most recent updates fetch or null (unknown)
      * @param string[] $cachewarnings An array containing warnings from the Cache API.
+     * @param array $eventshandlers Events 1 API handlers.
      *
      * @return string HTML to output.
      */
     public function admin_notifications_page($maturity, $insecuredataroot, $errorsdisplayed,
             $cronoverdue, $dbproblems, $maintenancemode, $availableupdates, $availableupdatesfetch,
-            $buggyiconvnomb, $registered, array $cachewarnings = array()) {
+            $buggyiconvnomb, $registered, array $cachewarnings = array(), $eventshandlers = 0) {
         global $CFG;
         $output = '';
 
@@ -294,6 +295,7 @@ class core_admin_renderer extends plugin_renderer_base {
         $output .= $this->db_problems($dbproblems);
         $output .= $this->maintenance_mode_warning($maintenancemode);
         $output .= $this->cache_warnings($cachewarnings);
+        $output .= $this->events_handlers($eventshandlers);
         $output .= $this->registration_warning($registered);
 
         //////////////////////////////////////////////////////////////////////////////////////////////////
@@ -594,6 +596,23 @@ class core_admin_renderer extends plugin_renderer_base {
         return join("\n", array_map(array($this, 'warning'), $cachewarnings));
     }
 
+    /**
+     * Renders events 1 API handlers warning.
+     *
+     * @param array $eventshandlers
+     * @return string
+     */
+    public function events_handlers($eventshandlers) {
+        if ($eventshandlers) {
+            $components = '';
+            foreach ($eventshandlers as $eventhandler) {
+                $components .= $eventhandler->component . ', ';
+            }
+            $components = rtrim($components, ', ');
+            return $this->warning(get_string('eventshandlersinuse', 'admin', $components));
+        }
+    }
+
     /**
      * Render an appropriate message if the site in in maintenance mode.
      * @param bool $maintenancemode
index bd88630..21ecab7 100644 (file)
@@ -205,6 +205,9 @@ if ($hassiteconfig or has_any_capability($capabilities, $systemcontext)) {
     // Create a page for general import configuration and defaults.
     $temp = new admin_settingpage('importgeneralsettings', new lang_string('importgeneralsettings', 'backup'), 'moodle/backup:backupcourse');
     $temp->add(new admin_setting_configtext('backup/import_general_maxresults', new lang_string('importgeneralmaxresults', 'backup'), new lang_string('importgeneralmaxresults_desc', 'backup'), 10));
+    $temp->add(new admin_setting_configcheckbox('backup/import_general_duplicate_admin_allowed',
+            new lang_string('importgeneralduplicateadminallowed', 'backup'),
+            new lang_string('importgeneralduplicateadminallowed_desc', 'backup'), 0));
     $ADMIN->add('backups', $temp);
 
     // Create a page for automated backups configuration and defaults.
index c1ee2fb..6017717 100644 (file)
@@ -188,7 +188,7 @@ echo html_writer::end_tag('td');
 $options = array();
 foreach ($availablelangs as $alang) {
     if (!empty($alang[0]) and trim($alang[0]) !== 'en' and !$controller->is_installed_lang($alang[0], $alang[1])) {
-        $options[$alang[0]] = $alang[2].' ('.$alang[0].')';
+        $options[$alang[0]] = $alang[2].' &lrm;('.$alang[0].')&lrm;';
     }
 }
 if (!empty($options)) {
index 4077347..2b1d491 100644 (file)
@@ -106,38 +106,6 @@ class manager implements \core\log\manager {
             if (empty($interface) || ($reader instanceof $interface)) {
                 $return[$plugin] = $reader;
             }
-            // TODO MDL-49291 These conditions should be removed as part of the 2nd stage deprecation.
-            if ($reader instanceof \core\log\sql_internal_reader) {
-                debugging('\core\log\sql_internal_reader has been deprecated in favour of \core\log\sql_internal_table_reader.' .
-                    ' Update ' . get_class($reader) . ' to use the new interface.', DEBUG_DEVELOPER);
-            } else if ($reader instanceof \core\log\sql_select_reader) {
-                debugging('\core\log\sql_select_reader has been deprecated in favour of \core\log\sql_reader. Update ' .
-                    get_class($reader) . ' to use the new interface.', DEBUG_DEVELOPER);
-            }
-        }
-
-        // TODO MDL-49291 This section below (until the final return) should be removed as part of the 2nd stage deprecation.
-        $isselectreader = (ltrim($interface, '\\') === 'core\log\sql_select_reader');
-        $isinternalreader = (ltrim($interface, '\\') === 'core\log\sql_internal_reader');
-        if ($isselectreader || $isinternalreader) {
-
-            if ($isselectreader) {
-                $alternative = '\core\log\sql_reader';
-            } else {
-                $alternative = '\core\log\sql_internal_table_reader';
-            }
-
-            if (count($return) === 0) {
-                // If there are no classes implementing the provided interface and the provided interface is one of
-                // the deprecated ones, we return the non-deprecated alternatives. It should be safe as the new interface
-                // is adding a new method but not changing the existing ones.
-                debugging($interface . ' has been deprecated in favour of ' . $alternative . '. Returning ' . $alternative .
-                    ' instances instead. Please call get_readers() using the new interface.', DEBUG_DEVELOPER);
-                $return = $this->get_readers($alternative);
-            } else {
-                debugging($interface . ' has been deprecated in favour of ' . $alternative .
-                    '. Please call get_readers() using the new interface.', DEBUG_DEVELOPER);
-            }
         }
 
         return $return;
index ff22833..4486cde 100644 (file)
@@ -659,6 +659,10 @@ class tool_uploadcourse_course {
         $this->data = $coursedata;
         $this->enrolmentdata = tool_uploadcourse_helper::get_enrolment_data($this->rawdata);
 
+        if (isset($this->rawdata['tags']) && strval($this->rawdata['tags']) !== '') {
+            $this->data['tags'] = preg_split('/\s*,\s*/', trim($this->rawdata['tags']), -1, PREG_SPLIT_NO_EMPTY);
+        }
+
         // Restore data.
         // TODO Speed up things by not really extracting the backup just yet, but checking that
         // the backup file or shortname passed are valid. Extraction should happen in proceed().
index a173e72..20bbaa3 100644 (file)
@@ -261,6 +261,7 @@ class tool_uploadcourse_course_testcase extends advanced_testcase {
             'groupmode' => '2',
             'groupmodeforce' => '1',
             'enablecompletion' => '1',
+            'tags' => 'Cat, Dog',
 
             'role_teacher' => 'Knight',
             'role_manager' => 'Jedi',
@@ -297,6 +298,7 @@ class tool_uploadcourse_course_testcase extends advanced_testcase {
         $this->assertEquals($data['groupmode'], $course->groupmode);
         $this->assertEquals($data['groupmodeforce'], $course->groupmodeforce);
         $this->assertEquals($data['enablecompletion'], $course->enablecompletion);
+        $this->assertEquals($data['tags'], join(', ', core_tag_tag::get_item_tags_array('core', 'course', $course->id)));
 
         // Roles.
         $roleids = array();
index e687fe3..2b3f43e 100644 (file)
@@ -96,6 +96,7 @@ $STD_FIELDS = array('id', 'username', 'email',
         'suspended',   // 1 means suspend user account, 0 means activate user account, nothing means keep as is for existing users
         'deleted',     // 1 means delete user
         'mnethostid',  // Can not be used for adding, updating or deleting of users - only for enrolments, groups, cohorts and suspending.
+        'interests',
     );
 // Include all name fields.
 $STD_FIELDS = array_merge($STD_FIELDS, get_all_user_name_fields());
@@ -836,6 +837,10 @@ if ($formdata = $mform2->is_cancelled()) {
             }
         }
 
+        // Update user interests.
+        if (isset($user->interests) && strval($user->interests) !== '') {
+            useredit_update_interests($user, preg_split('/\s*,\s*/', $user->interests, -1, PREG_SPLIT_NO_EMPTY));
+        }
 
         // add to cohort first, it might trigger enrolments indirectly - do NOT create cohorts here!
         foreach ($filecolumns as $column) {
index 25e4070..d14dbb9 100644 (file)
@@ -95,10 +95,6 @@ if (!$function or !$protocol) {
     $descparams = new stdClass();
     $descparams->atag = $atag;
     $descparams->mode = get_string('debugnormal', 'admin');
-    $amfclienturl = new moodle_url('/webservice/amf/testclient/index.php');
-    $amfclientatag =html_writer::tag('a', get_string('amftestclient', 'webservice'),
-            array('href' => $amfclienturl));
-    $descparams->amfatag = $amfclientatag;
     echo get_string('testclientdescription', 'webservice', $descparams);
     echo $OUTPUT->box_end();
 
index a41292d..caf5f07 100644 (file)
@@ -1778,22 +1778,8 @@ class restore_course_structure_step extends restore_structure_step {
 
         $data = (object)$data;
 
-        if (!empty($CFG->usetags)) { // if enabled in server
-            // TODO: This is highly inneficient. Each time we add one tag
-            // we fetch all the existing because tag_set() deletes them
-            // so everything must be reinserted on each call
-            $tags = array();
-            $existingtags = tag_get_tags('course', $this->get_courseid());
-            // Re-add all the existitng tags
-            foreach ($existingtags as $existingtag) {
-                $tags[] = $existingtag->rawname;
-            }
-            // Add the one being restored
-            $tags[] = $data->rawname;
-            // Send all the tags back to the course
-            tag_set('course', $this->get_courseid(), $tags, 'core',
-                context_course::instance($this->get_courseid())->id);
-        }
+        core_tag_tag::add_item_tag('core', 'course', $this->get_courseid(),
+                context_course::instance($this->get_courseid()), $data->rawname);
     }
 
     public function process_allowed_module($data) {
@@ -4078,25 +4064,17 @@ class restore_create_categories_and_questions extends restore_structure_step {
             return;
         }
 
-        if (!empty($CFG->usetags)) { // if enabled in server
-            // TODO: This is highly inefficient. Each time we add one tag
-            // we fetch all the existing because tag_set() deletes them
-            // so everything must be reinserted on each call
-            $tags = array();
-            $existingtags = tag_get_tags('question', $newquestion);
-            // Re-add all the existitng tags
-            foreach ($existingtags as $existingtag) {
-                $tags[] = $existingtag->rawname;
-            }
-            // Add the one being restored
-            $tags[] = $data->rawname;
+        if (core_tag_tag::is_enabled('core_question', 'question')) {
+            $tagname = $data->rawname;
             // Get the category, so we can then later get the context.
             $categoryid = $this->get_new_parentid('question_category');
             if (empty($this->cachedcategory) || $this->cachedcategory->id != $categoryid) {
                 $this->cachedcategory = $DB->get_record('question_categories', array('id' => $categoryid));
             }
-            // Send all the tags back to the question
-            tag_set('question', $newquestion, $tags, 'core_question', $this->cachedcategory->contextid);
+            // Add the tag to the question.
+            core_tag_tag::add_item_tag('core_question', 'question', $newquestion,
+                    context::instance_by_id($this->cachedcategory->contextid),
+                    $tagname);
         }
     }
 
index 880e75d..120ea6c 100644 (file)
@@ -1209,16 +1209,14 @@ abstract class restore_dbops {
                 }
 
                 // Process tags
-                if (!empty($CFG->usetags) && isset($user->tags)) { // if enabled in server and present in backup
+                if (core_tag_tag::is_enabled('core', 'user') && isset($user->tags)) { // If enabled in server and present in backup.
                     $tags = array();
                     foreach($user->tags['tag'] as $usertag) {
                         $usertag = (object)$usertag;
                         $tags[] = $usertag->rawname;
                     }
-                    if (empty($newuserctxid)) {
-                        $newuserctxid = null; // Tag apis expect a null contextid not 0.
-                    }
-                    tag_set('user', $newuserid, $tags, 'core', $newuserctxid);
+                    core_tag_tag::set_item_tags('core', 'user', $newuserid,
+                            context_user::instance($newuserid), $tags);
                 }
 
                 // Process preferences
@@ -1287,7 +1285,11 @@ abstract class restore_dbops {
     *      1F - None of the above, return true => User needs to be created
     *
     *  if restoring from another site backup (cannot match by id here, replace it by email/firstaccess combination):
-    *      2A - Normal check: If match by username and mnethost and (email or non-zero firstaccess) => ok, return target user
+    *      2A - Normal check:
+    *           2A1 - If match by username and mnethost and (email or non-zero firstaccess) => ok, return target user
+    *           2A2 - Exceptional handling (MDL-21912): Match "admin" username. Then, if import_general_duplicate_admin_allowed is
+    *                 enabled, attempt to map the admin user to the user 'admin_[oldsiteid]' if it exists. If not,
+    *                 the user 'admin_[oldsiteid]' will be created in precheck_included users
     *      2B - Handle users deleted in DB and "alive" in backup file:
     *           2B1 - If match by mnethost and user is deleted in DB and not empty email = md5(username) and
     *                 (username LIKE 'backup_email.%' or non-zero firstaccess) => ok, return target user
@@ -1305,7 +1307,7 @@ abstract class restore_dbops {
     * Note: for DB deleted users md5(username) is stored *sometimes* in the email field,
     *       hence we are looking there for usernames if not empty. See delete_user()
     */
-    protected static function precheck_user($user, $samesite) {
+    protected static function precheck_user($user, $samesite, $siteid = null) {
         global $CFG, $DB;
 
         // Handle checks from same site backups
@@ -1376,7 +1378,7 @@ abstract class restore_dbops {
         // Handle checks from different site backups
         } else {
 
-            // 2A - If match by username and mnethost and
+            // 2A1 - If match by username and mnethost and
             //     (email or non-zero firstaccess) => ok, return target user
             if ($rec = $DB->get_record_sql("SELECT *
                                               FROM {user} u
@@ -1393,6 +1395,14 @@ abstract class restore_dbops {
                 return $rec; // Matching user found, return it
             }
 
+            // 2A2 - If we're allowing conflicting admins, attempt to map user to admin_[oldsiteid].
+            if (get_config('backup', 'import_general_duplicate_admin_allowed') && $user->username === 'admin' && $siteid
+                    && $user->mnethostid == $CFG->mnet_localhost_id) {
+                if ($rec = $DB->get_record('user', array('username' => 'admin_' . $siteid))) {
+                    return $rec;
+                }
+            }
+
             // 2B - Handle users deleted in DB and "alive" in backup file
             // Note: for DB deleted users email is stored in username field, hence we
             //       are looking there for emails. See delete_user()
@@ -1500,6 +1510,9 @@ abstract class restore_dbops {
         // Calculate the context we are going to use for capability checking
         $context = context_course::instance($courseid);
 
+        // When conflicting users are detected we may need original site info.
+        $restoreinfo = restore_controller_dbops::load_controller($restoreid)->get_info();
+
         // Calculate if we have perms to create users, by checking:
         // to 'moodle/restore:createuser' and 'moodle/restore:userinfo'
         // and also observe $CFG->disableusercreationonrestore
@@ -1535,14 +1548,28 @@ abstract class restore_dbops {
             }
 
             // Now, precheck that user and, based on returned results, annotate action/problem
-            $usercheck = self::precheck_user($user, $samesite);
+            $usercheck = self::precheck_user($user, $samesite, $restoreinfo->original_site_identifier_hash);
 
             if (is_object($usercheck)) { // No problem, we have found one user in DB to be mapped to
                 // Annotate it, for later process. Set newitemid to mapping user->id
                 self::set_backup_ids_record($restoreid, 'user', $recuser->itemid, $usercheck->id);
 
             } else if ($usercheck === false) { // Found conflict, report it as problem
-                 $problems[] = get_string('restoreuserconflict', '', $user->username);
+                if (!get_config('backup', 'import_general_duplicate_admin_allowed')) {
+                    $problems[] = get_string('restoreuserconflict', '', $user->username);
+                } else if ($user->username == 'admin') {
+                    if (!$cancreateuser) {
+                        $problems[] = get_string('restorecannotcreateuser', '', $user->username);
+                    }
+                    if ($user->mnethostid != $CFG->mnet_localhost_id) {
+                        $problems[] = get_string('restoremnethostidmismatch', '', $user->username);
+                    }
+                    if (!$problems) {
+                        // Duplicate admin allowed, append original site idenfitier to username.
+                        $user->username .= '_' . $restoreinfo->original_site_identifier_hash;
+                        self::set_backup_ids_record($restoreid, 'user', $recuser->itemid, 0, null, (array)$user);
+                    }
+                }
 
             } else if ($usercheck === true) { // User needs to be created, check if we are able
                 if ($cancreateuser) { // Can create user, set newitemid to 0 so will be created later
index 0cfdfe7..500fa0c 100644 (file)
@@ -62,7 +62,7 @@ class restore_structure_parser_processor extends grouped_parser_processor {
         }
         // Decode file.php calls
         $search = array ("$@FILEPHP@$");
-        $replace = array(get_file_url($this->courseid));
+        $replace = array(moodle_url::make_legacyfile_url($this->courseid, null));
         $result = str_replace($search, $replace, $cdata);
         // Now $@SLASH@$ and $@FORCEDOWNLOAD@$ MDL-18799
         $search = array('$@SLASH@$', '$@FORCEDOWNLOAD@$');
index 2de1122..a8d4382 100644 (file)
@@ -28,6 +28,7 @@ defined('MOODLE_INTERNAL') || die();
 
 global $CFG;
 require_once($CFG->libdir . '/badgeslib.php');
+require_once($CFG->dirroot . '/badges/lib.php');
 
 class core_badges_badgeslib_testcase extends advanced_testcase {
     protected $badgeid;
@@ -472,4 +473,69 @@ class core_badges_badgeslib_testcase extends advanced_testcase {
         $this->assertStringMatchesFormat($testassertion->class, json_encode($assertion->get_badge_class()));
         $this->assertStringMatchesFormat($testassertion->issuer, json_encode($assertion->get_issuer()));
     }
+
+    /**
+     * Tests the core_badges_myprofile_navigation() function.
+     */
+    public function test_core_badges_myprofile_navigation() {
+        // Set up the test.
+        $tree = new \core_user\output\myprofile\tree();
+        $this->setAdminUser();
+        $badge = new badge($this->badgeid);
+        $badge->issue($this->user->id, true);
+        $iscurrentuser = true;
+        $course = null;
+
+        // Enable badges.
+        set_config('enablebadges', true);
+
+        // Check the node tree is correct.
+        core_badges_myprofile_navigation($tree, $this->user, $iscurrentuser, $course);
+        $reflector = new ReflectionObject($tree);
+        $nodes = $reflector->getProperty('nodes');
+        $nodes->setAccessible(true);
+        $this->assertArrayHasKey('localbadges', $nodes->getValue($tree));
+    }
+
+    /**
+     * Tests the core_badges_myprofile_navigation() function with badges disabled..
+     */
+    public function test_core_badges_myprofile_navigation_badges_disabled() {
+        // Set up the test.
+        $tree = new \core_user\output\myprofile\tree();
+        $this->setAdminUser();
+        $badge = new badge($this->badgeid);
+        $badge->issue($this->user->id, true);
+        $iscurrentuser = false;
+        $course = null;
+
+        // Disable badges.
+        set_config('enablebadges', false);
+
+        // Check the node tree is correct.
+        core_badges_myprofile_navigation($tree, $this->user, $iscurrentuser, $course);
+        $reflector = new ReflectionObject($tree);
+        $nodes = $reflector->getProperty('nodes');
+        $nodes->setAccessible(true);
+        $this->assertArrayNotHasKey('localbadges', $nodes->getValue($tree));
+    }
+
+    /**
+     * Tests the core_badges_myprofile_navigation() function with a course badge.
+     */
+    public function test_core_badges_myprofile_navigation_with_course_badge() {
+        // Set up the test.
+        $tree = new \core_user\output\myprofile\tree();
+        $this->setAdminUser();
+        $badge = new badge($this->coursebadge);
+        $badge->issue($this->user->id, true);
+        $iscurrentuser = false;
+
+        // Check the node tree is correct.
+        core_badges_myprofile_navigation($tree, $this->user, $iscurrentuser, $this->course);
+        $reflector = new ReflectionObject($tree);
+        $nodes = $reflector->getProperty('nodes');
+        $nodes->setAccessible(true);
+        $this->assertArrayHasKey('localbadges', $nodes->getValue($tree));
+    }
 }
diff --git a/blocks/activity_results/tests/behat/highscoreswithscales.feature b/blocks/activity_results/tests/behat/highscoreswithscales.feature
new file mode 100644 (file)
index 0000000..1263382
--- /dev/null
@@ -0,0 +1,111 @@
+@block @block_activity_results
+Feature: The activity results block displays student scores as scales
+  In order to be display student scores as scales
+  As a user
+  I need to see the activity results block
+
+  Background:
+    Given the following "users" exist:
+      | username | firstname | lastname | email | idnumber |
+      | teacher1 | Teacher | 1 | teacher1@example.com | T1 |
+      | student1 | Student | 1 | student1@example.com | S1 |
+      | student2 | Student | 2 | student2@example.com | S2 |
+      | student3 | Student | 3 | student3@example.com | S3 |
+      | student4 | Student | 4 | student4@example.com | S4 |
+      | student5 | Student | 5 | student5@example.com | S5 |
+    And the following "courses" exist:
+      | fullname | shortname | category |
+      | Course 1 | C1 | 0 |
+    And the following "course enrolments" exist:
+      | user | course | role |
+      | teacher1 | C1 | editingteacher |
+      | student1 | C1 | student |
+      | student2 | C1 | student |
+      | student3 | C1 | student |
+      | student4 | C1 | student |
+      | student5 | C1 | student |
+    And I log in as "teacher1"
+    And I follow "Course 1"
+    And I navigate to "Grades" node in "Course administration"
+    And I navigate to "Scales" node in "Grade administration"
+    And I press "Add a new scale"
+    And I set the following fields to these values:
+      | Name | My Scale |
+      | Scale | Disappointing, Not good enough, Average, Good, Very good, Excellent! |
+    And I press "Save changes"
+    And I follow "Course 1"
+    And I turn editing mode on
+    And I add a "Assignment" to section "1" and I fill the form with:
+      | Assignment name | Test assignment |
+      | Description | Offline text |
+      | assignsubmission_file_enabled | 0 |
+      | id_modgrade_type | Scale |
+      | id_modgrade_scale | My Scale |
+    And I follow "Course 1"
+    And I navigate to "Grades" node in "Course administration"
+    And I turn editing mode on
+    And I give the grade "Excellent!" to the user "Student 1" for the grade item "Test assignment"
+    And I give the grade "Very good" to the user "Student 2" for the grade item "Test assignment"
+    And I give the grade "Good" to the user "Student 3" for the grade item "Test assignment"
+    And I give the grade "Average" to the user "Student 4" for the grade item "Test assignment"
+    And I give the grade "Not good enough" to the user "Student 5" for the grade item "Test assignment"
+    And I press "Save changes"
+    And I follow "Course 1"
+
+  Scenario: Configure the block on the course page to show 1 high score
+    Given I add the "Activity results" block
+    When I configure the "Activity results" block
+    And I set the following fields to these values:
+      | id_config_showbest | 1 |
+      | id_config_showworst | 0 |
+      | id_config_nameformat | Display full names |
+      | id_config_decimalpoints | 0 |
+    And I press "Save changes"
+    Then I should see "Student 1" in the "Activity results" "block"
+    And I should see "Excellent!" in the "Activity results" "block"
+
+  Scenario: Try to configure the block on the course page to show multiple high scores using full names
+    Given I add the "Activity results" block
+    When I configure the "Activity results" block
+    And I set the following fields to these values:
+      | id_config_showbest | 3 |
+      | id_config_showworst | 0 |
+      | id_config_nameformat | Display full names |
+    And I press "Save changes"
+    Then I should see "Student 1" in the "Activity results" "block"
+    And I should see "Excellent!" in the "Activity results" "block"
+    And I should see "Student 2" in the "Activity results" "block"
+    And I should see "Very good" in the "Activity results" "block"
+    And I should see "Student 3" in the "Activity results" "block"
+    And I should see "Good" in the "Activity results" "block"
+
+  Scenario: Try to configure the block on the course page to show multiple high scores using ID numbers
+    Given I add the "Activity results" block
+    When I configure the "Activity results" block
+    And I set the following fields to these values:
+      | id_config_showbest | 3 |
+      | id_config_showworst | 0 |
+      | id_config_nameformat | Display only ID numbers |
+    And I press "Save changes"
+    Then I should see "User S1" in the "Activity results" "block"
+    And I should see "Excellent!" in the "Activity results" "block"
+    And I should see "User S2" in the "Activity results" "block"
+    And I should see "Very good" in the "Activity results" "block"
+    And I should see "User S3" in the "Activity results" "block"
+    And I should see "Good" in the "Activity results" "block"
+
+  Scenario: Try to configure the block on the course page to show multiple high scores using anonymous names
+    Given I add the "Activity results" block
+    When I configure the "Activity results" block
+    And I set the following fields to these values:
+      | id_config_showbest | 3 |
+      | id_config_showworst | 0 |
+      | id_config_nameformat | Anonymous results |
+    And I press "Save changes"
+    Then I should see "User" in the "Activity results" "block"
+    And I should not see "Student 1" in the "Activity results" "block"
+    And I should see "Excellent!" in the "Activity results" "block"
+    And I should not see "Student 2" in the "Activity results" "block"
+    And I should see "Very good" in the "Activity results" "block"
+    And I should not see "Student 3" in the "Activity results" "block"
+    And I should see "Good" in the "Activity results" "block"
diff --git a/blocks/activity_results/tests/behat/highscoreswithscalesandgroups.feature b/blocks/activity_results/tests/behat/highscoreswithscalesandgroups.feature
new file mode 100644 (file)
index 0000000..7856da5
--- /dev/null
@@ -0,0 +1,153 @@
+@block @block_activity_results
+Feature: The activity results block displays student scores as scales
+  In order to be display student scores as scales
+  As a user
+  I need to see the activity results block
+
+  Background:
+    Given the following "users" exist:
+      | username | firstname | lastname | email | idnumber |
+      | teacher1 | Teacher | 1 | teacher1@example.com | T1 |
+      | student1 | Student | 1 | student1@example.com | S1 |
+      | student2 | Student | 2 | student2@example.com | S2 |
+      | student3 | Student | 3 | student3@example.com | S3 |
+      | student4 | Student | 4 | student4@example.com | S4 |
+      | student5 | Student | 5 | student5@example.com | S5 |
+      | student6 | Student | 6 | student6@example.com | S6 |
+    And the following "courses" exist:
+      | fullname | shortname | category |
+      | Course 1 | C1 | 0 |
+    And the following "groups" exist:
+      | name | course | idnumber |
+      | Group 1 | C1 | G1 |
+      | Group 2 | C1 | G2 |
+      | Group 3 | C1 | G3 |
+      | Group 4 | C1 | G4 |
+      | Group 5 | C1 | G5 |
+    And the following "course enrolments" exist:
+      | user | course | role |
+      | teacher1 | C1 | editingteacher |
+      | student1 | C1 | student |
+      | student2 | C1 | student |
+      | student3 | C1 | student |
+      | student4 | C1 | student |
+      | student5 | C1 | student |
+      | student6 | C1 | student |
+    And the following "group members" exist:
+      | user     | group   |
+      | student1 | G1 |
+      | student2 | G1 |
+      | student3 | G2 |
+      | student4 | G2 |
+      | student5 | G3 |
+      | student6 | G3 |
+    And I log in as "teacher1"
+    And I follow "Course 1"
+    And I navigate to "Grades" node in "Course administration"
+    And I navigate to "Scales" node in "Grade administration"
+    And I press "Add a new scale"
+    And I set the following fields to these values:
+      | Name | My Scale |
+      | Scale | Disappointing, Not good enough, Average, Good, Very good, Excellent! |
+    And I press "Save changes"
+    And I follow "Course 1"
+    And I turn editing mode on
+    And I add a "Assignment" to section "1" and I fill the form with:
+      | Assignment name | Test assignment |
+      | Description | Offline text |
+      | assignsubmission_file_enabled | 0 |
+      | id_modgrade_type | Scale |
+      | id_modgrade_scale | My Scale |
+      | Group mode | Separate groups |
+    And I follow "Course 1"
+    And I navigate to "Grades" node in "Course administration"
+    And I turn editing mode on
+    And I give the grade "Excellent!" to the user "Student 1" for the grade item "Test assignment"
+    And I give the grade "Very good" to the user "Student 2" for the grade item "Test assignment"
+    And I give the grade "Very good" to the user "Student 3" for the grade item "Test assignment"
+    And I give the grade "Good" to the user "Student 4" for the grade item "Test assignment"
+    And I give the grade "Good" to the user "Student 5" for the grade item "Test assignment"
+    And I give the grade "Average" to the user "Student 6" for the grade item "Test assignment"
+    And I press "Save changes"
+    And I follow "Course 1"
+
+  Scenario: Try to configure the block on the course page to show 1 high score
+    Given I add the "Activity results" block
+    When I configure the "Activity results" block
+    And I set the following fields to these values:
+      | id_config_showbest | 1 |
+      | id_config_showworst | 0 |
+      | id_config_nameformat | Display full names |
+      | id_config_usegroups | Yes |
+    And I press "Save changes"
+    Then I should see "Group 1" in the "Activity results" "block"
+    And I should see "Excellent!" in the "Activity results" "block"
+    And I log out
+    And I log in as "student1"
+    And I follow "Course 1"
+    And I should see "Student 1" in the "Activity results" "block"
+    And I should see "Excellent!" in the "Activity results" "block"
+
+  Scenario: Try to configure the block on the course page to show multiple high scores using full names
+    Given I add the "Activity results" block
+    When I configure the "Activity results" block
+    And I set the following fields to these values:
+      | id_config_showbest | 3 |
+      | id_config_showworst | 0 |
+      | id_config_nameformat | Display full names |
+      | id_config_usegroups | Yes |
+    And I press "Save changes"
+    Then I should see "Group 1" in the "Activity results" "block"
+    And I should see "Excellent!" in the "Activity results" "block"
+    And I should see "Group 2" in the "Activity results" "block"
+    And I should see "Very good" in the "Activity results" "block"
+    And I should see "Group 3" in the "Activity results" "block"
+    And I should see "Good" in the "Activity results" "block"
+    And I log out
+    And I log in as "student3"
+    And I follow "Course 1"
+    And I should see "Student 3" in the "Activity results" "block"
+    And I should see "Very good" in the "Activity results" "block"
+    And I should see "Student 4" in the "Activity results" "block"
+    And I should see "Good" in the "Activity results" "block"
+
+  Scenario: Try to configure the block on the course page to show multiple high scores using ID numbers
+    Given I add the "Activity results" block
+    When I configure the "Activity results" block
+    And I set the following fields to these values:
+      | id_config_showbest | 3 |
+      | id_config_showworst | 0 |
+      | id_config_nameformat | Display only ID numbers |
+      | id_config_usegroups | Yes |
+    And I press "Save changes"
+    Then I should see "Group" in the "Activity results" "block"
+    And I should see "Excellent!" in the "Activity results" "block"
+    And I should see "Very good" in the "Activity results" "block"
+    And I should see "Good" in the "Activity results" "block"
+    And I log out
+    And I log in as "student1"
+    And I follow "Course 1"
+    And I should see "User S1" in the "Activity results" "block"
+    And I should see "Excellent!" in the "Activity results" "block"
+    And I should see "User S2" in the "Activity results" "block"
+    And I should see "Very good" in the "Activity results" "block"
+
+  Scenario: Try to configure the block on the course page to show multiple high scores using anonymous names
+    Given I add the "Activity results" block
+    When I configure the "Activity results" block
+    And I set the following fields to these values:
+      | id_config_showbest | 3 |
+      | id_config_showworst | 0 |
+      | id_config_nameformat | Anonymous results |
+      | id_config_usegroups | Yes |
+    And I press "Save changes"
+    Then I should see "Group" in the "Activity results" "block"
+    And I should see "Excellent!" in the "Activity results" "block"
+    And I should see "Very good" in the "Activity results" "block"
+    And I should see "Good" in the "Activity results" "block"
+    And I log out
+    And I log in as "student1"
+    And I follow "Course 1"
+    And I should see "User" in the "Activity results" "block"
+    And I should see "Excellent!" in the "Activity results" "block"
+    And I should see "Very good" in the "Activity results" "block"
index 3939bd6..27807f8 100644 (file)
@@ -33,19 +33,15 @@ Feature: The activity results block displays student scores
       | student4 | C1 | student |
       | student5 | C1 | student |
       | student6 | C1 | student |
-
-  @javascript
-  Scenario: Configure the block on the course page to show 1 high score
-    Given I log in as "teacher1"
-    And I follow "Course 1"
-    And I expand "Users" node
-    And I follow "Groups"
-    And I add "Student 1 (student1@example.com)" user to "Group 1" group members
-    And I add "Student 2 (student2@example.com)" user to "Group 1" group members
-    And I add "Student 3 (student3@example.com)" user to "Group 2" group members
-    And I add "Student 4 (student4@example.com)" user to "Group 2" group members
-    And I add "Student 5 (student5@example.com)" user to "Group 3" group members
-    And I add "Student 6 (student6@example.com)" user to "Group 3" group members
+    And the following "group members" exist:
+      | user     | group   |
+      | student1 | G1 |
+      | student2 | G1 |
+      | student3 | G2 |
+      | student4 | G2 |
+      | student5 | G3 |
+      | student6 | G3 |
+    And I log in as "teacher1"
     And I follow "Course 1"
     And I turn editing mode on
     And I add a "Assignment" to section "1" and I fill the form with:
@@ -64,7 +60,9 @@ Feature: The activity results block displays student scores
     And I give the grade "70.00" to the user "Student 6" for the grade item "Test assignment"
     And I press "Save changes"
     And I follow "Course 1"
-    And I add the "Activity results" block
+
+  Scenario: Configure the block on the course page to show 1 high score
+    Given I add the "Activity results" block
     When I configure the "Activity results" block
     And I set the following fields to these values:
       | id_config_showbest | 1 |
@@ -77,37 +75,8 @@ Feature: The activity results block displays student scores
     Then I should see "Group 1" in the "Activity results" "block"
     And I should see "95%" in the "Activity results" "block"
 
-  @javascript
   Scenario: Try to configure the block on the course page to show 1 high score as a fraction
-    Given I log in as "teacher1"
-    And I follow "Course 1"
-    And I expand "Users" node
-    And I follow "Groups"
-    And I add "Student 1 (student1@example.com)" user to "Group 1" group members
-    And I add "Student 2 (student2@example.com)" user to "Group 1" group members
-    And I add "Student 3 (student3@example.com)" user to "Group 2" group members
-    And I add "Student 4 (student4@example.com)" user to "Group 2" group members
-    And I add "Student 5 (student5@example.com)" user to "Group 3" group members
-    And I add "Student 6 (student6@example.com)" user to "Group 3" group members
-    And I follow "Course 1"
-    And I turn editing mode on
-    And I add a "Assignment" to section "1" and I fill the form with:
-      | Assignment name | Test assignment |
-      | Description | Offline text |
-      | assignsubmission_file_enabled | 0 |
-      | Group mode | Separate groups |
-    And I follow "Course 1"
-    And I navigate to "Grades" node in "Course administration"
-    And I turn editing mode on
-    And I give the grade "100.00" to the user "Student 1" for the grade item "Test assignment"
-    And I give the grade "90.00" to the user "Student 2" for the grade item "Test assignment"
-    And I give the grade "90.00" to the user "Student 3" for the grade item "Test assignment"
-    And I give the grade "80.00" to the user "Student 4" for the grade item "Test assignment"
-    And I give the grade "80.00" to the user "Student 5" for the grade item "Test assignment"
-    And I give the grade "70.00" to the user "Student 6" for the grade item "Test assignment"
-    And I press "Save changes"
-    And I follow "Course 1"
-    And I add the "Activity results" block
+    Given I add the "Activity results" block
     When I configure the "Activity results" block
     And I set the following fields to these values:
       | id_config_showbest | 1 |
@@ -124,37 +93,8 @@ Feature: The activity results block displays student scores
     And I should see "Student 1" in the "Activity results" "block"
     And I should see "100.00/100.00" in the "Activity results" "block"
 
-  @javascript
   Scenario: Try to configure the block on the course page to show 1 high score as a absolute numbers
-    Given I log in as "teacher1"
-    And I follow "Course 1"
-    And I expand "Users" node
-    And I follow "Groups"
-    And I add "Student 1 (student1@example.com)" user to "Group 1" group members
-    And I add "Student 2 (student2@example.com)" user to "Group 1" group members
-    And I add "Student 3 (student3@example.com)" user to "Group 2" group members
-    And I add "Student 4 (student4@example.com)" user to "Group 2" group members
-    And I add "Student 5 (student5@example.com)" user to "Group 3" group members
-    And I add "Student 6 (student6@example.com)" user to "Group 3" group members
-    And I follow "Course 1"
-    And I turn editing mode on
-    And I add a "Assignment" to section "1" and I fill the form with:
-      | Assignment name | Test assignment |
-      | Description | Offline text |
-      | assignsubmission_file_enabled | 0 |
-      | Group mode | Separate groups |
-    And I follow "Course 1"
-    And I navigate to "Grades" node in "Course administration"
-    And I turn editing mode on
-    And I give the grade "100.00" to the user "Student 1" for the grade item "Test assignment"
-    And I give the grade "90.00" to the user "Student 2" for the grade item "Test assignment"
-    And I give the grade "90.00" to the user "Student 3" for the grade item "Test assignment"
-    And I give the grade "80.00" to the user "Student 4" for the grade item "Test assignment"
-    And I give the grade "80.00" to the user "Student 5" for the grade item "Test assignment"
-    And I give the grade "70.00" to the user "Student 6" for the grade item "Test assignment"
-    And I press "Save changes"
-    And I follow "Course 1"
-    And I add the "Activity results" block
+    Given I add the "Activity results" block
     When I configure the "Activity results" block
     And I set the following fields to these values:
       | id_config_showbest | 1 |
@@ -171,37 +111,8 @@ Feature: The activity results block displays student scores
     And I should see "Student 1" in the "Activity results" "block"
     And I should see "100.00" in the "Activity results" "block"
 
-  @javascript
   Scenario: Try to configure the block on the course page to show multiple high scores as percentages
-    Given I log in as "teacher1"
-    And I follow "Course 1"
-    And I expand "Users" node
-    And I follow "Groups"
-    And I add "Student 1 (student1@example.com)" user to "Group 1" group members
-    And I add "Student 2 (student2@example.com)" user to "Group 1" group members
-    And I add "Student 3 (student3@example.com)" user to "Group 2" group members
-    And I add "Student 4 (student4@example.com)" user to "Group 2" group members
-    And I add "Student 5 (student5@example.com)" user to "Group 3" group members
-    And I add "Student 6 (student6@example.com)" user to "Group 3" group members
-    And I follow "Course 1"
-    And I turn editing mode on
-    And I add a "Assignment" to section "1" and I fill the form with:
-      | Assignment name | Test assignment |
-      | Description | Offline text |
-      | assignsubmission_file_enabled | 0 |
-      | Group mode | Separate groups |
-    And I follow "Course 1"
-    And I navigate to "Grades" node in "Course administration"
-    And I turn editing mode on
-    And I give the grade "100.00" to the user "Student 1" for the grade item "Test assignment"
-    And I give the grade "90.00" to the user "Student 2" for the grade item "Test assignment"
-    And I give the grade "90.00" to the user "Student 3" for the grade item "Test assignment"
-    And I give the grade "80.00" to the user "Student 4" for the grade item "Test assignment"
-    And I give the grade "80.00" to the user "Student 5" for the grade item "Test assignment"
-    And I give the grade "70.00" to the user "Student 6" for the grade item "Test assignment"
-    And I press "Save changes"
-    And I follow "Course 1"
-    And I add the "Activity results" block
+    Given I add the "Activity results" block
     When I configure the "Activity results" block
     And I set the following fields to these values:
       | id_config_showbest | 3 |
@@ -225,37 +136,8 @@ Feature: The activity results block displays student scores
     And I should see "Student 2" in the "Activity results" "block"
     And I should see "90%" in the "Activity results" "block"
 
-  @javascript
   Scenario: Try to configure the block on the course page to show multiple high scores as fractions
-    Given I log in as "teacher1"
-    And I follow "Course 1"
-    And I expand "Users" node
-    And I follow "Groups"
-    And I add "Student 1 (student1@example.com)" user to "Group 1" group members
-    And I add "Student 2 (student2@example.com)" user to "Group 1" group members
-    And I add "Student 3 (student3@example.com)" user to "Group 2" group members
-    And I add "Student 4 (student4@example.com)" user to "Group 2" group members
-    And I add "Student 5 (student5@example.com)" user to "Group 3" group members
-    And I add "Student 6 (student6@example.com)" user to "Group 3" group members
-    And I follow "Course 1"
-    And I turn editing mode on
-    And I add a "Assignment" to section "1" and I fill the form with:
-      | Assignment name | Test assignment |
-      | Description | Offline text |
-      | assignsubmission_file_enabled | 0 |
-      | Group mode | Separate groups |
-    And I follow "Course 1"
-    And I navigate to "Grades" node in "Course administration"
-    And I turn editing mode on
-    And I give the grade "100.00" to the user "Student 1" for the grade item "Test assignment"
-    And I give the grade "90.00" to the user "Student 2" for the grade item "Test assignment"
-    And I give the grade "90.00" to the user "Student 3" for the grade item "Test assignment"
-    And I give the grade "80.00" to the user "Student 4" for the grade item "Test assignment"
-    And I give the grade "80.00" to the user "Student 5" for the grade item "Test assignment"
-    And I give the grade "70.00" to the user "Student 6" for the grade item "Test assignment"
-    And I press "Save changes"
-    And I follow "Course 1"
-    And I add the "Activity results" block
+    Given I add the "Activity results" block
     When I configure the "Activity results" block
     And I set the following fields to these values:
       | id_config_showbest | 3 |
@@ -278,37 +160,8 @@ Feature: The activity results block displays student scores
     And I should see "Student 4" in the "Activity results" "block"
     And I should see "80.00/100.00" in the "Activity results" "block"
 
-  @javascript
   Scenario: Try to configure the block on the course page to show multiple high scores as absolute numbers
-    Given I log in as "teacher1"
-    And I follow "Course 1"
-    And I expand "Users" node
-    And I follow "Groups"
-    And I add "Student 1 (student1@example.com)" user to "Group 1" group members
-    And I add "Student 2 (student2@example.com)" user to "Group 1" group members
-    And I add "Student 3 (student3@example.com)" user to "Group 2" group members
-    And I add "Student 4 (student4@example.com)" user to "Group 2" group members
-    And I add "Student 5 (student5@example.com)" user to "Group 3" group members
-    And I add "Student 6 (student6@example.com)" user to "Group 3" group members
-    And I follow "Course 1"
-    And I turn editing mode on
-    And I add a "Assignment" to section "1" and I fill the form with:
-      | Assignment name | Test assignment |
-      | Description | Offline text |
-      | assignsubmission_file_enabled | 0 |
-      | Group mode | Separate groups |
-    And I follow "Course 1"
-    And I navigate to "Grades" node in "Course administration"
-    And I turn editing mode on
-    And I give the grade "100.00" to the user "Student 1" for the grade item "Test assignment"
-    And I give the grade "90.00" to the user "Student 2" for the grade item "Test assignment"
-    And I give the grade "90.00" to the user "Student 3" for the grade item "Test assignment"
-    And I give the grade "80.00" to the user "Student 4" for the grade item "Test assignment"
-    And I give the grade "80.00" to the user "Student 5" for the grade item "Test assignment"
-    And I give the grade "70.00" to the user "Student 6" for the grade item "Test assignment"
-    And I press "Save changes"
-    And I follow "Course 1"
-    And I add the "Activity results" block
+    Given I add the "Activity results" block
     When I configure the "Activity results" block
     And I set the following fields to these values:
       | id_config_showbest | 3 |
@@ -331,37 +184,8 @@ Feature: The activity results block displays student scores
     And I should see "Student 2" in the "Activity results" "block"
     And I should see "90.00" in the "Activity results" "block"
 
-  @javascript
   Scenario: Try to configure the block on the course page to show multiple high scores using ID numbers
-    Given I log in as "teacher1"
-    And I follow "Course 1"
-    And I expand "Users" node
-    And I follow "Groups"
-    And I add "Student 1 (student1@example.com)" user to "Group 1" group members
-    And I add "Student 2 (student2@example.com)" user to "Group 1" group members
-    And I add "Student 3 (student3@example.com)" user to "Group 2" group members
-    And I add "Student 4 (student4@example.com)" user to "Group 2" group members
-    And I add "Student 5 (student5@example.com)" user to "Group 3" group members
-    And I add "Student 6 (student6@example.com)" user to "Group 3" group members
-    And I follow "Course 1"
-    And I turn editing mode on
-    And I add a "Assignment" to section "1" and I fill the form with:
-      | Assignment name | Test assignment |
-      | Description | Offline text |
-      | assignsubmission_file_enabled | 0 |
-      | Group mode | Separate groups |
-    And I follow "Course 1"
-    And I navigate to "Grades" node in "Course administration"
-    And I turn editing mode on
-    And I give the grade "100.00" to the user "Student 1" for the grade item "Test assignment"
-    And I give the grade "90.00" to the user "Student 2" for the grade item "Test assignment"
-    And I give the grade "90.00" to the user "Student 3" for the grade item "Test assignment"
-    And I give the grade "80.00" to the user "Student 4" for the grade item "Test assignment"
-    And I give the grade "80.00" to the user "Student 5" for the grade item "Test assignment"
-    And I give the grade "70.00" to the user "Student 6" for the grade item "Test assignment"
-    And I press "Save changes"
-    And I follow "Course 1"
-    And I add the "Activity results" block
+    Given I add the "Activity results" block
     When I configure the "Activity results" block
     And I set the following fields to these values:
       | id_config_showbest | 3 |
@@ -382,37 +206,8 @@ Feature: The activity results block displays student scores
     And I should see "User S2" in the "Activity results" "block"
     And I should see "90.00%" in the "Activity results" "block"
 
-  @javascript
   Scenario: Try to configure the block on the course page to show multiple high scores using anonymous names
-    Given I log in as "teacher1"
-    And I follow "Course 1"
-    And I expand "Users" node
-    And I follow "Groups"
-    And I add "Student 1 (student1@example.com)" user to "Group 1" group members
-    And I add "Student 2 (student2@example.com)" user to "Group 1" group members
-    And I add "Student 3 (student3@example.com)" user to "Group 2" group members
-    And I add "Student 4 (student4@example.com)" user to "Group 2" group members
-    And I add "Student 5 (student5@example.com)" user to "Group 3" group members
-    And I add "Student 6 (student6@example.com)" user to "Group 3" group members
-    And I follow "Course 1"
-    And I turn editing mode on
-    And I add a "Assignment" to section "1" and I fill the form with:
-      | Assignment name | Test assignment |
-      | Description | Offline text |
-      | assignsubmission_file_enabled | 0 |
-      | Group mode | Separate groups |
-    And I follow "Course 1"
-    And I navigate to "Grades" node in "Course administration"
-    And I turn editing mode on
-    And I give the grade "100.00" to the user "Student 1" for the grade item "Test assignment"
-    And I give the grade "90.00" to the user "Student 2" for the grade item "Test assignment"
-    And I give the grade "90.00" to the user "Student 3" for the grade item "Test assignment"
-    And I give the grade "80.00" to the user "Student 4" for the grade item "Test assignment"
-    And I give the grade "80.00" to the user "Student 5" for the grade item "Test assignment"
-    And I give the grade "70.00" to the user "Student 6" for the grade item "Test assignment"
-    And I press "Save changes"
-    And I follow "Course 1"
-    And I add the "Activity results" block
+    Given I add the "Activity results" block
     When I configure the "Activity results" block
     And I set the following fields to these values:
       | id_config_showbest | 3 |
index 845e8ab..f5fd1bd 100644 (file)
@@ -33,19 +33,15 @@ Feature: The activity results block displays student scores
       | student4 | C1 | student |
       | student5 | C1 | student |
       | student6 | C1 | student |
-
-  @javascript
-  Scenario: Configure the block on the course page to show 1 high score
-    Given I log in as "teacher1"
-    And I follow "Course 1"
-    And I expand "Users" node
-    And I follow "Groups"
-    And I add "Student 1 (student1@example.com)" user to "Group 1" group members
-    And I add "Student 2 (student2@example.com)" user to "Group 1" group members
-    And I add "Student 3 (student3@example.com)" user to "Group 2" group members
-    And I add "Student 4 (student4@example.com)" user to "Group 2" group members
-    And I add "Student 5 (student5@example.com)" user to "Group 3" group members
-    And I add "Student 6 (student6@example.com)" user to "Group 3" group members
+    And the following "group members" exist:
+      | user     | group   |
+      | student1 | G1 |
+      | student2 | G1 |
+      | student3 | G2 |
+      | student4 | G2 |
+      | student5 | G3 |
+      | student6 | G3 |
+    And I log in as "teacher1"
     And I follow "Course 1"
     And I turn editing mode on
     And I add a "Assignment" to section "1" and I fill the form with:
@@ -64,7 +60,9 @@ Feature: The activity results block displays student scores
     And I give the grade "70.00" to the user "Student 6" for the grade item "Test assignment"
     And I press "Save changes"
     And I follow "Course 1"
-    And I add the "Activity results" block
+
+  Scenario: Configure the block on the course page to show 1 high score
+    Given I add the "Activity results" block
     When I configure the "Activity results" block
     And I set the following fields to these values:
       | id_config_showbest | 1 |
@@ -77,37 +75,8 @@ Feature: The activity results block displays student scores
     Then I should see "Group 1" in the "Activity results" "block"
     And I should see "95%" in the "Activity results" "block"
 
-  @javascript
   Scenario: Try to configure the block on the course page to show 1 high score as a fraction
-    Given I log in as "teacher1"
-    And I follow "Course 1"
-    And I expand "Users" node
-    And I follow "Groups"
-    And I add "Student 1 (student1@example.com)" user to "Group 1" group members
-    And I add "Student 2 (student2@example.com)" user to "Group 1" group members
-    And I add "Student 3 (student3@example.com)" user to "Group 2" group members
-    And I add "Student 4 (student4@example.com)" user to "Group 2" group members
-    And I add "Student 5 (student5@example.com)" user to "Group 3" group members
-    And I add "Student 6 (student6@example.com)" user to "Group 3" group members
-    And I follow "Course 1"
-    And I turn editing mode on
-    And I add a "Assignment" to section "1" and I fill the form with:
-      | Assignment name | Test assignment |
-      | Description | Offline text |
-      | assignsubmission_file_enabled | 0 |
-      | Group mode | Visible groups |
-    And I follow "Course 1"
-    And I navigate to "Grades" node in "Course administration"
-    And I turn editing mode on
-    And I give the grade "100.00" to the user "Student 1" for the grade item "Test assignment"
-    And I give the grade "90.00" to the user "Student 2" for the grade item "Test assignment"
-    And I give the grade "90.00" to the user "Student 3" for the grade item "Test assignment"
-    And I give the grade "80.00" to the user "Student 4" for the grade item "Test assignment"
-    And I give the grade "80.00" to the user "Student 5" for the grade item "Test assignment"
-    And I give the grade "70.00" to the user "Student 6" for the grade item "Test assignment"
-    And I press "Save changes"
-    And I follow "Course 1"
-    And I add the "Activity results" block
+    Given I add the "Activity results" block
     When I configure the "Activity results" block
     And I set the following fields to these values:
       | id_config_showbest | 1 |
@@ -122,37 +91,8 @@ Feature: The activity results block displays student scores
     And I should see "Group 1" in the "Activity results" "block"
     And I should see "95.00/100.00" in the "Activity results" "block"
 
-  @javascript
   Scenario: Try to configure the block on the course page to show 1 high score as a absolute numbers
-    Given I log in as "teacher1"
-    And I follow "Course 1"
-    And I expand "Users" node
-    And I follow "Groups"
-    And I add "Student 1 (student1@example.com)" user to "Group 1" group members
-    And I add "Student 2 (student2@example.com)" user to "Group 1" group members
-    And I add "Student 3 (student3@example.com)" user to "Group 2" group members
-    And I add "Student 4 (student4@example.com)" user to "Group 2" group members
-    And I add "Student 5 (student5@example.com)" user to "Group 3" group members
-    And I add "Student 6 (student6@example.com)" user to "Group 3" group members
-    And I follow "Course 1"
-    And I turn editing mode on
-    And I add a "Assignment" to section "1" and I fill the form with:
-      | Assignment name | Test assignment |
-      | Description | Offline text |
-      | assignsubmission_file_enabled | 0 |
-      | Group mode | Visible groups |
-    And I follow "Course 1"
-    And I navigate to "Grades" node in "Course administration"
-    And I turn editing mode on
-    And I give the grade "100.00" to the user "Student 1" for the grade item "Test assignment"
-    And I give the grade "90.00" to the user "Student 2" for the grade item "Test assignment"
-    And I give the grade "90.00" to the user "Student 3" for the grade item "Test assignment"
-    And I give the grade "80.00" to the user "Student 4" for the grade item "Test assignment"
-    And I give the grade "80.00" to the user "Student 5" for the grade item "Test assignment"
-    And I give the grade "70.00" to the user "Student 6" for the grade item "Test assignment"
-    And I press "Save changes"
-    And I follow "Course 1"
-    And I add the "Activity results" block
+    Given I add the "Activity results" block
     When I configure the "Activity results" block
     And I set the following fields to these values:
       | id_config_showbest | 1 |
@@ -167,37 +107,8 @@ Feature: The activity results block displays student scores
     And I should see "Group 1" in the "Activity results" "block"
     And I should see "95.00" in the "Activity results" "block"
 
-  @javascript
   Scenario: Try to configure the block on the course page to show multiple high scores as percentages
-    Given I log in as "teacher1"
-    And I follow "Course 1"
-    And I expand "Users" node
-    And I follow "Groups"
-    And I add "Student 1 (student1@example.com)" user to "Group 1" group members
-    And I add "Student 2 (student2@example.com)" user to "Group 1" group members
-    And I add "Student 3 (student3@example.com)" user to "Group 2" group members
-    And I add "Student 4 (student4@example.com)" user to "Group 2" group members
-    And I add "Student 5 (student5@example.com)" user to "Group 3" group members
-    And I add "Student 6 (student6@example.com)" user to "Group 3" group members
-    And I follow "Course 1"
-    And I turn editing mode on
-    And I add a "Assignment" to section "1" and I fill the form with:
-      | Assignment name | Test assignment |
-      | Description | Offline text |
-      | assignsubmission_file_enabled | 0 |
-      | Group mode | Visible groups |
-    And I follow "Course 1"
-    And I navigate to "Grades" node in "Course administration"
-    And I turn editing mode on
-    And I give the grade "100.00" to the user "Student 1" for the grade item "Test assignment"
-    And I give the grade "90.00" to the user "Student 2" for the grade item "Test assignment"
-    And I give the grade "90.00" to the user "Student 3" for the grade item "Test assignment"
-    And I give the grade "80.00" to the user "Student 4" for the grade item "Test assignment"
-    And I give the grade "80.00" to the user "Student 5" for the grade item "Test assignment"
-    And I give the grade "70.00" to the user "Student 6" for the grade item "Test assignment"
-    And I press "Save changes"
-    And I follow "Course 1"
-    And I add the "Activity results" block
+    Given I add the "Activity results" block
     When I configure the "Activity results" block
     And I set the following fields to these values:
       | id_config_showbest | 3 |
@@ -217,37 +128,8 @@ Feature: The activity results block displays student scores
     And I should see "Group 3" in the "Activity results" "block"
     And I should see "75%" in the "Activity results" "block"
 
-  @javascript
   Scenario: Try to configure the block on the course page to show multiple high scores as fractions
-    Given I log in as "teacher1"
-    And I follow "Course 1"
-    And I expand "Users" node
-    And I follow "Groups"
-    And I add "Student 1 (student1@example.com)" user to "Group 1" group members
-    And I add "Student 2 (student2@example.com)" user to "Group 1" group members
-    And I add "Student 3 (student3@example.com)" user to "Group 2" group members
-    And I add "Student 4 (student4@example.com)" user to "Group 2" group members
-    And I add "Student 5 (student5@example.com)" user to "Group 3" group members
-    And I add "Student 6 (student6@example.com)" user to "Group 3" group members
-    And I follow "Course 1"
-    And I turn editing mode on
-    And I add a "Assignment" to section "1" and I fill the form with:
-      | Assignment name | Test assignment |
-      | Description | Offline text |
-      | assignsubmission_file_enabled | 0 |
-      | Group mode | Visible groups |
-    And I follow "Course 1"
-    And I navigate to "Grades" node in "Course administration"
-    And I turn editing mode on
-    And I give the grade "100.00" to the user "Student 1" for the grade item "Test assignment"
-    And I give the grade "90.00" to the user "Student 2" for the grade item "Test assignment"
-    And I give the grade "90.00" to the user "Student 3" for the grade item "Test assignment"
-    And I give the grade "80.00" to the user "Student 4" for the grade item "Test assignment"
-    And I give the grade "80.00" to the user "Student 5" for the grade item "Test assignment"
-    And I give the grade "70.00" to the user "Student 6" for the grade item "Test assignment"
-    And I press "Save changes"
-    And I follow "Course 1"
-    And I add the "Activity results" block
+    Given I add the "Activity results" block
     When I configure the "Activity results" block
     And I set the following fields to these values:
       | id_config_showbest | 3 |
@@ -266,37 +148,8 @@ Feature: The activity results block displays student scores
     And I should see "Group 3" in the "Activity results" "block"
     And I should see "75.00/100.00" in the "Activity results" "block"
 
-  @javascript
   Scenario: Try to configure the block on the course page to show multiple high scores as absolute numbers
-    Given I log in as "teacher1"
-    And I follow "Course 1"
-    And I expand "Users" node
-    And I follow "Groups"
-    And I add "Student 1 (student1@example.com)" user to "Group 1" group members
-    And I add "Student 2 (student2@example.com)" user to "Group 1" group members
-    And I add "Student 3 (student3@example.com)" user to "Group 2" group members
-    And I add "Student 4 (student4@example.com)" user to "Group 2" group members
-    And I add "Student 5 (student5@example.com)" user to "Group 3" group members
-    And I add "Student 6 (student6@example.com)" user to "Group 3" group members
-    And I follow "Course 1"
-    And I turn editing mode on
-    And I add a "Assignment" to section "1" and I fill the form with:
-      | Assignment name | Test assignment |
-      | Description | Offline text |
-      | assignsubmission_file_enabled | 0 |
-      | Group mode | Visible groups |
-    And I follow "Course 1"
-    And I navigate to "Grades" node in "Course administration"
-    And I turn editing mode on
-    And I give the grade "100.00" to the user "Student 1" for the grade item "Test assignment"
-    And I give the grade "90.00" to the user "Student 2" for the grade item "Test assignment"
-    And I give the grade "90.00" to the user "Student 3" for the grade item "Test assignment"
-    And I give the grade "80.00" to the user "Student 4" for the grade item "Test assignment"
-    And I give the grade "80.00" to the user "Student 5" for the grade item "Test assignment"
-    And I give the grade "70.00" to the user "Student 6" for the grade item "Test assignment"
-    And I press "Save changes"
-    And I follow "Course 1"
-    And I add the "Activity results" block
+    Given I add the "Activity results" block
     When I configure the "Activity results" block
     And I set the following fields to these values:
       | id_config_showbest | 3 |
@@ -315,37 +168,8 @@ Feature: The activity results block displays student scores
     And I should see "Group 3" in the "Activity results" "block"
     And I should see "75.00" in the "Activity results" "block"
 
-  @javascript
   Scenario: Try to configure the block on the course page to show multiple high scores using ID numbers
-    Given I log in as "teacher1"
-    And I follow "Course 1"
-    And I expand "Users" node
-    And I follow "Groups"
-    And I add "Student 1 (student1@example.com)" user to "Group 1" group members
-    And I add "Student 2 (student2@example.com)" user to "Group 1" group members
-    And I add "Student 3 (student3@example.com)" user to "Group 2" group members
-    And I add "Student 4 (student4@example.com)" user to "Group 2" group members
-    And I add "Student 5 (student5@example.com)" user to "Group 3" group members
-    And I add "Student 6 (student6@example.com)" user to "Group 3" group members
-    And I follow "Course 1"
-    And I turn editing mode on
-    And I add a "Assignment" to section "1" and I fill the form with:
-      | Assignment name | Test assignment |
-      | Description | Offline text |
-      | assignsubmission_file_enabled | 0 |
-      | Group mode | Visible groups |
-    And I follow "Course 1"
-    And I navigate to "Grades" node in "Course administration"
-    And I turn editing mode on
-    And I give the grade "100.00" to the user "Student 1" for the grade item "Test assignment"
-    And I give the grade "90.00" to the user "Student 2" for the grade item "Test assignment"
-    And I give the grade "90.00" to the user "Student 3" for the grade item "Test assignment"
-    And I give the grade "80.00" to the user "Student 4" for the grade item "Test assignment"
-    And I give the grade "80.00" to the user "Student 5" for the grade item "Test assignment"
-    And I give the grade "70.00" to the user "Student 6" for the grade item "Test assignment"
-    And I press "Save changes"
-    And I follow "Course 1"
-    And I add the "Activity results" block
+    Given I add the "Activity results" block
     When I configure the "Activity results" block
     And I set the following fields to these values:
       | id_config_showbest | 3 |
@@ -362,37 +186,8 @@ Feature: The activity results block displays student scores
     And I should see "85.00%" in the "Activity results" "block"
     And I should see "75.00%" in the "Activity results" "block"
 
-  @javascript
   Scenario: Try to configure the block on the course page to show multiple high scores using anonymous names
-    Given I log in as "teacher1"
-    And I follow "Course 1"
-    And I expand "Users" node
-    And I follow "Groups"
-    And I add "Student 1 (student1@example.com)" user to "Group 1" group members
-    And I add "Student 2 (student2@example.com)" user to "Group 1" group members
-    And I add "Student 3 (student3@example.com)" user to "Group 2" group members
-    And I add "Student 4 (student4@example.com)" user to "Group 2" group members
-    And I add "Student 5 (student5@example.com)" user to "Group 3" group members
-    And I add "Student 6 (student6@example.com)" user to "Group 3" group members
-    And I follow "Course 1"
-    And I turn editing mode on
-    And I add a "Assignment" to section "1" and I fill the form with:
-      | Assignment name | Test assignment |
-      | Description | Offline text |
-      | assignsubmission_file_enabled | 0 |
-      | Group mode | Visible groups |
-    And I follow "Course 1"
-    And I navigate to "Grades" node in "Course administration"
-    And I turn editing mode on
-    And I give the grade "100.00" to the user "Student 1" for the grade item "Test assignment"
-    And I give the grade "90.00" to the user "Student 2" for the grade item "Test assignment"
-    And I give the grade "90.00" to the user "Student 3" for the grade item "Test assignment"
-    And I give the grade "80.00" to the user "Student 4" for the grade item "Test assignment"
-    And I give the grade "80.00" to the user "Student 5" for the grade item "Test assignment"
-    And I give the grade "70.00" to the user "Student 6" for the grade item "Test assignment"
-    And I press "Save changes"
-    And I follow "Course 1"
-    And I add the "Activity results" block
+    Given I add the "Activity results" block
     When I configure the "Activity results" block
     And I set the following fields to these values:
       | id_config_showbest | 3 |
diff --git a/blocks/activity_results/tests/behat/lowscoreswithscales.feature b/blocks/activity_results/tests/behat/lowscoreswithscales.feature
new file mode 100644 (file)
index 0000000..149e0f6
--- /dev/null
@@ -0,0 +1,112 @@
+@block @block_activity_results
+Feature: The activity results block displays student scores as scales
+  In order to be display student scores as scales
+  As a user
+  I need to see the activity results block
+
+  Background:
+    Given the following "users" exist:
+      | username | firstname | lastname | email | idnumber |
+      | teacher1 | Teacher | 1 | teacher1@example.com | T1 |
+      | student1 | Student | 1 | student1@example.com | S1 |
+      | student2 | Student | 2 | student2@example.com | S2 |
+      | student3 | Student | 3 | student3@example.com | S3 |
+      | student4 | Student | 4 | student4@example.com | S4 |
+      | student5 | Student | 5 | student5@example.com | S5 |
+    And the following "courses" exist:
+      | fullname | shortname | category |
+      | Course 1 | C1 | 0 |
+    And the following "course enrolments" exist:
+      | user | course | role |
+      | teacher1 | C1 | editingteacher |
+      | student1 | C1 | student |
+      | student2 | C1 | student |
+      | student3 | C1 | student |
+      | student4 | C1 | student |
+      | student5 | C1 | student |
+    And I log in as "teacher1"
+    And I follow "Course 1"
+    And I navigate to "Grades" node in "Course administration"
+    And I navigate to "Scales" node in "Grade administration"
+    And I press "Add a new scale"
+    And I set the following fields to these values:
+      | Name | My Scale |
+      | Scale | Disappointing, Not good enough, Average, Good, Very good, Excellent! |
+    And I press "Save changes"
+    And I follow "Course 1"
+    And I turn editing mode on
+    And I add a "Assignment" to section "1" and I fill the form with:
+      | Assignment name | Test assignment |
+      | Description | Offline text |
+      | assignsubmission_file_enabled | 0 |
+      | id_modgrade_type | Scale |
+      | id_modgrade_scale | My Scale |
+    And I follow "Course 1"
+    And I navigate to "Grades" node in "Course administration"
+    And I turn editing mode on
+    And I give the grade "Excellent!" to the user "Student 1" for the grade item "Test assignment"
+    And I give the grade "Very good" to the user "Student 2" for the grade item "Test assignment"
+    And I give the grade "Good" to the user "Student 3" for the grade item "Test assignment"
+    And I give the grade "Average" to the user "Student 4" for the grade item "Test assignment"
+    And I give the grade "Not good enough" to the user "Student 5" for the grade item "Test assignment"
+    And I press "Save changes"
+    And I follow "Course 1"
+
+  Scenario: Configure the block on the course page to show 1 low score
+    Given I add the "Activity results" block
+    When I configure the "Activity results" block
+    And I set the following fields to these values:
+      | id_config_showbest | 0 |
+      | id_config_showworst | 1 |
+      | id_config_gradeformat | Percentages |
+      | id_config_nameformat | Display full names |
+      | id_config_decimalpoints | 0 |
+    And I press "Save changes"
+    Then I should see "Student 5" in the "Activity results" "block"
+    And I should see "Not good enough" in the "Activity results" "block"
+
+  Scenario: Try to configure the block on the course page to show multiple low scores using full names
+    Given I add the "Activity results" block
+    When I configure the "Activity results" block
+    And I set the following fields to these values:
+      | id_config_showbest | 0 |
+      | id_config_showworst | 3 |
+      | id_config_nameformat | Display full names |
+    And I press "Save changes"
+    Then I should see "Student 5" in the "Activity results" "block"
+    And I should see "Not good enough" in the "Activity results" "block"
+    And I should see "Student 4" in the "Activity results" "block"
+    And I should see "Average" in the "Activity results" "block"
+    And I should see "Student 3" in the "Activity results" "block"
+    And I should see "Good" in the "Activity results" "block"
+
+  Scenario: Try to configure the block on the course page to show multiple low scores using ID numbers
+    Given I add the "Activity results" block
+    When I configure the "Activity results" block
+    And I set the following fields to these values:
+      | id_config_showbest | 0 |
+      | id_config_showworst | 3 |
+      | id_config_nameformat | Display only ID numbers |
+    And I press "Save changes"
+    Then I should see "User S5" in the "Activity results" "block"
+    And I should see "Not good enough" in the "Activity results" "block"
+    And I should see "User S4" in the "Activity results" "block"
+    And I should see "Average" in the "Activity results" "block"
+    And I should see "User S3" in the "Activity results" "block"
+    And I should see "Good" in the "Activity results" "block"
+
+  Scenario: Try to configure the block on the course page to show multiple low scores using anonymous names
+    Given I add the "Activity results" block
+    When I configure the "Activity results" block
+    And I set the following fields to these values:
+      | id_config_showbest | 0 |
+      | id_config_showworst | 3 |
+      | id_config_nameformat | Anonymous results |
+    And I press "Save changes"
+    Then I should see "User" in the "Activity results" "block"
+    And I should not see "Student 5" in the "Activity results" "block"
+    And I should see "Not good enough" in the "Activity results" "block"
+    And I should not see "Student 4" in the "Activity results" "block"
+    And I should see "Average" in the "Activity results" "block"
+    And I should not see "Student 3" in the "Activity results" "block"
+    And I should see "Good" in the "Activity results" "block"
diff --git a/blocks/activity_results/tests/behat/lowscoreswithscalesandgroups.feature b/blocks/activity_results/tests/behat/lowscoreswithscalesandgroups.feature
new file mode 100644 (file)
index 0000000..9134339
--- /dev/null
@@ -0,0 +1,150 @@
+@block @block_activity_results
+Feature: The activity results block displays student scores as scales
+  In order to be display student scores as scales
+  As a user
+  I need to see the activity results block
+
+  Background:
+    Given the following "users" exist:
+      | username | firstname | lastname | email | idnumber |
+      | teacher1 | Teacher | 1 | teacher1@example.com | T1 |
+      | student1 | Student | 1 | student1@example.com | S1 |
+      | student2 | Student | 2 | student2@example.com | S2 |
+      | student3 | Student | 3 | student3@example.com | S3 |
+      | student4 | Student | 4 | student4@example.com | S4 |
+      | student5 | Student | 5 | student5@example.com | S5 |
+      | student6 | Student | 6 | student6@example.com | S6 |
+    And the following "courses" exist:
+      | fullname | shortname | category |
+      | Course 1 | C1 | 0 |
+    And the following "groups" exist:
+      | name | course | idnumber |
+      | Group 1 | C1 | G1 |
+      | Group 2 | C1 | G2 |
+      | Group 3 | C1 | G3 |
+      | Group 4 | C1 | G4 |
+      | Group 5 | C1 | G5 |
+    And the following "course enrolments" exist:
+      | user | course | role |
+      | teacher1 | C1 | editingteacher |
+      | student1 | C1 | student |
+      | student2 | C1 | student |
+      | student3 | C1 | student |
+      | student4 | C1 | student |
+      | student5 | C1 | student |
+      | student6 | C1 | student |
+    And the following "group members" exist:
+      | user     | group   |
+      | student1 | G1 |
+      | student2 | G1 |
+      | student3 | G2 |
+      | student4 | G2 |
+      | student5 | G3 |
+      | student6 | G3 |
+    And I log in as "teacher1"
+    And I follow "Course 1"
+    And I navigate to "Grades" node in "Course administration"
+    And I navigate to "Scales" node in "Grade administration"
+    And I press "Add a new scale"
+    And I set the following fields to these values:
+      | Name | My Scale |
+      | Scale | Disappointing, Not good enough, Average, Good, Very good, Excellent! |
+    And I press "Save changes"
+    And I follow "Course 1"
+    And I turn editing mode on
+    And I add a "Assignment" to section "1" and I fill the form with:
+      | Assignment name | Test assignment |
+      | Description | Offline text |
+      | assignsubmission_file_enabled | 0 |
+      | id_modgrade_type | Scale |
+      | id_modgrade_scale | My Scale |
+      | Group mode | Separate groups |
+    And I follow "Course 1"
+    And I navigate to "Grades" node in "Course administration"
+    And I turn editing mode on
+    And I give the grade "Excellent!" to the user "Student 1" for the grade item "Test assignment"
+    And I give the grade "Very good" to the user "Student 2" for the grade item "Test assignment"
+    And I give the grade "Very good" to the user "Student 3" for the grade item "Test assignment"
+    And I give the grade "Good" to the user "Student 4" for the grade item "Test assignment"
+    And I give the grade "Good" to the user "Student 5" for the grade item "Test assignment"
+    And I give the grade "Average" to the user "Student 6" for the grade item "Test assignment"
+    And I press "Save changes"
+    And I follow "Course 1"
+
+  Scenario: Try to configure the block on the course page to show 1 low score
+    Given I add the "Activity results" block
+    When I configure the "Activity results" block
+    And I set the following fields to these values:
+      | id_config_showbest | 0 |
+      | id_config_showworst | 1 |
+      | id_config_nameformat | Display full names |
+      | id_config_usegroups | Yes |
+    And I press "Save changes"
+    Then I should see "Group 3" in the "Activity results" "block"
+    And I should see "Good" in the "Activity results" "block"
+    And I log out
+    And I log in as "student5"
+    And I follow "Course 1"
+    And I should see "Student 6" in the "Activity results" "block"
+    And I should see "Average" in the "Activity results" "block"
+
+  Scenario: Try to configure the block on the course page to show multiple high scores using full names
+    Given I add the "Activity results" block
+    When I configure the "Activity results" block
+    And I set the following fields to these values:
+      | id_config_showbest | 0 |
+      | id_config_showworst | 2 |
+      | id_config_nameformat | Display full names |
+      | id_config_usegroups | Yes |
+    And I press "Save changes"
+    Then I should see "Group 2" in the "Activity results" "block"
+    And I should see "Very good" in the "Activity results" "block"
+    And I should see "Group 3" in the "Activity results" "block"
+    And I should see "Good" in the "Activity results" "block"
+    And I log out
+    And I log in as "student3"
+    And I follow "Course 1"
+    And I should see "Student 3" in the "Activity results" "block"
+    And I should see "Very good" in the "Activity results" "block"
+    And I should see "Student 4" in the "Activity results" "block"
+    And I should see "Good" in the "Activity results" "block"
+
+  Scenario: Try to configure the block on the course page to show multiple high scores using ID numbers
+    Given I add the "Activity results" block
+    When I configure the "Activity results" block
+    And I set the following fields to these values:
+      | id_config_showbest | 0 |
+      | id_config_showworst | 2 |
+      | id_config_nameformat | Display only ID numbers |
+      | id_config_usegroups | Yes |
+    And I press "Save changes"
+    Then I should see "Group" in the "Activity results" "block"
+    And I should see "Very good" in the "Activity results" "block"
+    And I should see "Good" in the "Activity results" "block"
+    And I log out
+    And I log in as "student5"
+    And I follow "Course 1"
+    And I should see "User S5" in the "Activity results" "block"
+    And I should see "Good" in the "Activity results" "block"
+    And I should see "User S6" in the "Activity results" "block"
+    And I should see "Average" in the "Activity results" "block"
+
+  Scenario: Try to configure the block on the course page to show multiple high scores using anonymous names
+    Given I add the "Activity results" block
+    When I configure the "Activity results" block
+    And I set the following fields to these values:
+      | id_config_showbest | 0 |
+      | id_config_showworst | 2 |
+      | id_config_nameformat | Anonymous results |
+      | id_config_usegroups | Yes |
+    And I press "Save changes"
+    Then I should see "Group" in the "Activity results" "block"
+    And I should see "Very good" in the "Activity results" "block"
+    And I should see "Good" in the "Activity results" "block"
+    And I log out
+    And I log in as "student5"
+    And I follow "Course 1"
+    And I should see "User" in the "Activity results" "block"
+    And I should see "Good" in the "Activity results" "block"
+    And I should see "Average" in the "Activity results" "block"
+
index f18ccf8..b5e0546 100644 (file)
@@ -33,19 +33,15 @@ Feature: The activity results block displays student scores
       | student4 | C1 | student |
       | student5 | C1 | student |
       | student6 | C1 | student |
-
-  @javascript
-  Scenario: Configure the block on the course page to show 1 low score
-    Given I log in as "teacher1"
-    And I follow "Course 1"
-    And I expand "Users" node
-    And I follow "Groups"
-    And I add "Student 1 (student1@example.com)" user to "Group 1" group members
-    And I add "Student 2 (student2@example.com)" user to "Group 1" group members
-    And I add "Student 3 (student3@example.com)" user to "Group 2" group members
-    And I add "Student 4 (student4@example.com)" user to "Group 2" group members
-    And I add "Student 5 (student5@example.com)" user to "Group 3" group members
-    And I add "Student 6 (student6@example.com)" user to "Group 3" group members
+    And the following "group members" exist:
+      | user     | group   |
+      | student1 | G1 |
+      | student2 | G1 |
+      | student3 | G2 |
+      | student4 | G2 |
+      | student5 | G3 |
+      | student6 | G3 |
+    And I log in as "teacher1"
     And I follow "Course 1"
     And I turn editing mode on
     And I add a "Assignment" to section "1" and I fill the form with:
@@ -64,7 +60,9 @@ Feature: The activity results block displays student scores
     And I give the grade "70.00" to the user "Student 6" for the grade item "Test assignment"
     And I press "Save changes"
     And I follow "Course 1"
-    And I add the "Activity results" block
+
+  Scenario: Configure the block on the course page to show 1 low score
+    Given I add the "Activity results" block
     When I configure the "Activity results" block
     And I set the following fields to these values:
       | id_config_showbest | 0 |
@@ -77,37 +75,8 @@ Feature: The activity results block displays student scores
     Then I should see "Group 3" in the "Activity results" "block"
     And I should see "75%" in the "Activity results" "block"
 
-  @javascript
   Scenario: Try to configure the block on the course page to show 1 low score as a fraction
-    Given I log in as "teacher1"
-    And I follow "Course 1"
-    And I expand "Users" node
-    And I follow "Groups"
-    And I add "Student 1 (student1@example.com)" user to "Group 1" group members
-    And I add "Student 2 (student2@example.com)" user to "Group 1" group members
-    And I add "Student 3 (student3@example.com)" user to "Group 2" group members
-    And I add "Student 4 (student4@example.com)" user to "Group 2" group members
-    And I add "Student 5 (student5@example.com)" user to "Group 3" group members
-    And I add "Student 6 (student6@example.com)" user to "Group 3" group members
-    And I follow "Course 1"
-    And I turn editing mode on
-    And I add a "Assignment" to section "1" and I fill the form with:
-      | Assignment name | Test assignment |
-      | Description | Offline text |
-      | assignsubmission_file_enabled | 0 |
-      | Group mode | Separate groups |
-    And I follow "Course 1"
-    And I navigate to "Grades" node in "Course administration"
-    And I turn editing mode on
-    And I give the grade "100.00" to the user "Student 1" for the grade item "Test assignment"
-    And I give the grade "90.00" to the user "Student 2" for the grade item "Test assignment"
-    And I give the grade "90.00" to the user "Student 3" for the grade item "Test assignment"
-    And I give the grade "80.00" to the user "Student 4" for the grade item "Test assignment"
-    And I give the grade "80.00" to the user "Student 5" for the grade item "Test assignment"
-    And I give the grade "70.00" to the user "Student 6" for the grade item "Test assignment"
-    And I press "Save changes"
-    And I follow "Course 1"
-    And I add the "Activity results" block
+    Given I add the "Activity results" block
     When I configure the "Activity results" block
     And I set the following fields to these values:
       | id_config_showbest | 0 |
@@ -124,37 +93,8 @@ Feature: The activity results block displays student scores
     And I should see "Student 6" in the "Activity results" "block"
     And I should see "70.00/100.00" in the "Activity results" "block"
 
-  @javascript
   Scenario: Try to configure the block on the course page to show 1 low score as a absolute numbers
-    Given I log in as "teacher1"
-    And I follow "Course 1"
-    And I expand "Users" node
-    And I follow "Groups"
-    And I add "Student 1 (student1@example.com)" user to "Group 1" group members
-    And I add "Student 2 (student2@example.com)" user to "Group 1" group members
-    And I add "Student 3 (student3@example.com)" user to "Group 2" group members
-    And I add "Student 4 (student4@example.com)" user to "Group 2" group members
-    And I add "Student 5 (student5@example.com)" user to "Group 3" group members
-    And I add "Student 6 (student6@example.com)" user to "Group 3" group members
-    And I follow "Course 1"
-    And I turn editing mode on
-    And I add a "Assignment" to section "1" and I fill the form with:
-      | Assignment name | Test assignment |
-      | Description | Offline text |
-      | assignsubmission_file_enabled | 0 |
-      | Group mode | Separate groups |
-    And I follow "Course 1"
-    And I navigate to "Grades" node in "Course administration"
-    And I turn editing mode on
-    And I give the grade "100.00" to the user "Student 1" for the grade item "Test assignment"
-    And I give the grade "90.00" to the user "Student 2" for the grade item "Test assignment"
-    And I give the grade "90.00" to the user "Student 3" for the grade item "Test assignment"
-    And I give the grade "80.00" to the user "Student 4" for the grade item "Test assignment"
-    And I give the grade "80.00" to the user "Student 5" for the grade item "Test assignment"
-    And I give the grade "70.00" to the user "Student 6" for the grade item "Test assignment"
-    And I press "Save changes"
-    And I follow "Course 1"
-    And I add the "Activity results" block
+    Given I add the "Activity results" block
     When I configure the "Activity results" block
     And I set the following fields to these values:
       | id_config_showbest | 0 |
@@ -171,37 +111,8 @@ Feature: The activity results block displays student scores
     And I should see "Student 6" in the "Activity results" "block"
     And I should see "70.00" in the "Activity results" "block"
 
-  @javascript
   Scenario: Try to configure the block on the course page to show multiple low scores as percentages
-    Given I log in as "teacher1"
-    And I follow "Course 1"
-    And I expand "Users" node
-    And I follow "Groups"
-    And I add "Student 1 (student1@example.com)" user to "Group 1" group members
-    And I add "Student 2 (student2@example.com)" user to "Group 1" group members
-    And I add "Student 3 (student3@example.com)" user to "Group 2" group members
-    And I add "Student 4 (student4@example.com)" user to "Group 2" group members
-    And I add "Student 5 (student5@example.com)" user to "Group 3" group members
-    And I add "Student 6 (student6@example.com)" user to "Group 3" group members
-    And I follow "Course 1"
-    And I turn editing mode on
-    And I add a "Assignment" to section "1" and I fill the form with:
-      | Assignment name | Test assignment |
-      | Description | Offline text |
-      | assignsubmission_file_enabled | 0 |
-      | Group mode | Separate groups |
-    And I follow "Course 1"
-    And I navigate to "Grades" node in "Course administration"
-    And I turn editing mode on
-    And I give the grade "100.00" to the user "Student 1" for the grade item "Test assignment"
-    And I give the grade "90.00" to the user "Student 2" for the grade item "Test assignment"
-    And I give the grade "90.00" to the user "Student 3" for the grade item "Test assignment"
-    And I give the grade "80.00" to the user "Student 4" for the grade item "Test assignment"
-    And I give the grade "80.00" to the user "Student 5" for the grade item "Test assignment"
-    And I give the grade "70.00" to the user "Student 6" for the grade item "Test assignment"
-    And I press "Save changes"
-    And I follow "Course 1"
-    And I add the "Activity results" block
+    Given I add the "Activity results" block
     When I configure the "Activity results" block
     And I set the following fields to these values:
       | id_config_showbest | 0 |
@@ -223,37 +134,8 @@ Feature: The activity results block displays student scores
     And I should see "Student 5" in the "Activity results" "block"
     And I should see "80%" in the "Activity results" "block"
 
-  @javascript
   Scenario: Try to configure the block on the course page to show multiple low scores as fractions
-    Given I log in as "teacher1"
-    And I follow "Course 1"
-    And I expand "Users" node
-    And I follow "Groups"
-    And I add "Student 1 (student1@example.com)" user to "Group 1" group members
-    And I add "Student 2 (student2@example.com)" user to "Group 1" group members
-    And I add "Student 3 (student3@example.com)" user to "Group 2" group members
-    And I add "Student 4 (student4@example.com)" user to "Group 2" group members
-    And I add "Student 5 (student5@example.com)" user to "Group 3" group members
-    And I add "Student 6 (student6@example.com)" user to "Group 3" group members
-    And I follow "Course 1"
-    And I turn editing mode on
-    And I add a "Assignment" to section "1" and I fill the form with:
-      | Assignment name | Test assignment |
-      | Description | Offline text |
-      | assignsubmission_file_enabled | 0 |
-      | Group mode | Separate groups |
-    And I follow "Course 1"
-    And I navigate to "Grades" node in "Course administration"
-    And I turn editing mode on
-    And I give the grade "100.00" to the user "Student 1" for the grade item "Test assignment"
-    And I give the grade "90.00" to the user "Student 2" for the grade item "Test assignment"
-    And I give the grade "90.00" to the user "Student 3" for the grade item "Test assignment"
-    And I give the grade "80.00" to the user "Student 4" for the grade item "Test assignment"
-    And I give the grade "80.00" to the user "Student 5" for the grade item "Test assignment"
-    And I give the grade "70.00" to the user "Student 6" for the grade item "Test assignment"
-    And I press "Save changes"
-    And I follow "Course 1"
-    And I add the "Activity results" block
+    Given I add the "Activity results" block
     When I configure the "Activity results" block
     And I set the following fields to these values:
       | id_config_showbest | 0 |
@@ -274,37 +156,8 @@ Feature: The activity results block displays student scores
     And I should see "Student 4" in the "Activity results" "block"
     And I should see "80.00/100.00" in the "Activity results" "block"
 
-  @javascript
   Scenario: Try to configure the block on the course page to show multiple low scores as absolute numbers
-    Given I log in as "teacher1"
-    And I follow "Course 1"
-    And I expand "Users" node
-    And I follow "Groups"
-    And I add "Student 1 (student1@example.com)" user to "Group 1" group members
-    And I add "Student 2 (student2@example.com)" user to "Group 1" group members
-    And I add "Student 3 (student3@example.com)" user to "Group 2" group members
-    And I add "Student 4 (student4@example.com)" user to "Group 2" group members
-    And I add "Student 5 (student5@example.com)" user to "Group 3" group members
-    And I add "Student 6 (student6@example.com)" user to "Group 3" group members
-    And I follow "Course 1"
-    And I turn editing mode on
-    And I add a "Assignment" to section "1" and I fill the form with:
-      | Assignment name | Test assignment |
-      | Description | Offline text |
-      | assignsubmission_file_enabled | 0 |
-      | Group mode | Separate groups |
-    And I follow "Course 1"
-    And I navigate to "Grades" node in "Course administration"
-    And I turn editing mode on
-    And I give the grade "100.00" to the user "Student 1" for the grade item "Test assignment"
-    And I give the grade "90.00" to the user "Student 2" for the grade item "Test assignment"
-    And I give the grade "90.00" to the user "Student 3" for the grade item "Test assignment"
-    And I give the grade "80.00" to the user "Student 4" for the grade item "Test assignment"
-    And I give the grade "80.00" to the user "Student 5" for the grade item "Test assignment"
-    And I give the grade "70.00" to the user "Student 6" for the grade item "Test assignment"
-    And I press "Save changes"
-    And I follow "Course 1"
-    And I add the "Activity results" block
+    Given I add the "Activity results" block
     When I configure the "Activity results" block
     And I set the following fields to these values:
       | id_config_showbest | 0 |
@@ -325,37 +178,8 @@ Feature: The activity results block displays student scores
     And I should see "Student 6" in the "Activity results" "block"
     And I should see "70.00" in the "Activity results" "block"
 
-  @javascript
   Scenario: Try to configure the block on the course page to show multiple low scores using ID numbers
-    Given I log in as "teacher1"
-    And I follow "Course 1"
-    And I expand "Users" node
-    And I follow "Groups"
-    And I add "Student 1 (student1@example.com)" user to "Group 1" group members
-    And I add "Student 2 (student2@example.com)" user to "Group 1" group members
-    And I add "Student 3 (student3@example.com)" user to "Group 2" group members
-    And I add "Student 4 (student4@example.com)" user to "Group 2" group members
-    And I add "Student 5 (student5@example.com)" user to "Group 3" group members
-    And I add "Student 6 (student6@example.com)" user to "Group 3" group members
-    And I follow "Course 1"
-    And I turn editing mode on
-    And I add a "Assignment" to section "1" and I fill the form with:
-      | Assignment name | Test assignment |
-      | Description | Offline text |
-      | assignsubmission_file_enabled | 0 |
-      | Group mode | Separate groups |
-    And I follow "Course 1"
-    And I navigate to "Grades" node in "Course administration"
-    And I turn editing mode on
-    And I give the grade "100.00" to the user "Student 1" for the grade item "Test assignment"
-    And I give the grade "90.00" to the user "Student 2" for the grade item "Test assignment"
-    And I give the grade "90.00" to the user "Student 3" for the grade item "Test assignment"
-    And I give the grade "80.00" to the user "Student 4" for the grade item "Test assignment"
-    And I give the grade "80.00" to the user "Student 5" for the grade item "Test assignment"
-    And I give the grade "70.00" to the user "Student 6" for the grade item "Test assignment"
-    And I press "Save changes"
-    And I follow "Course 1"
-    And I add the "Activity results" block
+    Given I add the "Activity results" block
     When I configure the "Activity results" block
     And I set the following fields to these values:
       | id_config_showbest | 0 |
@@ -375,37 +199,8 @@ Feature: The activity results block displays student scores
     And I should see "User S2" in the "Activity results" "block"
     And I should see "90.00%" in the "Activity results" "block"
 
-  @javascript
   Scenario: Try to configure the block on the course page to show multiple low scores using anonymous names
-    Given I log in as "teacher1"
-    And I follow "Course 1"
-    And I expand "Users" node
-    And I follow "Groups"
-    And I add "Student 1 (student1@example.com)" user to "Group 1" group members
-    And I add "Student 2 (student2@example.com)" user to "Group 1" group members
-    And I add "Student 3 (student3@example.com)" user to "Group 2" group members
-    And I add "Student 4 (student4@example.com)" user to "Group 2" group members
-    And I add "Student 5 (student5@example.com)" user to "Group 3" group members
-    And I add "Student 6 (student6@example.com)" user to "Group 3" group members
-    And I follow "Course 1"
-    And I turn editing mode on
-    And I add a "Assignment" to section "1" and I fill the form with:
-      | Assignment name | Test assignment |
-      | Description | Offline text |
-      | assignsubmission_file_enabled | 0 |
-      | Group mode | Separate groups |
-    And I follow "Course 1"
-    And I navigate to "Grades" node in "Course administration"
-    And I turn editing mode on
-    And I give the grade "100.00" to the user "Student 1" for the grade item "Test assignment"
-    And I give the grade "90.00" to the user "Student 2" for the grade item "Test assignment"
-    And I give the grade "90.00" to the user "Student 3" for the grade item "Test assignment"
-    And I give the grade "80.00" to the user "Student 4" for the grade item "Test assignment"
-    And I give the grade "80.00" to the user "Student 5" for the grade item "Test assignment"
-    And I give the grade "70.00" to the user "Student 6" for the grade item "Test assignment"
-    And I press "Save changes"
-    And I follow "Course 1"
-    And I add the "Activity results" block
+    Given I add the "Activity results" block
     When I configure the "Activity results" block
     And I set the following fields to these values:
       | id_config_showbest | 0 |
index e02d58d..7049958 100644 (file)
@@ -33,19 +33,15 @@ Feature: The activity results block displays student scores
       | student4 | C1 | student |
       | student5 | C1 | student |
       | student6 | C1 | student |
-
-  @javascript
-  Scenario: Configure the block on the course page to show 1 low score
-    Given I log in as "teacher1"
-    And I follow "Course 1"
-    And I expand "Users" node
-    And I follow "Groups"
-    And I add "Student 1 (student1@example.com)" user to "Group 1" group members
-    And I add "Student 2 (student2@example.com)" user to "Group 1" group members
-    And I add "Student 3 (student3@example.com)" user to "Group 2" group members
-    And I add "Student 4 (student4@example.com)" user to "Group 2" group members
-    And I add "Student 5 (student5@example.com)" user to "Group 3" group members
-    And I add "Student 6 (student6@example.com)" user to "Group 3" group members
+    And the following "group members" exist:
+      | user     | group   |
+      | student1 | G1 |
+      | student2 | G1 |
+      | student3 | G2 |
+      | student4 | G2 |
+      | student5 | G3 |
+      | student6 | G3 |
+    And I log in as "teacher1"
     And I follow "Course 1"
     And I turn editing mode on
     And I add a "Assignment" to section "1" and I fill the form with:
@@ -64,7 +60,9 @@ Feature: The activity results block displays student scores
     And I give the grade "70.00" to the user "Student 6" for the grade item "Test assignment"
     And I press "Save changes"
     And I follow "Course 1"
-    And I add the "Activity results" block
+
+  Scenario: Configure the block on the course page to show 1 low score
+    Given I add the "Activity results" block
     When I configure the "Activity results" block
     And I set the following fields to these values:
       | id_config_showbest | 0 |
@@ -77,37 +75,8 @@ Feature: The activity results block displays student scores
     Then I should see "Group 3" in the "Activity results" "block"
     And I should see "75%" in the "Activity results" "block"
 
-  @javascript
   Scenario: Try to configure the block on the course page to show 1 low score as a fraction
-    Given I log in as "teacher1"
-    And I follow "Course 1"
-    And I expand "Users" node
-    And I follow "Groups"
-    And I add "Student 1 (student1@example.com)" user to "Group 1" group members
-    And I add "Student 2 (student2@example.com)" user to "Group 1" group members
-    And I add "Student 3 (student3@example.com)" user to "Group 2" group members
-    And I add "Student 4 (student4@example.com)" user to "Group 2" group members
-    And I add "Student 5 (student5@example.com)" user to "Group 3" group members
-    And I add "Student 6 (student6@example.com)" user to "Group 3" group members
-    And I follow "Course 1"
-    And I turn editing mode on
-    And I add a "Assignment" to section "1" and I fill the form with:
-      | Assignment name | Test assignment |
-      | Description | Offline text |
-      | assignsubmission_file_enabled | 0 |
-      | Group mode | Visible groups |
-    And I follow "Course 1"
-    And I navigate to "Grades" node in "Course administration"
-    And I turn editing mode on
-    And I give the grade "100.00" to the user "Student 1" for the grade item "Test assignment"
-    And I give the grade "90.00" to the user "Student 2" for the grade item "Test assignment"
-    And I give the grade "90.00" to the user "Student 3" for the grade item "Test assignment"
-    And I give the grade "80.00" to the user "Student 4" for the grade item "Test assignment"
-    And I give the grade "80.00" to the user "Student 5" for the grade item "Test assignment"
-    And I give the grade "70.00" to the user "Student 6" for the grade item "Test assignment"
-    And I press "Save changes"
-    And I follow "Course 1"
-    And I add the "Activity results" block
+    Given I add the "Activity results" block
     When I configure the "Activity results" block
     And I set the following fields to these values:
       | id_config_showbest | 0 |
@@ -122,37 +91,8 @@ Feature: The activity results block displays student scores
     And I should see "Group 3" in the "Activity results" "block"
     And I should see "75.00/100.00" in the "Activity results" "block"
 
-  @javascript
   Scenario: Try to configure the block on the course page to show 1 low score as a absolute numbers
-    Given I log in as "teacher1"
-    And I follow "Course 1"
-    And I expand "Users" node
-    And I follow "Groups"
-    And I add "Student 1 (student1@example.com)" user to "Group 1" group members
-    And I add "Student 2 (student2@example.com)" user to "Group 1" group members
-    And I add "Student 3 (student3@example.com)" user to "Group 2" group members
-    And I add "Student 4 (student4@example.com)" user to "Group 2" group members
-    And I add "Student 5 (student5@example.com)" user to "Group 3" group members
-    And I add "Student 6 (student6@example.com)" user to "Group 3" group members
-    And I follow "Course 1"
-    And I turn editing mode on
-    And I add a "Assignment" to section "1" and I fill the form with:
-      | Assignment name | Test assignment |
-      | Description | Offline text |
-      | assignsubmission_file_enabled | 0 |
-      | Group mode | Visible groups |
-    And I follow "Course 1"
-    And I navigate to "Grades" node in "Course administration"
-    And I turn editing mode on
-    And I give the grade "100.00" to the user "Student 1" for the grade item "Test assignment"
-    And I give the grade "90.00" to the user "Student 2" for the grade item "Test assignment"
-    And I give the grade "90.00" to the user "Student 3" for the grade item "Test assignment"
-    And I give the grade "80.00" to the user "Student 4" for the grade item "Test assignment"
-    And I give the grade "80.00" to the user "Student 5" for the grade item "Test assignment"
-    And I give the grade "70.00" to the user "Student 6" for the grade item "Test assignment"
-    And I press "Save changes"
-    And I follow "Course 1"
-    And I add the "Activity results" block
+    Given I add the "Activity results" block
     When I configure the "Activity results" block
     And I set the following fields to these values:
       | id_config_showbest | 0 |
@@ -167,37 +107,8 @@ Feature: The activity results block displays student scores
     And I should see "Group 3" in the "Activity results" "block"
     And I should see "75.00" in the "Activity results" "block"
 
-  @javascript
   Scenario: Try to configure the block on the course page to show multiple low scores as percentages
-    Given I log in as "teacher1"
-    And I follow "Course 1"
-    And I expand "Users" node
-    And I follow "Groups"
-    And I add "Student 1 (student1@example.com)" user to "Group 1" group members
-    And I add "Student 2 (student2@example.com)" user to "Group 1" group members
-    And I add "Student 3 (student3@example.com)" user to "Group 2" group members
-    And I add "Student 4 (student4@example.com)" user to "Group 2" group members
-    And I add "Student 5 (student5@example.com)" user to "Group 3" group members
-    And I add "Student 6 (student6@example.com)" user to "Group 3" group members
-    And I follow "Course 1"
-    And I turn editing mode on
-    And I add a "Assignment" to section "1" and I fill the form with:
-      | Assignment name | Test assignment |
-      | Description | Offline text |
-      | assignsubmission_file_enabled | 0 |
-      | Group mode | Visible groups |
-    And I follow "Course 1"
-    And I navigate to "Grades" node in "Course administration"
-    And I turn editing mode on
-    And I give the grade "100.00" to the user "Student 1" for the grade item "Test assignment"
-    And I give the grade "90.00" to the user "Student 2" for the grade item "Test assignment"
-    And I give the grade "90.00" to the user "Student 3" for the grade item "Test assignment"
-    And I give the grade "80.00" to the user "Student 4" for the grade item "Test assignment"
-    And I give the grade "80.00" to the user "Student 5" for the grade item "Test assignment"
-    And I give the grade "70.00" to the user "Student 6" for the grade item "Test assignment"
-    And I press "Save changes"
-    And I follow "Course 1"
-    And I add the "Activity results" block
+    Given I add the "Activity results" block
     When I configure the "Activity results" block
     And I set the following fields to these values:
       | id_config_showbest | 0 |
@@ -219,37 +130,8 @@ Feature: The activity results block displays student scores
     And I should see "Group 3" in the "Activity results" "block"
     And I should see "75%" in the "Activity results" "block"
 
-  @javascript
   Scenario: Try to configure the block on the course page to show multiple low scores as fractions
-    Given I log in as "teacher1"
-    And I follow "Course 1"
-    And I expand "Users" node
-    And I follow "Groups"
-    And I add "Student 1 (student1@example.com)" user to "Group 1" group members
-    And I add "Student 2 (student2@example.com)" user to "Group 1" group members
-    And I add "Student 3 (student3@example.com)" user to "Group 2" group members
-    And I add "Student 4 (student4@example.com)" user to "Group 2" group members
-    And I add "Student 5 (student5@example.com)" user to "Group 3" group members
-    And I add "Student 6 (student6@example.com)" user to "Group 3" group members
-    And I follow "Course 1"
-    And I turn editing mode on
-    And I add a "Assignment" to section "1" and I fill the form with:
-      | Assignment name | Test assignment |
-      | Description | Offline text |
-      | assignsubmission_file_enabled | 0 |
-      | Group mode | Visible groups |
-    And I follow "Course 1"
-    And I navigate to "Grades" node in "Course administration"
-    And I turn editing mode on
-    And I give the grade "100.00" to the user "Student 1" for the grade item "Test assignment"
-    And I give the grade "90.00" to the user "Student 2" for the grade item "Test assignment"
-    And I give the grade "90.00" to the user "Student 3" for the grade item "Test assignment"
-    And I give the grade "80.00" to the user "Student 4" for the grade item "Test assignment"
-    And I give the grade "80.00" to the user "Student 5" for the grade item "Test assignment"
-    And I give the grade "70.00" to the user "Student 6" for the grade item "Test assignment"
-    And I press "Save changes"
-    And I follow "Course 1"
-    And I add the "Activity results" block
+    Given I add the "Activity results" block
     When I configure the "Activity results" block
     And I set the following fields to these values:
       | id_config_showbest | 0 |
@@ -266,37 +148,8 @@ Feature: The activity results block displays student scores
     And I should see "Group 3" in the "Activity results" "block"
     And I should see "75.00/100.00" in the "Activity results" "block"
 
-  @javascript
   Scenario: Try to configure the block on the course page to show multiple low scores as absolute numbers
-    Given I log in as "teacher1"
-    And I follow "Course 1"
-    And I expand "Users" node
-    And I follow "Groups"
-    And I add "Student 1 (student1@example.com)" user to "Group 1" group members
-    And I add "Student 2 (student2@example.com)" user to "Group 1" group members
-    And I add "Student 3 (student3@example.com)" user to "Group 2" group members
-    And I add "Student 4 (student4@example.com)" user to "Group 2" group members
-    And I add "Student 5 (student5@example.com)" user to "Group 3" group members
-    And I add "Student 6 (student6@example.com)" user to "Group 3" group members
-    And I follow "Course 1"
-    And I turn editing mode on
-    And I add a "Assignment" to section "1" and I fill the form with:
-      | Assignment name | Test assignment |
-      | Description | Offline text |
-      | assignsubmission_file_enabled | 0 |
-      | Group mode | Visible groups |
-    And I follow "Course 1"
-    And I navigate to "Grades" node in "Course administration"
-    And I turn editing mode on
-    And I give the grade "100.00" to the user "Student 1" for the grade item "Test assignment"
-    And I give the grade "90.00" to the user "Student 2" for the grade item "Test assignment"
-    And I give the grade "90.00" to the user "Student 3" for the grade item "Test assignment"
-    And I give the grade "80.00" to the user "Student 4" for the grade item "Test assignment"
-    And I give the grade "80.00" to the user "Student 5" for the grade item "Test assignment"
-    And I give the grade "70.00" to the user "Student 6" for the grade item "Test assignment"
-    And I press "Save changes"
-    And I follow "Course 1"
-    And I add the "Activity results" block
+    Given I add the "Activity results" block
     When I configure the "Activity results" block
     And I set the following fields to these values:
       | id_config_showbest | 0 |
@@ -313,37 +166,8 @@ Feature: The activity results block displays student scores
     And I should see "Group 3" in the "Activity results" "block"
     And I should see "75.00" in the "Activity results" "block"
 
-  @javascript
   Scenario: Try to configure the block on the course page to show multiple low scores using ID numbers
-    Given I log in as "teacher1"
-    And I follow "Course 1"
-    And I expand "Users" node
-    And I follow "Groups"
-    And I add "Student 1 (student1@example.com)" user to "Group 1" group members
-    And I add "Student 2 (student2@example.com)" user to "Group 1" group members
-    And I add "Student 3 (student3@example.com)" user to "Group 2" group members
-    And I add "Student 4 (student4@example.com)" user to "Group 2" group members
-    And I add "Student 5 (student5@example.com)" user to "Group 3" group members
-    And I add "Student 6 (student6@example.com)" user to "Group 3" group members
-    And I follow "Course 1"
-    And I turn editing mode on
-    And I add a "Assignment" to section "1" and I fill the form with:
-      | Assignment name | Test assignment |
-      | Description | Offline text |
-      | assignsubmission_file_enabled | 0 |
-      | Group mode | Visible groups |
-    And I follow "Course 1"
-    And I navigate to "Grades" node in "Course administration"
-    And I turn editing mode on
-    And I give the grade "100.00" to the user "Student 1" for the grade item "Test assignment"
-    And I give the grade "90.00" to the user "Student 2" for the grade item "Test assignment"
-    And I give the grade "90.00" to the user "Student 3" for the grade item "Test assignment"
-    And I give the grade "80.00" to the user "Student 4" for the grade item "Test assignment"
-    And I give the grade "80.00" to the user "Student 5" for the grade item "Test assignment"
-    And I give the grade "70.00" to the user "Student 6" for the grade item "Test assignment"
-    And I press "Save changes"
-    And I follow "Course 1"
-    And I add the "Activity results" block
+    Given I add the "Activity results" block
     When I configure the "Activity results" block
     And I set the following fields to these values:
       | id_config_showbest | 0 |
@@ -359,37 +183,8 @@ Feature: The activity results block displays student scores
     And I should see "85.00%" in the "Activity results" "block"
     And I should see "75.00%" in the "Activity results" "block"
 
-  @javascript
   Scenario: Try to configure the block on the course page to show multiple low scores using anonymous names
-    Given I log in as "teacher1"
-    And I follow "Course 1"
-    And I expand "Users" node
-    And I follow "Groups"
-    And I add "Student 1 (student1@example.com)" user to "Group 1" group members
-    And I add "Student 2 (student2@example.com)" user to "Group 1" group members
-    And I add "Student 3 (student3@example.com)" user to "Group 2" group members
-    And I add "Student 4 (student4@example.com)" user to "Group 2" group members
-    And I add "Student 5 (student5@example.com)" user to "Group 3" group members
-    And I add "Student 6 (student6@example.com)" user to "Group 3" group members
-    And I follow "Course 1"
-    And I turn editing mode on
-    And I add a "Assignment" to section "1" and I fill the form with:
-      | Assignment name | Test assignment |
-      | Description | Offline text |
-      | assignsubmission_file_enabled | 0 |
-      | Group mode | Visible groups |
-    And I follow "Course 1"
-    And I navigate to "Grades" node in "Course administration"
-    And I turn editing mode on
-    And I give the grade "100.00" to the user "Student 1" for the grade item "Test assignment"
-    And I give the grade "90.00" to the user "Student 2" for the grade item "Test assignment"
-    And I give the grade "90.00" to the user "Student 3" for the grade item "Test assignment"
-    And I give the grade "80.00" to the user "Student 4" for the grade item "Test assignment"
-    And I give the grade "80.00" to the user "Student 5" for the grade item "Test assignment"
-    And I give the grade "70.00" to the user "Student 6" for the grade item "Test assignment"
-    And I press "Save changes"
-    And I follow "Course 1"
-    And I add the "Activity results" block
+    Given I add the "Activity results" block
     When I configure the "Activity results" block
     And I set the following fields to these values:
       | id_config_showbest | 0 |
diff --git a/blocks/admin_bookmarks/tests/behat/bookmark_admin_pages.feature b/blocks/admin_bookmarks/tests/behat/bookmark_admin_pages.feature
new file mode 100644 (file)
index 0000000..1574fe8
--- /dev/null
@@ -0,0 +1,36 @@
+@block @block_admin_bookmarks
+Feature: Add a bookmarks to an admin pages
+  In order to speed up common tasks
+  As an admin
+  I need to add and access pages through bookmarks
+
+  Background:
+    Given I log in as "admin"
+    And I navigate to "Scheduled tasks" node in "Site administration > Server"
+    And I click on "Bookmark this page" "link" in the "Admin bookmarks" "block"
+    And I log out
+
+  # Test bookmark functionality using the "User profile fields" page as our bookmark.
+  Scenario: Admin page can be bookmarked
+    Given I log in as "admin"
+    And I navigate to "User profile fields" node in "Site administration > Users > Accounts"
+    When I click on "Bookmark this page" "link" in the "Admin bookmarks" "block"
+    Then I should see "User profile fields" in the "Admin bookmarks" "block"
+    # See the existing bookmark is there too.
+    And I should see "Scheduled tasks" in the "Admin bookmarks" "block"
+
+  Scenario: Admin page can be accessed through bookmarks block
+    Given I log in as "admin"
+    And I navigate to "Notifications" node in "Site administration"
+    And I click on "Scheduled tasks" "link" in the "Admin bookmarks" "block"
+    # Verify that we are on the right page.
+    Then I should see "Scheduled tasks" in the "h1" "css_element"
+
+  Scenario: Admin page can be removed from bookmarks
+    Given I log in as "admin"
+    And I navigate to "Notifications" node in "Site administration"
+    And I click on "Scheduled tasks" "link" in the "Admin bookmarks" "block"
+    When I click on "Unbookmark this page" "link" in the "Admin bookmarks" "block"
+    Then I should see "Bookmark deleted"
+    And I wait to be redirected
+    And I should not see "Scheduled tasks" in the "Admin bookmarks" "block"
diff --git a/blocks/blog_menu/tests/behat/block_blog_menu.feature b/blocks/blog_menu/tests/behat/block_blog_menu.feature
new file mode 100644 (file)
index 0000000..b93728f
--- /dev/null
@@ -0,0 +1,81 @@
+@block @block_blog_menu
+Feature: Enable Block blog menu in a course
+  In order to enable the blog menu in a course
+  As a teacher
+  I can add blog menu block to a course
+
+  Background:
+    Given the following "users" exist:
+      | username | firstname | lastname | email | idnumber |
+      | teacher1 | Teacher | 1 | teacher1@example.com | T1 |
+    And the following "courses" exist:
+      | fullname | shortname | category |
+      | Course 1 | C1 | 0 |
+    And the following "course enrolments" exist:
+      | user | course | role |
+      | teacher1 | C1 | editingteacher |
+
+  Scenario: Add the block to a the course when blogs are disabled
+    Given I log in as "admin"
+    And the following config values are set as admin:
+      | enableblogs | 0 |
+    And I log out
+    And I log in as "teacher1"
+    And I follow "Course 1"
+    And I turn editing mode on
+    When I add the "Blog menu" block
+    Then I should see "Blogging is disabled!" in the "Blog menu" "block"
+
+  Scenario: Add the block to a the course when blog associations are disabled
+    Given I log in as "admin"
+    And the following config values are set as admin:
+      | useblogassociations | 0 |
+    And I log out
+    And I log in as "teacher1"
+    And I follow "Course 1"
+    And I turn editing mode on
+    When I add the "Blog menu" block
+    Then I should see "Blog entries" in the "Blog menu" "block"
+    And I should see "Add a new entry" in the "Blog menu" "block"
+    And I should not see "View all entries for this course" in the "Blog menu" "block"
+    And I should not see "View my entries about this course" in the "Blog menu" "block"
+    And I should not see "Add an entry about this course" in the "Blog menu" "block"
+
+  Scenario: Add the block to a the course when blog associations are enabled
+    Given I log in as "admin"
+    And the following config values are set as admin:
+      | useblogassociations | 1 |
+    And I log out
+    And I log in as "teacher1"
+    And I follow "Course 1"
+    And I turn editing mode on
+    When I add the "Blog menu" block
+    Then I should see "Blog entries" in the "Blog menu" "block"
+    And I should see "Add a new entry" in the "Blog menu" "block"
+    And I should see "View all entries for this course" in the "Blog menu" "block"
+    And I should see "View my entries about this course" in the "Blog menu" "block"
+    And I should see "Add an entry about this course" in the "Blog menu" "block"
+
+  Scenario: Add the block to a the course when RSS is disabled
+    Given I log in as "admin"
+    And the following config values are set as admin:
+      | enablerssfeeds | 0 |
+    And I log out
+    And I log in as "teacher1"
+    And I follow "Course 1"
+    And I turn editing mode on
+    When I add the "Blog menu" block
+    Then I should not see "Blog RSS feed" in the "Blog menu" "block"
+    And I should see "Add a new entry" in the "Blog menu" "block"
+
+  Scenario: Add the block to a the course when RSS is enabled
+    Given I log in as "admin"
+    And the following config values are set as admin:
+      | enablerssfeeds | 1 |
+    And I log out
+    And I log in as "teacher1"
+    And I follow "Course 1"
+    And I turn editing mode on
+    When I add the "Blog menu" block
+    Then I should see "Blog RSS feed" in the "Blog menu" "block"
+    And I should see "Add a new entry" in the "Blog menu" "block"
diff --git a/blocks/blog_menu/tests/behat/block_blog_menu_course.feature b/blocks/blog_menu/tests/behat/block_blog_menu_course.feature
new file mode 100644 (file)
index 0000000..f45f62f
--- /dev/null
@@ -0,0 +1,199 @@
+@block @block_blog_menu
+Feature: Enable Block blog menu in a course
+  In order to enable the blog menu in a course
+  As a teacher
+  I can add blog menu block to a course
+
+  Background:
+    Given the following "users" exist:
+      | username | firstname | lastname | email | idnumber |
+      | teacher1 | Teacher | 1 | teacher1@example.com | T1 |
+      | student1 | Student | 1 | student1@example.com | S1 |
+      | student2 | Student | 2 | student2@example.com | S2 |
+    And the following "courses" exist:
+      | fullname | shortname | category |
+      | Course 1 | C1 | 0 |
+    And the following "course enrolments" exist:
+      | user | course | role |
+      | teacher1 | C1 | editingteacher |
+      | student1 | C1 | student |
+      | student2 | C1 | student |
+    And I log in as "teacher1"
+    And I follow "Course 1"
+    And I turn editing mode on
+    And I add the "Blog menu" block
+    And I log out
+
+  Scenario: Students use the blog menu block to post blogs
+    Given I log in as "student1"
+    And I follow "Course 1"
+    And I follow "Add a new entry"
+    When I set the following fields to these values:
+      | Entry title | S1 First Blog |
+      | Blog entry body | This is my awesome blog! |
+    And I press "Save changes"
+    Then I should see "S1 First Blog"
+    And I should see "This is my awesome blog!"
+    And I follow "Dashboard"
+    And I follow "Course 1"
+    And I follow "Blog entries"
+    And I should see "S1 First Blog"
+    And I should see "This is my awesome blog!"
+
+  Scenario: Students use the blog menu block to view their blogs about the course
+    Given I log in as "student1"
+    And I follow "Course 1"
+    And I follow "Add an entry about this course"
+    And I set the following fields to these values:
+      | Entry title | S1 First Blog |
+      | Blog entry body | This is my awesome blog about this course! |
+    And I press "Save changes"
+    And I should see "S1 First Blog"
+    And I should see "This is my awesome blog about this course!"
+    And I should see "Associated Course: C1"
+    And I log out
+    And I log in as "student2"
+    And I follow "Course 1"
+    And I follow "Add a new entry"
+    And I set the following fields to these values:
+      | Entry title | S2 Second Blog |
+      | Blog entry body | My unrelated blog! |
+    And I press "Save changes"
+    And I should see "S2 Second Blog"
+    And I should see "My unrelated blog!"
+    And I should not see "Associated Course: C1"
+    And I follow "Dashboard"
+    And I follow "Course 1"
+    And I follow "Add an entry about this course"
+    And I set the following fields to these values:
+      | Entry title | S2 First Blog |
+      | Blog entry body | My course blog is better! |
+    And I press "Save changes"
+    And I should see "S2 First Blog"
+    And I should see "My course blog is better!"
+    And I should see "Associated Course: C1"
+    And I follow "Dashboard"
+    And I follow "Course 1"
+    When I follow "View my entries about this course"
+    Then I should see "S2 First Blog"
+    And I should not see "S2 Second Blog"
+    And I should not see "S1 First Blog"
+
+  Scenario: Students use the blog menu block to view all blogs about the course
+    Given I log in as "student1"
+    And I follow "Course 1"
+    And I follow "Add an entry about this course"
+    And I set the following fields to these values:
+      | Entry title | S1 First Blog |
+      | Blog entry body | This is my awesome blog about this course! |
+    And I press "Save changes"
+    And I should see "S1 First Blog"
+    And I should see "This is my awesome blog about this course!"
+    And I should see "Associated Course: C1"
+    And I log out
+    And I log in as "student2"
+    And I follow "Course 1"
+    And I follow "Add a new entry"
+    And I set the following fields to these values:
+      | Entry title | S2 Second Blog |
+      | Blog entry body | My unrelated blog! |
+    And I press "Save changes"
+    And I should see "S2 Second Blog"
+    And I should see "My unrelated blog!"
+    And I should not see "Associated Course: C1"
+    And I follow "Dashboard"
+    And I follow "Course 1"
+    And I follow "Add an entry about this course"
+    And I set the following fields to these values:
+      | Entry title | S2 First Blog |
+      | Blog entry body | My course blog is better! |
+    And I press "Save changes"
+    And I should see "S2 First Blog"
+    And I should see "My course blog is better!"
+    And I should see "Associated Course: C1"
+    And I follow "Dashboard"
+    And I follow "Course 1"
+    When I follow "View all entries for this course"
+    Then I should see "S1 First Blog"
+    And I should see "S2 First Blog"
+    And I should not see "S2 Second Blog"
+
+  Scenario: Students use the blog menu block to view all their blog entries
+    Given I log in as "student1"
+    And I follow "Course 1"
+    And I follow "Add an entry about this course"
+    And I set the following fields to these values:
+      | Entry title | S1 First Blog |
+      | Blog entry body | This is my awesome blog about this course! |
+    And I press "Save changes"
+    And I should see "S1 First Blog"
+    And I should see "This is my awesome blog about this course!"
+    And I should see "Associated Course: C1"
+    And I log out
+    And I log in as "student2"
+    And I follow "Course 1"
+    And I follow "Add a new entry"
+    And I set the following fields to these values:
+      | Entry title | S2 Second Blog |
+      | Blog entry body | My unrelated blog! |
+    And I press "Save changes"
+    And I should see "S2 Second Blog"
+    And I should see "My unrelated blog!"
+    And I should not see "Associated Course: C1"
+    And I follow "Dashboard"
+    And I follow "Course 1"
+    And I follow "Add an entry about this course"
+    And I set the following fields to these values:
+      | Entry title | S2 First Blog |
+      | Blog entry body | My course blog is better! |
+    And I press "Save changes"
+    And I should see "S2 First Blog"
+    And I should see "My course blog is better!"
+    And I should see "Associated Course: C1"
+    And I follow "Dashboard"
+    And I follow "Course 1"
+    When I follow "Blog entries"
+    Then I should see "S2 First Blog"
+    And I should see "S2 Second Blog"
+    And I should not see "S1 First Blog"
+
+  Scenario: Teacher searches for student blogs
+    Given I log in as "student1"
+    And I follow "Course 1"
+    And I follow "Add an entry about this course"
+    And I set the following fields to these values:
+      | Entry title | S1 First Blog |
+      | Blog entry body | This is my awesome blog about this course! |
+    And I press "Save changes"
+    And I should see "S1 First Blog"
+    And I should see "This is my awesome blog about this course!"
+    And I should see "Associated Course: C1"
+    And I log out
+    And I log in as "student2"
+    And I follow "Course 1"
+    And I follow "Add a new entry"
+    And I set the following fields to these values:
+      | Entry title | S2 Second Blog |
+      | Blog entry body | My unrelated blog! |
+    And I press "Save changes"
+    And I should see "S2 Second Blog"
+    And I should see "My unrelated blog!"
+    And I should not see "Associated Course: C1"
+    And I follow "Dashboard"
+    And I follow "Course 1"
+    And I follow "Add an entry about this course"
+    And I set the following fields to these values:
+      | Entry title | S2 First Blog |
+      | Blog entry body | My course blog is better! |
+    And I press "Save changes"
+    And I should see "S2 First Blog"
+    And I should see "My course blog is better!"
+    And I should see "Associated Course: C1"
+    And I log out
+    When I log in as "teacher1"
+    And I follow "Course 1"
+    And I set the field "blogsearchquery" to "First"
+    And I press "Search"
+    Then I should see "S1 First Blog"
+    And I should see "S2 First Blog"
+    And I should not see "S2 Second Blog"
diff --git a/blocks/blog_menu/tests/behat/block_blog_menu_frontpage.feature b/blocks/blog_menu/tests/behat/block_blog_menu_frontpage.feature
new file mode 100644 (file)
index 0000000..3c2936a
--- /dev/null
@@ -0,0 +1,30 @@
+@block @block_blog_menu
+Feature: Enable Block blog menu on the frontpage
+  In order to enable the blog menu on the frontpage
+  As an admin
+  I can add blog menu block to the frontpage
+
+  Background:
+    Given the following "users" exist:
+      | username | firstname | lastname | email | idnumber |
+      | student1 | Student | 1 | student1@example.com | S1 |
+    And I log in as "admin"
+    And I am on site homepage
+    And I navigate to "Turn editing on" node in "Front page settings"
+    And I add the "Blog menu" block
+    And I log out
+
+  Scenario: Students use the blog menu block to post blogs
+    Given I log in as "student1"
+    And I am on site homepage
+    And I follow "Add a new entry"
+    When I set the following fields to these values:
+      | Entry title | S1 First Blog |
+      | Blog entry body | This is my awesome blog! |
+    And I press "Save changes"
+    Then I should see "S1 First Blog"
+    And I should see "This is my awesome blog!"
+    And I am on site homepage
+    And I follow "Blog entries"
+    And I should see "S1 First Blog"
+    And I should see "This is my awesome blog!"
index de32984..6edc7b5 100644 (file)
@@ -75,7 +75,7 @@ class block_blog_tags extends block_base {
             }
             return $this->content;
 
-        } else if (empty($CFG->usetags)) {
+        } else if (!core_tag_tag::is_enabled('core', 'post')) {
             $this->content = new stdClass();
             $this->content->text = '';
             if ($this->page->user_is_editing()) {
@@ -126,6 +126,7 @@ class block_blog_tags extends block_base {
                   WHERE t.id = ti.tagid AND p.id = ti.itemid
                         $type
                         AND ti.itemtype = 'post'
+                        AND ti.component = 'core'
                         AND ti.timemodified > $timewithin";
 
         if ($context->contextlevel == CONTEXT_MODULE) {
@@ -195,7 +196,9 @@ class block_blog_tags extends block_base {
                 }
 
                 $blogurl->param('tagid', $tag->id);
-                $link = html_writer::link($blogurl, tag_display_name($tag), array('class'=>$tag->class, 'title'=>get_string('numberofentries','blog',$tag->ct)));
+                $link = html_writer::link($blogurl, core_tag_tag::make_display_name($tag),
+                        array('class' => $tag->class,
+                            'title' => get_string('numberofentries', 'blog', $tag->ct)));
                 $this->content->text .= '<li>' . $link . '</li> ';
             }
             $this->content->text .= "\n</ul>\n";
index f16b0bc..57ae2b3 100644 (file)
@@ -344,16 +344,9 @@ class block_base {
      * You don't need to override this if you 're satisfied with the above
      *
      * @deprecated since Moodle 2.9 MDL-49385 - Please use Admin Settings functionality to save block configuration.
-     * @todo MDL-49553 This will be deleted in Moodle 3.1
-     * @param array $data
-     * @return boolean
      */
     function config_save($data) {
-        debugging('config_save($data) is deprecated, use Admin Settings functionality to save block configuration.', DEBUG_DEVELOPER);
-        foreach ($data as $name => $value) {
-            set_config($name, $value);
-        }
-        return true;
+        throw new coding_exception('config_save() can not be used any more, use Admin Settings functionality to save block configuration.');
     }
 
     /**
diff --git a/blocks/navigation/amd/build/ajax_response_renderer.min.js b/blocks/navigation/amd/build/ajax_response_renderer.min.js
new file mode 100644 (file)
index 0000000..3f5162d
Binary files /dev/null and b/blocks/navigation/amd/build/ajax_response_renderer.min.js differ
diff --git a/blocks/navigation/amd/build/nav_loader.min.js b/blocks/navigation/amd/build/nav_loader.min.js
new file mode 100644 (file)
index 0000000..183a19f
Binary files /dev/null and b/blocks/navigation/amd/build/nav_loader.min.js differ
diff --git a/blocks/navigation/amd/build/navblock.min.js b/blocks/navigation/amd/build/navblock.min.js
new file mode 100644 (file)
index 0000000..5a5d7b9
Binary files /dev/null and b/blocks/navigation/amd/build/navblock.min.js differ
diff --git a/blocks/navigation/amd/build/site_admin_loader.min.js b/blocks/navigation/amd/build/site_admin_loader.min.js
new file mode 100644 (file)
index 0000000..9bd76cb
Binary files /dev/null and b/blocks/navigation/amd/build/site_admin_loader.min.js differ
diff --git a/blocks/navigation/amd/src/ajax_response_renderer.js b/blocks/navigation/amd/src/ajax_response_renderer.js
new file mode 100644 (file)
index 0000000..1416899
--- /dev/null
@@ -0,0 +1,170 @@
+// 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/>.
+
+/**
+ * Parse the response from the navblock ajax page and render the correct DOM
+ * structure for the tree from it.
+ *
+ * @module     block_navigation/ajax_response_renderer
+ * @package    core
+ * @copyright  2015 John Okely <john@moodle.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+define(['jquery'], function($) {
+
+    // Mappings for the different types of nodes coming from the navigation.
+    // Copied from lib/navigationlib.php navigation_node constants.
+    var NODETYPE = {
+        // @type int Root node = 0.
+        ROOTNODE : 0,
+        // @type int System context = 1.
+        SYSTEM : 1,
+        // @type int Course category = 10.
+        CATEGORY : 10,
+        // @type int MYCATEGORY = 11.
+        MYCATEGORY : 11,
+        // @type int Course = 20.
+        COURSE : 20,
+        // @type int Course section = 30.
+        SECTION : 30,
+        // @type int Activity (course module) = 40.
+        ACTIVITY : 40,
+        // @type int Resource (course module = 50.
+        RESOURCE : 50,
+        // @type int Custom node (could be anything) = 60.
+        CUSTOM : 60,
+        // @type int Setting = 70.
+        SETTING : 70,
+        // @type int site administration = 71.
+        SITEADMIN : 71,
+        // @type int User context = 80.
+        USER : 80,
+        // @type int Container = 90.
+        CONTAINER : 90
+    };
+
+    /**
+     * Build DOM.
+     *
+     * @method buildDOM
+     * @param {Object} rootElement the root element of DOM.
+     * @param {object} nodes jquery object representing the nodes to be build.
+     * @return
+     */
+    function buildDOM(rootElement, nodes) {
+        var ul = $('<ul></ul>');
+        ul.attr('role', 'group');
+
+        $.each(nodes, function(index, node) {
+            if (typeof node !== 'object') {
+                return;
+            }
+
+            var li = $('<li></li>');
+            var p = $('<p></p>');
+            var icon = null;
+            var isBranch = (node.expandable || node.haschildren) ? true : false;
+
+            p.addClass('tree_item');
+            p.attr('id', node.id);
+            li.attr('role', 'treeitem');
+
+            if (node.requiresajaxloading) {
+                li.attr('data-requires-ajax', true);
+                li.attr('data-node-id', node.id);
+                li.attr('data-node-key', node.key);
+                li.attr('data-node-type', node.type);
+            }
+
+            if (isBranch) {
+                li.addClass('collapsed contains_branch');
+                li.attr('aria-expanded', false);
+                p.addClass('branch');
+            }
+
+            if (node.icon && (!isBranch || node.type === NODETYPE.ACTIVITY || node.type === NODETYPE.RESOURCE)) {
+                li.addClass('item_with_icon');
+                p.addClass('hasicon');
+
+                icon = $('<img/>');
+                icon.attr('alt', node.icon.alt);
+                icon.attr('title', node.icon.title);
+                icon.attr('src', M.util.image_url(node.icon.pix, node.icon.component));
+                $.each(node.icon.classes, function(index, className) {
+                    icon.addClass(className);
+                });
+            }
+
+            if (node.link) {
+                var link = $('<a></a>');
+                link.attr('title', node.title);
+                link.attr('href', node.link);
+
+                if (icon) {
+                    link.append(icon);
+                    link.append('<span class="item-content-wrap">'+node.name+'</span>');
+                } else {
+                    link.text(node.name);
+                }
+
+                if (node.hidden) {
+                    link.addClass('dimmed');
+                }
+
+                p.append(link);
+            } else {
+                var span = $('<span></span>');
+
+                if (icon) {
+                    span.append(icon);
+                    span.append('<span class="item-content-wrap">'+node.name+'</span>');
+                } else {
+                    span.text(node.name);
+                }
+
+                if (node.hidden) {
+                    span.addClass('dimmed');
+                }
+
+                p.append(span);
+            }
+
+            li.append(p);
+            ul.append(li);
+
+            if (node.children && node.children.length) {
+                buildDOM(li, node.children);
+            } else if (isBranch && !node.requiresajaxloading) {
+                li.removeClass('contains_branch');
+                li.addClass('emptybranch');
+            }
+        });
+
+        rootElement.append(ul);
+    }
+
+    return {
+        render: function(element, nodes) {
+            // The first element of the response is the existing node so we start with processing the children.
+            if (nodes.children && nodes.children.length) {
+                buildDOM(element, nodes.children);
+            } else {
+                if (element.hasClass('contains_branch')) {
+                    element.removeClass('contains_branch').addClass('emptybranch');
+                }
+            }
+        }
+    };
+});
diff --git a/blocks/navigation/amd/src/nav_loader.js b/blocks/navigation/amd/src/nav_loader.js
new file mode 100644 (file)
index 0000000..2cb5137
--- /dev/null
@@ -0,0 +1,64 @@
+// 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/>.
+
+/**
+ * Load the nav tree items via ajax and render the response.
+ *
+ * @module     block_navigation/nav_loader
+ * @package    core
+ * @copyright  2015 John Okely <john@moodle.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+define(['jquery', 'core/ajax', 'core/config', 'block_navigation/ajax_response_renderer'],
+    function($, ajax, config, renderer) {
+        var URL = config.wwwroot + '/lib/ajax/getnavbranch.php';
+
+        /**
+         * Get the block instance id.
+         *
+         * @function getBlockInstanceId
+         * @param element
+         * @returns {*}
+         */
+        function getBlockInstanceId(element) {
+            return element.closest('[data-block]').attr('data-instanceid');
+        }
+
+    return {
+        load: function(element) {
+            element = $(element);
+            var promise = $.Deferred();
+            var data = {
+                elementid: element.attr('data-node-id'),
+                id: element.attr('data-node-key'),
+                type: element.attr('data-node-type'),
+                sesskey: config.sesskey,
+                instance: getBlockInstanceId(element)
+            };
+            var settings = {
+                type: 'POST',
+                dataType: 'json',
+                data: data
+            };
+
+            $.ajax(URL, settings).done(function(nodes) {
+                renderer.render(element, nodes);
+                promise.resolve();
+            });
+
+            return promise;
+        }
+    };
+});
similarity index 70%
rename from webservice/amf/lang/en/webservice_amf.php
rename to blocks/navigation/amd/src/navblock.js
index 7b04928..14b14bb 100644 (file)
@@ -1,4 +1,3 @@
-<?php
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
 // You should have received a copy of the GNU General Public License
 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
 
-
 /**
- * Strings for component 'webservice_amf', language 'en', branch 'MOODLE_20_STABLE'
+ * Load the navigation tree javascript.
  *
- * @package    webservice_amf
- * @category   string
- * @copyright  2010 Petr Skodak
+ * @module     block_navigation/navblock
+ * @package    core
+ * @copyright  2015 John Okely <john@moodle.com>
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
-
-
-$string['amf:use'] = 'Use AMF protocol';
-$string['pluginname'] = 'AMF protocol';
+define(['jquery', 'core/tree'], function($, Tree) {
+    return {
+        init: function() {
+            new Tree(".block_navigation .block_tree");
+        }
+    };
+});
diff --git a/blocks/navigation/amd/src/site_admin_loader.js b/blocks/navigation/amd/src/site_admin_loader.js
new file mode 100644 (file)
index 0000000..b203aac
--- /dev/null
@@ -0,0 +1,52 @@
+// 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/>.
+
+/**
+ * Load the site admin nav tree via ajax and render the response.
+ *
+ * @module     block_navigation/site_admin_loader
+ * @package    core
+ * @copyright  2015 John Okely <john@moodle.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+define(['jquery', 'core/ajax', 'core/config', 'block_navigation/ajax_response_renderer'],
+        function($, ajax, config, renderer) {
+
+    var SITE_ADMIN_NODE_TYPE = 71;
+    var URL = config.wwwroot + '/lib/ajax/getsiteadminbranch.php';
+
+    return {
+        load: function(element) {
+            element = $(element);
+            var promise = $.Deferred();
+            var data = {
+                type: SITE_ADMIN_NODE_TYPE,
+                sesskey: config.sesskey
+            };
+            var settings = {
+                type: 'POST',
+                dataType: 'json',
+                data: data
+            };
+
+            $.ajax(URL, settings).done(function(nodes) {
+                renderer.render(element, nodes);
+                promise.resolve();
+            });
+
+            return promise;
+        }
+    };
+});
index 17a2509..31a3fc8 100644 (file)
@@ -107,25 +107,9 @@ class block_navigation extends block_base {
      * Gets Javascript that may be required for navigation
      */
     function get_required_javascript() {
-        global $CFG;
         parent::get_required_javascript();
-        $limit = 20;
-        if (!empty($CFG->navcourselimit)) {
-            $limit = $CFG->navcourselimit;
-        }
-        $expansionlimit = 0;
-        if (!empty($this->config->expansionlimit)) {
-            $expansionlimit = $this->config->expansionlimit;
-        }
-        $arguments = array(
-            'id'             => $this->instance->id,
-            'instance'       => $this->instance->id,
-            'candock'        => $this->instance_can_be_docked(),
-            'courselimit'    => $limit,
-            'expansionlimit' => $expansionlimit
-        );
         $this->page->requires->string_for_js('viewallcourses', 'moodle');
-        $this->page->requires->yui_module('moodle-block_navigation-navigation', 'M.block_navigation.init_add_tree', array($arguments));
+        $this->page->requires->js_call_amd('block_navigation/navblock', 'init', array());
     }
 
     /**
@@ -134,6 +118,7 @@ class block_navigation extends block_base {
      * @return object $this->content
      */
     function get_content() {
+        global $CFG;
         // First check if we have already generated, don't waste cycles
         if ($this->contentgenerated === true) {
             return $this->content;
@@ -196,7 +181,21 @@ class block_navigation extends block_base {
             }
         }
 
-        $this->page->requires->data_for_js('navtreeexpansions'.$this->instance->id, $expandable);
+        $limit = 20;
+        if (!empty($CFG->navcourselimit)) {
+            $limit = $CFG->navcourselimit;
+        }
+        $expansionlimit = 0;
+        if (!empty($this->config->expansionlimit)) {
+            $expansionlimit = $this->config->expansionlimit;
+        }
+        $arguments = array(
+            'id'             => $this->instance->id,
+            'instance'       => $this->instance->id,
+            'candock'        => $this->instance_can_be_docked(),
+            'courselimit'    => $limit,
+            'expansionlimit' => $expansionlimit
+        );
 
         $options = array();
         $options['linkcategories'] = (!empty($this->config->linkcategories) && $this->config->linkcategories == 'yes');
index 2a92c9f..3c8932c 100644 (file)
@@ -42,7 +42,11 @@ class block_navigation_renderer extends plugin_renderer_base {
      */
     public function navigation_tree(global_navigation $navigation, $expansionlimit, array $options = array()) {
         $navigation->add_class('navigation_node');
-        $content = $this->navigation_node(array($navigation), array('class'=>'block_tree list'), $expansionlimit, $options);
+        $navigationattrs = array(
+            'class' => 'block_tree list',
+            'role' => 'tree',
+            'data-ajax-loader' => 'block_navigation/nav_loader');
+        $content = $this->navigation_node(array($navigation), $navigationattrs, $expansionlimit, $options);
         if (isset($navigation->id) && !is_numeric($navigation->id) && !empty($content)) {
             $content = $this->output->box($content, 'block_tree_box', $navigation->id);
         }
@@ -66,7 +70,9 @@ class block_navigation_renderer extends plugin_renderer_base {
 
         // Turn our navigation items into list items.
         $lis = array();
+        $number = 0;
         foreach ($items as $item) {
+            $number++;
             if (!$item->display && !$item->contains_active_node()) {
                 continue;
             }
@@ -100,7 +106,8 @@ class block_navigation_renderer extends plugin_renderer_base {
                 continue;
             }
 
-            $attributes = array();
+            $nodetextid = 'label_' . $depth . '_' . $number;
+            $attributes = array('tabindex' => '-1', 'id' => $nodetextid);
             if ($title !== '') {
                 $attributes['title'] = $title;
             }
@@ -110,7 +117,6 @@ class block_navigation_renderer extends plugin_renderer_base {
             if (is_string($item->action) || empty($item->action) ||
                     (($item->type === navigation_node::TYPE_CATEGORY || $item->type === navigation_node::TYPE_MY_CATEGORY) &&
                     empty($options['linkcategories']))) {
-                $attributes['tabindex'] = '0'; //add tab support to span but still maintain character stream sequence.
                 $content = html_writer::tag('span', $content, $attributes);
             } else if ($item->action instanceof action_link) {
                 //TODO: to be replaced with something else
@@ -129,12 +135,27 @@ class block_navigation_renderer extends plugin_renderer_base {
             $divclasses = array('tree_item');
 
             $liexpandable = array();
-            if ($item->has_children() && (!$item->forceopen || $item->collapse)) {
-                $liclasses[] = 'collapsed';
-            }
+            $lirole = array('role' => 'treeitem');
             if ($isbranch) {
                 $liclasses[] = 'contains_branch';
-                $liexpandable = array('aria-expanded' => in_array('collapsed', $liclasses) ? "false" : "true");
+                if ($depth == 1) {
+                    $liexpandable = array(
+                        'data-expandable' => 'false'
+                    );
+                } else {
+                    $liexpandable = array(
+                        'aria-expanded' => ($item->has_children() &&
+                            (!$item->forceopen || $item->collapse)) ? "false" : "true");
+                }
+
+                if ($item->requiresajaxloading) {
+                    $liexpandable['data-requires-ajax'] = 'true';
+                    $liexpandable['data-loaded'] = 'false';
+                    $liexpandable['data-node-id'] = $item->id;
+                    $liexpandable['data-node-key'] = $item->key;
+                    $liexpandable['data-node-type'] = $item->type;
+                }
+
                 $divclasses[] = 'branch';
             } else {
                 $divclasses[] = 'leaf';
@@ -152,7 +173,7 @@ class block_navigation_renderer extends plugin_renderer_base {
             }
 
             // Now build attribute arrays.
-            $liattr = array('class' => join(' ', $liclasses)) + $liexpandable;
+            $liattr = array('class' => join(' ', $liclasses)) + $liexpandable + $lirole;
             $divattr = array('class'=>join(' ', $divclasses));
             if (!empty($item->id)) {
                 $divattr['id'] = $item->id;
@@ -161,11 +182,16 @@ class block_navigation_renderer extends plugin_renderer_base {
             // Create the structure.
             $content = html_writer::tag('p', $content, $divattr);
             if ($isexpandable) {
-                $content .= $this->navigation_node($item->children, array(), $expansionlimit, $options, $depth+1);
+                $content .= $this->navigation_node($item->children, array('role' => 'group'), $expansionlimit,
+                    $options, $depth + 1);
             }
             if (!empty($item->preceedwithhr) && $item->preceedwithhr===true) {
                 $content = html_writer::empty_tag('hr') . $content;
             }
+            if ($depth == 1) {
+                $liattr['tabindex'] = '0';
+            }
+            $liattr['aria-labelledby'] = $nodetextid;
             $content = html_writer::tag('li', $content, $liattr);
             $lis[] = $content;
         }
index c35c764..e4e0392 100644 (file)
     background-image: url('[[pix:i/loading_small]]');
 }
 
+.block_navigation .block_tree .loading .tree_item.branch {
+    background-image: url('[[pix:i/loading_small]]');
+}
+
+.block_navigation .block_tree .emptybranch .tree_item,
+.block_navigation .block_tree [aria-expanded="false"].emptybranch .tree_item.branch {
+    padding-left: 21px;
+    background-image: url('[[pix:t/collapsed_empty]]');
+}
+
 .block_navigation .block_tree .tree_item img {
     width: 16px;
     height: 16px;
     list-style: none;
 }
 
-.jsenabled .block_navigation .block_tree li.collapsed ul {
+.jsenabled .block_navigation .block_tree [aria-expanded="false"] ul {
     display: none;
 }
 
-.jsenabled .block_navigation .block_tree li.collapsed .tree_item.branch {
+.jsenabled .block_navigation .block_tree [aria-expanded="false"] .tree_item.branch {
     background-image: url('[[pix:t/collapsed]]');
 }
 
+.jsenabled .block_navigation .block_tree [aria-expanded="false"].loading .tree_item.branch {
+    background-image: url('[[pix:i/loading_small]]');
+}
+
+.jsenabled .block_navigation .block_tree [aria-expanded="false"].emptybranch .tree_item.branch {
+    padding-left: 21px;
+    background-image: url('[[pix:t/collapsed_empty]]');
+}
+
 .jsenabled .block_navigation.dock_on_load {
     display: none;
 }
     padding-left: 0;
 }
 
-.dir-rtl .block_navigation .block_tree .tree_item.emptybranch {
+.dir-rtl .block_navigation .block_tree .tree_item.emptybranch,
+.dir-rtl .block_navigation .block_tree .emptybranch .tree_item {
     padding-right: 21px;
     padding-left: 0;
     background-image: url('[[pix:t/collapsed_empty_rtl]]');
     margin: 0 16px 0 0;
 }
 
-.dir-rtl.jsenabled .block_navigation .block_tree .collapsed .tree_item.branch {
+.dir-rtl.jsenabled .block_navigation .block_tree [aria-expanded="false"] .tree_item.branch {
     background-image: url('[[pix:t/collapsed_rtl]]');
 }
+
+.dir-rtl.jsenabled .block_navigation .block_tree [aria-expanded="false"].emptybranch .tree_item.branch {
+    background-image: url('[[pix:t/collapsed_empty_rtl]]');
+}
diff --git a/blocks/navigation/yui/build/moodle-block_navigation-navigation/moodle-block_navigation-navigation-debug.js b/blocks/navigation/yui/build/moodle-block_navigation-navigation/moodle-block_navigation-navigation-debug.js
deleted file mode 100644 (file)
index 2d58702..0000000
Binary files a/blocks/navigation/yui/build/moodle-block_navigation-navigation/moodle-block_navigation-navigation-debug.js and /dev/null differ
diff --git a/blocks/navigation/yui/build/moodle-block_navigation-navigation/moodle-block_navigation-navigation-min.js b/blocks/navigation/yui/build/moodle-block_navigation-navigation/moodle-block_navigation-navigation-min.js
deleted file mode 100644 (file)
index 7c67d98..0000000
Binary files a/blocks/navigation/yui/build/moodle-block_navigation-navigation/moodle-block_navigation-navigation-min.js and /dev/null differ
diff --git a/blocks/navigation/yui/build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js b/blocks/navigation/yui/build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js
deleted file mode 100644 (file)
index b661bfd..0000000
Binary files a/blocks/navigation/yui/build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js and /dev/null differ
diff --git a/blocks/navigation/yui/src/navigation/build.json b/blocks/navigation/yui/src/navigation/build.json
deleted file mode 100644 (file)
index 5e28a6c..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-{
-  "name": "moodle-block_navigation-navigation",
-  "builds": {
-    "moodle-block_navigation-navigation": {
-      "jsfiles": [
-        "navigation.js"
-      ]
-    }
-  }
-}
diff --git a/blocks/navigation/yui/src/navigation/js/navigation.js b/blocks/navigation/yui/src/navigation/js/navigation.js
deleted file mode 100644 (file)
index 3678bff..0000000
+++ /dev/null
@@ -1,897 +0,0 @@
-/**
- * Navigation block JS.
- *
- * This file contains the Navigation block JS..
- *
- * @module moodle-block_navigation-navigation
- */
-
-/**
- * This namespace will contain all of the contents of the navigation blocks
- * global navigation and settings.
- * @class M.block_navigation
- * @static
- */
-M.block_navigation = M.block_navigation || {};
-/**
- * The number of expandable branches in existence.
- *
- * @property expandablebranchcount
- * @protected
- * @static
- * @type Number
- */
-M.block_navigation.expandablebranchcount = 1;
-/**
- * The maximum number of courses to show as part of a branch.
- *
- * @property courselimit
- * @protected
- * @static
- * @type Number
- */
-M.block_navigation.courselimit = 20;
-/**
- * Add new instance of navigation tree to tree collection
- *
- * @method init_add_tree
- * @static
- * @param {Object} properties
- */
-M.block_navigation.init_add_tree = function(properties) {
-    if (properties.courselimit) {
-        this.courselimit = properties.courselimit;
-    }
-    new TREE(properties);
-};
-
-/**
- * A 'actionkey' Event to help with Y.delegate().
- * The event consists of the left arrow, right arrow, enter and space keys.
- * More keys can be mapped to action meanings.
- * actions: collapse , expand, toggle, enter.
- *
- * This event is delegated to branches in the navigation tree.
- * The on() method to subscribe allows specifying the desired trigger actions as JSON.
- *
- * @namespace M.block_navigation
- * @class ActionKey
- */
-Y.Event.define("actionkey", {
-    // Webkit and IE repeat keydown when you hold down arrow keys.
-    // Opera links keypress to page scroll; others keydown.
-    // Firefox prevents page scroll via preventDefault() on either
-    // keydown or keypress.
-    _event: (Y.UA.webkit || Y.UA.ie) ? 'keydown' : 'keypress',
-
-    /**
-     * The keys to trigger on.
-     * @method _keys
-     */
-    _keys: {
-        //arrows
-        '37': 'collapse',
-        '39': 'expand',
-        '32': 'toggle',
-        '13': 'enter'
-    },
-
-    /**
-     * Handles key events
-     * @method _keyHandler
-     * @param {EventFacade} e
-     * @param {SyntheticEvent.Notifier} notifier The notifier used to trigger the execution of subscribers
-     * @param {Object} args
-     */
-    _keyHandler: function (e, notifier, args) {
-        var actObj;
-        if (!args.actions) {
-            actObj = {collapse:true, expand:true, toggle:true, enter:true};
-        } else {
-            actObj = args.actions;
-        }
-        if (this._keys[e.keyCode] && actObj[this._keys[e.keyCode]]) {
-            e.action = this._keys[e.keyCode];
-            notifier.fire(e);
-        }
-    },
-
-    /**
-     * Subscribes to events.
-     * @method on
-     * @param {Node} node The node this subscription was applied to.
-     * @param {Subscription} sub The object tracking this subscription.
-     * @param {SyntheticEvent.Notifier} notifier The notifier used to trigger the execution of subscribers
-     */
-    on: function (node, sub, notifier) {
-        // subscribe to _event and ask keyHandler to handle with given args[0] (the desired actions).
-        if (sub.args === null) {
-            //no actions given
-            sub._detacher = node.on(this._event, this._keyHandler,this, notifier, {actions:false});
-        } else {
-            sub._detacher = node.on(this._event, this._keyHandler,this, notifier, sub.args[0]);
-        }
-    },
-
-    /**
-     * Detaches an event listener
-     * @method detach
-     */
-    detach: function (node, sub) {
-        //detach our _detacher handle of the subscription made in on()
-        sub._detacher.detach();
-    },
-
-    /**
-     * Creates a delegated event listener.
-     * @method delegate
-     * @param {Node} node The node this subscription was applied to.
-     * @param {Subscription} sub The object tracking this subscription.
-     * @param {SyntheticEvent.Notifier} notifier The notifier used to trigger the execution of subscribers
-     * @param {String|function} filter Selector string or function that accpets an event object and returns null.
-     */
-    delegate: function (node, sub, notifier, filter) {
-        // subscribe to _event and ask keyHandler to handle with given args[0] (the desired actions).
-        if (sub.args === null) {
-            //no actions given
-            sub._delegateDetacher = node.delegate(this._event, this._keyHandler,filter, this, notifier, {actions:false});
-        } else {
-            sub._delegateDetacher = node.delegate(this._event, this._keyHandler,filter, this, notifier, sub.args[0]);
-        }
-    },
-
-    /**
-     * Detaches a delegated event listener.
-     * @method detachDelegate
-     * @param {Node} node The node this subscription was applied to.
-     * @param {Subscription} sub The object tracking this subscription.
-     * @param {SyntheticEvent.Notifier} notifier The notifier used to trigger the execution of subscribers
-     * @param {String|function} filter Selector string or function that accpets an event object and returns null.
-     */
-    detachDelegate: function (node, sub) {
-        sub._delegateDetacher.detach();
-    }
-});
-
-var EXPANSIONLIMIT_EVERYTHING = 0,
-    EXPANSIONLIMIT_COURSE     = 20,
-    EXPANSIONLIMIT_SECTION    = 30,
-    EXPANSIONLIMIT_ACTIVITY   = 40;
-
-// Mappings for the different types of nodes coming from the navigation.
-// Copied from lib/navigationlib.php navigation_node constants.
-var NODETYPE = {
-    // @type int Root node = 0
-    ROOTNODE : 0,
-    // @type int System context = 1
-    SYSTEM : 1,
-    // @type int Course category = 10
-    CATEGORY : 10,
-    // @type int MYCATEGORY = 11
-    MYCATEGORY : 11,
-    // @type int Course = 20
-    COURSE : 20,
-    // @type int Course section = 30
-    SECTION : 30,
-    // @type int Activity (course module) = 40
-    ACTIVITY : 40,
-    // @type int Resource (course module = 50
-    RESOURCE : 50,
-    // @type int Custom node (could be anything) = 60
-    CUSTOM : 60,
-    // @type int Setting = 70
-    SETTING : 70,
-    // @type int site administration = 71
-    SITEADMIN : 71,
-    // @type int User context = 80
-    USER : 80,
-    // @type int Container = 90
-    CONTAINER : 90
-};
-
-/**
- * Navigation tree class.
- *
- * This class establishes the tree initially, creating expandable branches as
- * required, and delegating the expand/collapse event.
- *
- * @namespace M.block_navigation
- * @class Tree
- * @constructor
- * @extends Base
- */
-var TREE = function() {
-    TREE.superclass.constructor.apply(this, arguments);
-};
-TREE.prototype = {
-    /**
-     * The tree's ID, normally its block instance id.
-     * @property id
-     * @type Number
-     * @protected
-     */
-    id : null,
-    /**
-     * An array of initialised branches.
-     * @property branches
-     * @type Array
-     * @protected
-     */
-    branches : [],
-    /**
-     * Initialise the tree object when its first created.
-     * @method initializer
-     * @param {Object} config
-     */
-    initializer : function(config) {
-        Y.log('Initialising navigation block tree', 'note', 'moodle-block_navigation');
-
-        this.id = parseInt(config.id, 10);
-
-        var node = Y.one('#inst'+config.id);
-
-        // Can't find the block instance within the page
-        if (node === null) {
-            return;
-        }
-
-        // Delegate event to toggle expansion
-        Y.delegate('click', this.toggleExpansion, node.one('.block_tree'), '.tree_item.branch', this);
-        Y.delegate('actionkey', this.toggleExpansion, node.one('.block_tree'), '.tree_item.branch', this);
-
-        // Gather the expandable branches ready for initialisation.
-        var expansions = [];
-        if (config.expansions) {
-            expansions = config.expansions;
-        } else if (window['navtreeexpansions'+config.id]) {
-            expansions = window['navtreeexpansions'+config.id];
-        }
-        // Establish each expandable branch as a tree branch.
-        for (var i in expansions) {
-            var branch = new BRANCH({
-                tree:this,
-                branchobj:expansions[i],
-                overrides : {
-                    expandable : true,
-                    children : [],
-                    haschildren : true
-                }
-            }).wire();
-            M.block_navigation.expandablebranchcount++;
-            this.branches[branch.get('id')] = branch;
-        }
-        // Create siteadmin branch.
-        if (window.siteadminexpansion) {
-            var siteadminbranch = new BRANCH({
-                tree: this,
-                branchobj: window.siteadminexpansion,
-                overrides : {
-                    expandable : true,
-                    children : [],
-                    haschildren : true
-                }
-            }).wire();
-            M.block_navigation.expandablebranchcount++;
-            this.branches[siteadminbranch.get('id')] = siteadminbranch;
-            // Remove link on site admin with JS to keep old UI.
-            if (siteadminbranch.node) {
-                var siteadminlinknode = siteadminbranch.node.get('childNodes').item(0);
-                if (siteadminlinknode) {
-                    var siteadminnode = Y.Node.create('<span tabindex="0">'+siteadminlinknode.get('innerHTML')+'</span>');
-                    siteadminbranch.node.replaceChild(siteadminnode, siteadminlinknode);
-                }
-            }
-        }
-        if (M.block_navigation.expandablebranchcount > 0) {
-            // Delegate some events to handle AJAX loading.
-            Y.delegate('click', this.fire_branch_action, node.one('.block_tree'), '.tree_item.branch[data-expandable]', this);
-            Y.delegate('actionkey', this.fire_branch_action, node.one('.block_tree'), '.tree_item.branch[data-expandable]', this);
-        }
-    },
-    /**
-     * Fire actions for a branch when an event occurs.
-     * @method fire_branch_action
-     * @param {EventFacade} event
-     */
-    fire_branch_action : function(event) {
-        var id = event.currentTarget.getAttribute('id');
-        var branch = this.branches[id];
-        branch.ajaxLoad(event);
-    },
-    /**
-     * This is a callback function responsible for expanding and collapsing the
-     * branches of the tree. It is delegated to rather than multiple event handles.
-     * @method toggleExpansion
-     * @param {EventFacade} e
-     * @return Boolean
-     */
-    toggleExpansion : function(e) {
-        // First check if they managed to click on the li iteslf, then find the closest
-        // LI ancestor and use that
-
-        if (e.target.test('a') && (e.keyCode === 0 || e.keyCode === 13)) {
-            // A link has been clicked (or keypress is 'enter') don't fire any more events just do the default.
-            e.stopPropagation();
-            return;
-        }
-
-        // Makes sure we can get to the LI containing the branch.
-        var target = e.target;
-        if (!target.test('li')) {
-            target = target.ancestor('li');
-        }
-        if (!target) {
-            return;
-        }
-
-        // Toggle expand/collapse providing its not a root level branch.
-        if (!target.hasClass('depth_1')) {
-            if (e.type === 'actionkey') {
-                switch (e.action) {
-                    case 'expand' :
-                        target.removeClass('collapsed');
-                        target.set('aria-expanded', true);
-                        break;
-                    case 'collapse' :
-                        target.addClass('collapsed');
-                        target.set('aria-expanded', false);
-                        break;
-                    default :
-                        target.toggleClass('collapsed');
-                        target.set('aria-expanded', !target.hasClass('collapsed'));
-                }
-                e.halt();
-            } else {
-                target.toggleClass('collapsed');
-                target.set('aria-expanded', !target.hasClass('collapsed'));
-            }
-        }
-
-        // If the accordian feature has been enabled collapse all siblings.
-        if (this.get('accordian')) {
-            target.siblings('li').each(function(){
-                if (this.get('id') !== target.get('id') && !this.hasClass('collapsed')) {
-                    this.addClass('collapsed');
-                    this.set('aria-expanded', false);
-                }
-            });
-        }
-
-        // If this block can dock tell the dock to resize if required and check
-        // the width on the dock panel in case it is presently in use.
-        if (this.get('candock') && M.core.dock.notifyBlockChange) {
-            M.core.dock.notifyBlockChange(this.id);
-        }
-        return true;
-
-    }
-};
-// The tree extends the YUI base foundation.
-Y.extend(TREE, Y.Base, TREE.prototype, {
-    NAME : 'navigation-tree',
-    ATTRS : {
-        /**
-         * True if the block can dock.
-         * @attribute candock
-         * @type Boolean
-         */
-        candock : {
-            validator : Y.Lang.isBool,
-            value : false
-        },
-        /**
-         * If set to true nodes will be opened/closed in an accordian fashion.
-         * @attribute accordian
-         * @type Boolean
-         */
-        accordian : {
-            validator : Y.Lang.isBool,
-            value : false
-        },
-        /**
-         * The nodes that get shown.
-         * @attribute expansionlimit
-         * @type Number
-         */
-        expansionlimit : {
-            value : 0,
-            setter : function(val) {
-                val = parseInt(val, 10);
-                if (val !== EXPANSIONLIMIT_EVERYTHING &&
-                    val !== EXPANSIONLIMIT_COURSE &&
-                    val !== EXPANSIONLIMIT_SECTION &&
-                    val !== EXPANSIONLIMIT_ACTIVITY) {
-                    val = EXPANSIONLIMIT_EVERYTHING;
-                }
-                return val;
-            }
-        },
-        /**
-         * The navigation tree block instance.
-         *
-         * @attribute instance
-         * @default false
-         * @type Number
-         */
-        instance : {
-            value : false,
-            setter : function(val) {
-                return parseInt(val, 10);
-            }
-        }
-    }
-});
-
-/**
- * The Branch class.
- *
- * This class is used to manage a tree branch, in particular its ability to load
- * its contents by AJAX.
- *
- * @namespace M.block_navigation
- * @class Branch
- * @constructor
- * @extends Base
- */
-var BRANCH = function() {
-    BRANCH.superclass.constructor.apply(this, arguments);
-};
-BRANCH.prototype = {
-    /**
-     * The node for this branch (p)
-     * @property node
-     * @type Node
-     * @protected
-     */
-    node : null,
-    /**
-     * Initialises the branch when it is first created.
-     * @method initializer
-     * @param {Object} config
-     */
-    initializer : function(config) {
-        var i,
-            children;
-        if (config.branchobj !== null) {
-            // Construct from the provided xml
-            for (i in config.branchobj) {
-                this.set(i, config.branchobj[i]);
-            }
-            children = this.get('children');
-            this.set('haschildren', (children.length > 0));
-        }
-        if (config.overrides !== null) {
-            // Construct from the provided xml
-            for (i in config.overrides) {
-                this.set(i, config.overrides[i]);
-            }
-        }
-        // Get the node for this branch
-        this.node = Y.one('#'+this.get('id'));
-        var expansionlimit = this.get('tree').get('expansionlimit');
-        var type = this.get('type');
-        if (expansionlimit !== EXPANSIONLIMIT_EVERYTHING &&  type >= expansionlimit && type <= EXPANSIONLIMIT_ACTIVITY) {
-            this.set('expandable', false);
-            this.set('haschildren', false);
-        }
-    },
-    /**
-     * Draws the branch within the tree.
-     *
-     * This function creates a DOM structure for the branch and then injects
-     * it into the navigation tree at the correct point.
-     *
-     * It is important that this is kept in check with block_navigation_renderer::navigation_node as that produces
-     * the same thing as this but on the php side.
-     *
-     * @method draw
-     * @chainable
-     * @param {Node} element
-     * @return Branch
-     */
-    draw : function(element) {
-
-        var isbranch = (this.get('expandable') || this.get('haschildren'));
-        var branchli = Y.Node.create('<li></li>');
-        var link = this.get('link');
-        var branchp = Y.Node.create('<p class="tree_item"></p>').setAttribute('id', this.get('id'));
-        var name;
-        if (!link) {
-            //add tab focus if not link (so still one focus per menu node).
-            // it was suggested to have 2 foci. one for the node and one for the link in MDL-27428.
-            branchp.setAttribute('tabindex', '0');
-        }
-        if (isbranch) {
-            branchli.addClass('collapsed').addClass('contains_branch');
-            branchli.set('aria-expanded', false);
-            branchp.addClass('branch');
-        }
-
-        // Prepare the icon, should be an object representing a pix_icon
-        var branchicon = false;
-        var icon = this.get('icon');
-        if (icon && (!isbranch || this.get('type') === NODETYPE.ACTIVITY || this.get('type') === NODETYPE.RESOURCE)) {
-            branchicon = Y.Node.create('<img alt="" />');
-            branchicon.setAttribute('src', M.util.image_url(icon.pix, icon.component));
-            branchli.addClass('item_with_icon');
-            branchp.addClass('hasicon');
-            if (icon.alt) {
-                branchicon.setAttribute('alt', icon.alt);
-            }
-            if (icon.title) {
-                branchicon.setAttribute('title', icon.title);
-            }
-            if (icon.classes) {
-                for (var i in icon.classes) {
-                    branchicon.addClass(icon.classes[i]);
-                }
-            }
-        }
-
-        if (!link) {
-            var branchspan = Y.Node.create('<span></span>');
-            if (branchicon) {
-                branchspan.appendChild(branchicon);
-                name = '<span class="item-content-wrap">' + this.get('name') + '</span>';
-            } else {
-                name = this.get('name');
-            }
-            branchspan.append(name);
-            if (this.get('hidden')) {
-                branchspan.addClass('dimmed_text');
-            }
-            branchp.appendChild(branchspan);
-        } else {
-            var branchlink = Y.Node.create('<a title="'+this.get('title')+'" href="'+link+'"></a>');
-            if (branchicon) {
-                branchlink.appendChild(branchicon);
-                name = '<span class="item-content-wrap">' + this.get('name') + '</span>';
-            } else {
-                name = this.get('name');
-            }
-            branchlink.append(name);
-            if (this.get('hidden')) {
-                branchlink.addClass('dimmed');
-            }
-            branchp.appendChild(branchlink);
-        }
-
-        branchli.appendChild(branchp);
-        element.appendChild(branchli);
-        this.node = branchp;
-        return this;
-    },
-    /**
-     * Attaches required events to the branch structure.
-     *
-     * @chainable
-     * @method wire
-     * @return {BRANCH} This function is chainable, it always returns itself.
-     */
-    wire : function() {
-        this.node = this.node || Y.one('#'+this.get('id'));
-        if (!this.node) {
-            return this;
-        }
-        if (this.get('expandable')) {
-            this.node.setAttribute('data-expandable', '1');
-            this.node.setAttribute('data-loaded', '0');
-        }
-        return this;
-    },
-    /**
-     * Gets the UL element that children for this branch should be inserted into.
-     * @method getChildrenUL
-     * @return Node
-     */
-    getChildrenUL : function() {
-        var ul = this.node.next('ul');
-        if (!ul) {
-            ul = Y.Node.create('<ul></ul>');
-            this.node.ancestor().append(ul);
-        }
-        return ul;
-    },
-    /**
-     * Load the content of the branch via AJAX.
-     *
-     * This function calls ajaxProcessResponse with the result of the AJAX
-     * request made here.
-     *
-     * @method ajaxLoad
-     * @param {EventFacade} e
-     * @return Bool
-     */
-    ajaxLoad : function(e) {
-        if (e.type === 'actionkey' && e.action !== 'enter') {
-            e.halt();
-        } else {
-            e.stopPropagation();
-        }
-        if ((e.type === 'actionkey' && e.action === 'enter') || e.target.test('a')) {
-            // No ajaxLoad for enter.
-            this.node.setAttribute('data-expandable', '0');
-            this.node.setAttribute('data-loaded', '1');
-            return true;
-        }
-
-        if (this.node.hasClass('loadingbranch')) {
-            // Already loading. Just skip.
-            return true;
-        }
-
-        if (this.node.getAttribute('data-loaded') === '1') {
-            // We've already loaded this stuff.
-            return true;
-        }
-        Y.log('Loading navigation branch via AJAX: '+this.get('key'), 'note', 'moodle-block_navigation');
-        this.node.addClass('loadingbranch');
-
-        var params = {
-            elementid : this.get('id'),
-            id : this.get('key'),
-            type : this.get('type'),
-            sesskey : M.cfg.sesskey,
-            instance : this.get('tree').get('instance')
-        };
-
-        var ajaxfile = '/lib/ajax/getnavbranch.php';
-        // For siteadmin navigation get tree from getsiteadminbranch.php.
-        if (this.get('type') === NODETYPE.SITEADMIN) {
-            ajaxfile = '/lib/ajax/getsiteadminbranch.php';
-        }
-
-        Y.io(M.cfg.wwwroot + ajaxfile, {
-            method:'POST',
-            data:  params,
-            on: {
-                complete: this.ajaxProcessResponse
-            },
-            context:this
-        });
-        return true;
-    },
-    /**
-     * Processes an AJAX request to load the content of this branch through
-     * AJAX.
-     *
-     * @method ajaxProcessResponse
-     * @param {Int} tid The transaction id.
-     * @param {Object} outcome
-     * @return Boolean
-     */
-    ajaxProcessResponse : function(tid, outcome) {
-        this.node.removeClass('loadingbranch');
-        this.node.setAttribute('data-loaded', '1');
-        try {
-            var object = Y.JSON.parse(outcome.responseText);
-            if (object.error) {
-                Y.use('moodle-core-notification-ajaxexception', function () {
-                    return new M.core.ajaxException(object).show();
-                });
-                return false;
-            }
-            if (object.children && object.children.length > 0) {
-                var coursecount = 0;
-                for (var i in object.children) {
-                    if (typeof(object.children[i])==='object') {
-                        if (object.children[i].type === NODETYPE.COURSE) {
-                            coursecount++;
-                        }
-                        this.addChild(object.children[i]);
-                    }
-                }
-                if ((this.get('type') === NODETYPE.CATEGORY ||
-                     this.get('type') === NODETYPE.ROOTNODE ||
-                     this.get('type') === NODETYPE.MYCATEGORY)
-                     && coursecount >= M.block_navigation.courselimit) {
-                    this.addViewAllCoursesChild(this);
-                }
-                Y.log('AJAX loading complete.', 'note', 'moodle-block_navigation');
-                // If this block can dock tell the dock to resize if required and check
-                // the width on the dock panel in case it is presently in use.
-                if (this.get('tree').get('candock') && M.core.dock.notifyBlockChange) {
-                    M.core.dock.notifyBlockChange(this.get('tree').id);
-                }
-                return true;
-            }
-            Y.log('AJAX loading complete but there were no children.', 'note', 'moodle-block_navigation');
-        } catch (error) {
-            if (outcome && outcome.status && outcome.status > 0) {
-                // If we got here then there was an error parsing the result.
-                Y.log('Error parsing AJAX response or adding branches to the navigation tree', 'error', 'moodle-block_navigation');
-                Y.use('moodle-core-notification-exception', function () {
-                    return new M.core.exception(error).show();
-                });
-            }
-
-            return false;
-        }
-        // The branch is empty so class it accordingly
-        this.node.replaceClass('branch', 'emptybranch');
-        return true;
-    },
-    /**
-     * Turns the branch object passed to the method into a proper branch object
-     * and then adds it as a child of this branch.
-     *
-     * @method addChild
-     * @param {Object} branchobj
-     * @return Boolean
-     */
-    addChild : function(branchobj) {
-        // Make the new branch into an object
-        var branch = new BRANCH({tree:this.get('tree'), branchobj:branchobj});
-        if (branch.draw(this.getChildrenUL())) {
-            this.get('tree').branches[branch.get('id')] = branch;
-            branch.wire();
-            var count = 0, i, children = branch.get('children');
-            for (i in children) {
-                // Add each branch to the tree
-                if (children[i].type === NODETYPE.COURSE) {
-                    count++;
-                }
-                if (typeof(children[i]) === 'object') {
-                    branch.addChild(children[i]);
-                }
-            }
-            if ((branch.get('type') === NODETYPE.CATEGORY || branch.get('type') === NODETYPE.MYCATEGORY)
-                && count >= M.block_navigation.courselimit) {
-                this.addViewAllCoursesChild(branch);
-            }
-        }
-        return true;
-    },
-
-    /**
-     * Add a link to view all courses in a category
-     *
-     * @method addViewAllCoursesChild
-     * @param {BRANCH} branch
-     */
-    addViewAllCoursesChild: function(branch) {
-        var url = null;
-        if (branch.get('type') === NODETYPE.ROOTNODE) {
-            if (branch.get('key') === 'mycourses') {
-                url = M.cfg.wwwroot + '/my';
-            } else {
-                url = M.cfg.wwwroot + '/course/index.php';
-            }
-        } else {
-            url = M.cfg.wwwroot+'/course/index.php?categoryid=' + branch.get('key');
-        }
-        branch.addChild({
-            name : M.util.get_string('viewallcourses', 'moodle'),
-            title : M.util.get_string('viewallcourses', 'moodle'),
-            link : url,
-            haschildren : false,
-            icon : {'pix':"i/navigationitem",'component':'moodle'}
-        });
-    }
-};
-Y.extend(BRANCH, Y.Base, BRANCH.prototype, {
-    NAME : 'navigation-branch',
-    ATTRS : {
-        /**
-         * The Tree this branch belongs to.
-         * @attribute tree
-         * @type TREE
-         * @required
-         * @writeOnce
-         */
-        tree : {
-            writeOnce : 'initOnly',
-            validator : Y.Lang.isObject
-        },
-        /**
-         * The name of this branch.
-         * @attribute name
-         * @type String
-         */
-        name : {
-            value : '',
-            validator : Y.Lang.isString,
-            setter : function(val) {
-                return val.replace(/\n/g, '<br />');
-            }
-        },
-        /**
-         * The title to use for this branch.
-         * @attribute title
-         * @type String
-         */
-        title : {
-            value : '',
-            validator : Y.Lang.isString
-        },
-        /**
-         * The ID of this branch.
-         * The ID and Type should always form a unique pair.
-         * @attribute id
-         * @type String
-         */
-        id : {
-            value : '',
-            validator : Y.Lang.isString,
-            getter : function(val) {
-                if (val === '') {
-                    val = 'expandable_branch_'+M.block_navigation.expandablebranchcount;
-                    M.block_navigation.expandablebranchcount++;
-                }
-                return val;
-            }
-        },
-        /**
-         * The key used to identify this branch easily if there is one.
-         * @attribute key
-         * @type String
-         */
-        key : {
-            value : null
-        },
-        /**
-         * The type of this branch.
-         * @attribute type
-         * @type Number
-         */
-        type : {
-            value : null,
-            setter : function(value) {
-                return parseInt(value, 10);
-            }
-        },
-        /**
-         * The link to use for this branch.
-         * @attribute link
-         * @type String
-         */
-        link : {
-            value : false
-        },
-        /**
-         * The Icon to add when displaying this branch.
-         * @attribute icon
-         * @type Object
-         */
-        icon : {
-            value : false,
-            validator : Y.Lang.isObject
-        },
-        /**
-         * True if this branch is expandable.
-         * @attribute expandable
-         * @type Boolean
-         */
-        expandable : {
-            value : false,
-            validator : Y.Lang.isBool
-        },
-        /**
-         * True if this branch is hidden and should be displayed greyed out.
-         * @attribute hidden
-         * @type Boolean
-         */
-        hidden : {
-            value : false,
-            validator : Y.Lang.isBool
-        },
-        /**
-         * True if this branch has any children.
-         * @attribute haschildren
-         * @type Boolean
-         */
-        haschildren : {
-            value : false,
-            validator : Y.Lang.isBool
-        },
-        /**
-         * An array of other branches that appear as children of this branch.
-         * @attribute children
-         * @type Array
-         */
-        children : {
-            value : [],
-            validator : Y.Lang.isArray
-        }
-    }
-});
diff --git a/blocks/navigation/yui/src/navigation/meta/navigation.json b/blocks/navigation/yui/src/navigation/meta/navigation.json
deleted file mode 100644 (file)
index c544b51..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-{
-  "moodle-block_navigation-navigation": {
-    "requires": [
-        "base",
-        "io-base",
-        "node",
-        "event-synthetic",
-        "event-delegate",
-        "json-parse"
-    ]
-  }
-}
index de57a2d..c8b7f2c 100644 (file)
@@ -93,7 +93,8 @@ class block_news_items extends block_base {
             // descending order. The call to default sort order here will use
             // that unless the discussion that post is in has a timestart set
             // in the future.
-            $sort = forum_get_default_sort_order(true, 'p.modified');
+            // This sort will ignore pinned posts as we want the most recent.
+            $sort = forum_get_default_sort_order(true, 'p.modified', 'd', false);
             if (! $discussions = forum_get_discussions($cm, $sort, false,
                                                        $currentgroup, $this->page->course->newsitems) ) {
                 $text .= '('.get_string('nonews', 'forum').')';
index 68a13ac..e41e68c 100644 (file)
 // You should have received a copy of the GNU General Public License
 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
 
+/**
+ * Contains block_rss_client
+ * @package    block_rss_client
+ * @copyright  Daryl Hawes
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL
+ */
+
 /**
  * A block which displays Remote feeds
  *
         }
     }
 
+    /**
+     * Gets the footer, which is the channel link of the last feed in our list of feeds
+     *
+     * @param array $feedrecords The feed records from the database.
+     * @return block_rss_client\output\footer|null The renderable footer or null if none should be displayed.
+     */
+    protected function get_footer($feedrecords) {
+        $footer = null;
+
+        if ($this->config->block_rss_client_show_channel_link) {
+            global $CFG;
+            require_once($CFG->libdir.'/simplepie/moodle_simplepie.php');
+
+            $feedrecord     = array_pop($feedrecords);
+            $feed           = new moodle_simplepie($feedrecord->url);
+            $channellink    = new moodle_url($feed->get_link());
+
+            if (!empty($channellink)) {
+                $footer = new block_rss_client\output\footer($channellink);
+            }
+        }
+
+        return $footer;
+    }
+
     function get_content() {
         global $CFG, $DB;
 
             $maxentries = intval($CFG->block_rss_client_num_entries);
         }
 
-
         /* ---------------------------------
          * Begin Normal Display of Block Content
          * --------------------------------- */
 
-        $output = '';
-
+        $renderer = $this->page->get_renderer('block_rss_client');
+        $block = new \block_rss_client\output\block();
 
         if (!empty($this->config->rssid)) {
-            list($rss_ids_sql, $params) = $DB->get_in_or_equal($this->config->rssid);
-
-            $rss_feeds = $DB->get_records_select('block_rss_client', "id $rss_ids_sql", $params);
+            list($rssidssql, $params) = $DB->get_in_or_equal($this->config->rssid);
+            $rssfeeds = $DB->get_records_select('block_rss_client', "id $rssidssql", $params);
+
+            if (!empty($rssfeeds)) {
+                $showtitle = false;
+                if (count($rssfeeds) > 1) {
+                    // When many feeds show the title for each feed.
+                    $showtitle = true;
+                }
 
-            $showtitle = false;
-            if (count($rss_feeds) > 1) {
-                // when many feeds show the title for each feed
-                $showtitle = true;
-            }
+                foreach ($rssfeeds as $feed) {
+                    if ($renderablefeed = $this->get_feed($feed, $maxentries, $showtitle)) {
+                        $block->add_feed($renderablefeed);
+                    }
+                }
 
-            foreach($rss_feeds as $feed){
-                $output.= $this->get_feed_html($feed, $maxentries, $showtitle);
+                $footer = $this->get_footer($rssfeeds);
             }
         }
 
-        $this->content->text = $output;
+        $this->content->text = $renderer->render_block($block);
+        if (isset($footer)) {
+            $this->content->footer = $renderer->render_footer($footer);
+        }
 
         return $this->content;
     }
      * @param mixed feedrecord The feed record from the database
      * @param int maxentries The maximum number of entries to be displayed
      * @param boolean showtitle Should the feed title be displayed in html
-     * @return string html representing the rss feed content
+     * @return block_rss_client\output\feed|null The renderable feed or null of there is an error
      */
-    function get_feed_html($feedrecord, $maxentries, $showtitle){
+    public function get_feed($feedrecord, $maxentries, $showtitle) {
         global $CFG;
         require_once($CFG->libdir.'/simplepie/moodle_simplepie.php');
 
-        $feed = new moodle_simplepie($feedrecord->url);
+        $simplepiefeed = new moodle_simplepie($feedrecord->url);
 
         if(isset($CFG->block_rss_client_timeout)){
-            $feed->set_cache_duration($CFG->block_rss_client_timeout*60);
-        }
-
-        if ($CFG->debugdeveloper && $feed->error()) {
-            return '<p>'. $feedrecord->url .' Failed with code: '.$feed->error().'</p>';
+            $simplepiefeed->set_cache_duration($CFG->block_rss_client_timeout * 60);
         }
 
-        $r = ''; // return string
-
-        if($this->config->block_rss_client_show_channel_image){
-            if($image = $feed->get_image_url()){
-                $imagetitle = s($feed->get_image_title());
-                $imagelink  = $feed->get_image_link();
-
-                $r.='<div class="image" title="'.$imagetitle.'">'."\n";
-                if($imagelink){
-                    $r.='<a href="'.$imagelink.'">';
-                }
-                $r.='<img src="'.$image.'" alt="'.$imagetitle.'" />'."\n";
-                if($imagelink){
-                    $r.='</a>';
-                }
-                $r.= '</div>';
-            }
+        if ($simplepiefeed->error()) {
+            debugging($feedrecord->url .' Failed with code: '.$simplepiefeed->error());
+            return null;
         }
 
         if(empty($feedrecord->preferredtitle)){
-            $feedtitle = $this->format_title($feed->get_title());
+            $feedtitle = $this->format_title($simplepiefeed->get_title());
         }else{
             $feedtitle = $this->format_title($feedrecord->preferredtitle);
         }
 
-        if($showtitle){
-            $r.='<div class="title">'.$feedtitle.'</div>';
-        }
-
-
-        $r.='<ul class="list no-overflow">'."\n";
-
-        $feeditems = $feed->get_items(0, $maxentries);
-        foreach($feeditems as $item){
-            $r.= $this->get_item_html($item);
-        }
-
-        $r.='</ul>';
-
-
-        if ($this->config->block_rss_client_show_channel_link) {
-
-            $channellink = $feed->get_link();
-
-            if (!empty($channellink)){
-                //NOTE: this means the 'last feed' display wins the block title - but
-                //this is exiting behaviour..
-                $this->content->footer = '<a href="'.htmlspecialchars(clean_param($channellink,PARAM_URL)).'">'. get_string('clientchannellink', 'block_rss_client') .'</a>';
-            }
-        }
-
         if (empty($this->config->title)){
             //NOTE: this means the 'last feed' displayed wins the block title - but
             //this is exiting behaviour..
             $this->title = strip_tags($feedtitle);
         }
 
-        return $r;
-    }
-
-
-    /**
-     * Returns the html list item of a feed item
-     *
-     * @param mixed item simplepie_item representing the feed item
-     * @return string html li representing the rss feed item
-     */
-    function get_item_html($item){
-
-        $link        = $item->get_link();
-        $title       = $item->get_title();
-        $description = $item->get_description();
-
-
-        if(empty($title)){
-            // no title present, use portion of description
-            $title = core_text::substr(strip_tags($description), 0, 20) . '...';
-        }else{
-            $title = break_up_long_words($title, 30);
+        $feed = new \block_rss_client\output\feed($feedtitle, $showtitle, $this->config->block_rss_client_show_channel_image);
+
+        if ($simplepieitems = $simplepiefeed->get_items(0, $maxentries)) {
+            foreach ($simplepieitems as $simplepieitem) {
+                try {
+                    $item = new \block_rss_client\output\item(
+                        $simplepieitem->get_id(),
+                        new moodle_url($simplepieitem->get_link()),
+                        $simplepieitem->get_title(),
+                        $simplepieitem->get_description(),
+                        new moodle_url($simplepieitem->get_permalink()),
+                        $simplepieitem->get_date('U'),
+                        $this->config->display_description
+                    );
+
+                    $feed->add_item($item);
+                } catch (moodle_exception $e) {
+                    // If there is an error with the RSS item, we don't
+                    // want to crash the page. Specifically, moodle_url can
+                    //&