Merge branch 'wip-MDL-49522-master' of git://github.com/abgreeve/moodle
authorDan Poltawski <dan@moodle.com>
Mon, 30 Mar 2015 11:18:41 +0000 (12:18 +0100)
committerDan Poltawski <dan@moodle.com>
Mon, 30 Mar 2015 11:18:41 +0000 (12:18 +0100)
148 files changed:
admin/registration/lib.php
admin/repository.php
admin/tool/behat/cli/init.php
admin/tool/behat/cli/run.php
backup/moodle2/backup_stepslib.php
backup/moodle2/restore_stepslib.php
badges/criteria/award_criteria.php
badges/criteria/award_criteria_course.php
badges/criteria/award_criteria_overall.php
badges/criteria_action.php
badges/criteria_form.php
badges/criteria_settings.php
badges/renderer.php
badges/tests/badgeslib_test.php
badges/tests/behat/award_badge.feature
blocks/activity_results/backup/moodle2/restore_activity_results_block_task.class.php [new file with mode: 0644]
blocks/activity_results/block_activity_results.php [new file with mode: 0644]
blocks/activity_results/db/access.php [new file with mode: 0644]
blocks/activity_results/edit_form.php [new file with mode: 0644]
blocks/activity_results/lang/en/block_activity_results.php [new file with mode: 0644]
blocks/activity_results/styles.css [new file with mode: 0644]
blocks/activity_results/tests/behat/addblockinactivity.feature [new file with mode: 0644]
blocks/activity_results/tests/behat/addunconfiguredblock.feature [new file with mode: 0644]
blocks/activity_results/tests/behat/addunsupportedactivity.feature [new file with mode: 0644]
blocks/activity_results/tests/behat/highscoreswithoutgroups.feature [new file with mode: 0644]
blocks/activity_results/tests/behat/highscoreswithseperategroups.feature [new file with mode: 0644]
blocks/activity_results/tests/behat/highscoreswithvisiblegroups.feature [new file with mode: 0644]
blocks/activity_results/tests/behat/lowscoreswithoutgroups.feature [new file with mode: 0644]
blocks/activity_results/tests/behat/lowscoreswithseperategroups.feature [new file with mode: 0644]
blocks/activity_results/tests/behat/lowscoreswithvisiblegroups.feature [new file with mode: 0644]
blocks/activity_results/version.php [new file with mode: 0644]
blocks/quiz_results/backup/moodle2/restore_quiz_results_block_task.class.php
blocks/quiz_results/block_quiz_results.php
blocks/quiz_results/db/install.php [new file with mode: 0644]
blocks/quiz_results/db/upgrade.php [new file with mode: 0644]
blocks/quiz_results/edit_form.php [deleted file]
blocks/quiz_results/lang/en/block_quiz_results.php
blocks/quiz_results/lang/en/depreciated.txt [new file with mode: 0644]
blocks/quiz_results/styles.css [deleted file]
blocks/quiz_results/version.php
calendar/lib.php
calendar/tests/behat/calendar.feature
completion/classes/external.php [new file with mode: 0644]
completion/tests/externallib_test.php [new file with mode: 0644]
composer.json
course/modedit.php
course/modlib.php
course/moodleform_mod.php
course/yui/build/moodle-course-dragdrop/moodle-course-dragdrop-debug.js
course/yui/build/moodle-course-dragdrop/moodle-course-dragdrop-min.js
course/yui/build/moodle-course-dragdrop/moodle-course-dragdrop.js
course/yui/src/dragdrop/js/resource.js
enrol/paypal/lib.php
grade/grading/form/guide/lib.php
grade/grading/form/guide/tests/guide_test.php [new file with mode: 0644]
grade/report/user/styles.css
grade/tests/behat/grade_to_pass.feature [new file with mode: 0644]
install/lang/oc_lnc/install.php [new file with mode: 0644]
lang/en/badges.php
lang/en/grades.php
lang/en/moodle.php
lib/classes/plugin_manager.php
lib/classes/plugininfo/repository.php
lib/classes/task/scheduled_task.php
lib/coursecatlib.php
lib/db/access.php
lib/db/install.xml
lib/db/services.php
lib/db/tasks.php
lib/db/upgrade.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/clean.js
lib/editor/atto/yui/src/editor/js/editor.js
lib/moodlelib.php
lib/tests/behat/behat_data_generators.php
lib/tests/regex_test.php [new file with mode: 0644]
lib/tests/scheduled_task_test.php
lib/yui/build/moodle-core-checknet/moodle-core-checknet-debug.js
lib/yui/build/moodle-core-checknet/moodle-core-checknet-min.js
lib/yui/build/moodle-core-checknet/moodle-core-checknet.js
lib/yui/src/checknet/js/checknet.js
mod/book/db/upgradelib.php
mod/choice/backup/moodle2/backup_choice_stepslib.php
mod/choice/db/install.xml
mod/choice/db/upgrade.php
mod/choice/lang/en/choice.php
mod/choice/lib.php
mod/choice/mod_form.php
mod/choice/report.php
mod/choice/tests/behat/include_inactive.feature [new file with mode: 0644]
mod/choice/version.php
mod/choice/view.php
mod/data/classes/external.php [new file with mode: 0644]
mod/data/db/services.php [new file with mode: 0644]
mod/data/tests/externallib_test.php [new file with mode: 0644]
mod/data/version.php
mod/feedback/lib.php
mod/glossary/import.php
mod/glossary/lib.php
mod/imscp/lib.php
mod/imscp/tests/lib_test.php [new file with mode: 0644]
mod/imscp/view.php
mod/lesson/classes/event/lesson_restarted.php [new file with mode: 0644]
mod/lesson/classes/event/lesson_resumed.php [new file with mode: 0644]
mod/lesson/classes/event/page_moved.php [new file with mode: 0644]
mod/lesson/editpage.php
mod/lesson/lang/en/lesson.php
mod/lesson/lesson.php
mod/lesson/locallib.php
mod/lesson/renderer.php
mod/lesson/tests/events_test.php
mod/lesson/version.php
mod/quiz/lang/en/quiz.php
mod/quiz/lib.php
mod/quiz/styles.css
mod/quiz/tests/behat/quiz_reset.feature [new file with mode: 0644]
mod/scorm/locallib.php
mod/upgrade.txt
mod/workshop/lang/en/workshop.php
mod/workshop/lib.php
mod/workshop/mod_form.php
phpunit.xml.dist
question/classes/bank/creator_name_column.php
question/classes/bank/modifier_name_column.php
theme/bootstrapbase/amd/build/bootstrap.min.js [new file with mode: 0644]
theme/bootstrapbase/amd/src/bootstrap.js [new file with mode: 0644]
theme/bootstrapbase/javascript/moodlebootstrap.js
theme/bootstrapbase/less/moodle/core.less
theme/bootstrapbase/style/moodle.css
theme/bootstrapbase/yui/build/moodle-theme_bootstrapbase-bootstrap/moodle-theme_bootstrapbase-bootstrap-debug.js [deleted file]
theme/bootstrapbase/yui/build/moodle-theme_bootstrapbase-bootstrap/moodle-theme_bootstrapbase-bootstrap-min.js [deleted file]
theme/bootstrapbase/yui/build/moodle-theme_bootstrapbase-bootstrap/moodle-theme_bootstrapbase-bootstrap.js [deleted file]
theme/bootstrapbase/yui/src/bootstrap/build.json [deleted file]
theme/bootstrapbase/yui/src/bootstrap/js/bootstrap.js [deleted file]
theme/bootstrapbase/yui/src/bootstrap/js/bootstrapcollapse.js [deleted file]
theme/bootstrapbase/yui/src/bootstrap/js/bootstrapdropdown.js [deleted file]
theme/bootstrapbase/yui/src/bootstrap/js/bootstrapengine.js [deleted file]
theme/bootstrapbase/yui/src/bootstrap/meta/bootstrap.json [deleted file]
theme/clean/layout/columns3.php
theme/yui_combo.php
user/externallib.php
user/messageselect.php
user/tests/externallib_test.php
version.php
webservice/externallib.php
webservice/tests/externallib_test.php

index 6aed437..5a521e1 100644 (file)
@@ -53,32 +53,30 @@ class registration_manager {
     public function cron() {
         global $CFG;
         if (extension_loaded('xmlrpc')) {
-            //check if the last registration cron update was less than a week ago
-            $lastcron = get_config('registration', 'crontime');
-            if ($lastcron === false or $lastcron < strtotime("-7 day")) { //set to a week, see MDL-23704
-                $function = 'hub_update_site_info';
-                require_once($CFG->dirroot . "/webservice/xmlrpc/lib.php");
+            $function = 'hub_update_site_info';
+            require_once($CFG->dirroot . "/webservice/xmlrpc/lib.php");
 
-                //update all hub where the site is registered on
-                $hubs = $this->get_registered_on_hubs();
-                foreach ($hubs as $hub) {
-                    //update the registration
-                    $siteinfo = $this->get_site_info($hub->huburl);
-                    $params = array('siteinfo' => $siteinfo);
-                    $serverurl = $hub->huburl . "/local/hub/webservice/webservices.php";
-                    $xmlrpcclient = new webservice_xmlrpc_client($serverurl, $hub->token);
-                    try {
-                        $result = $xmlrpcclient->call($function, $params);
-                        $this->update_registeredhub($hub); // To update timemodified.
-                        mtrace(get_string('siteupdatedcron', 'hub', $hub->hubname));
-                    } catch (Exception $e) {
-                        $errorparam = new stdClass();
-                        $errorparam->errormessage = $e->getMessage();
-                        $errorparam->hubname = $hub->hubname;
-                        mtrace(get_string('errorcron', 'hub', $errorparam));
-                    }
+            // Update all hubs where the site is registered.
+            $hubs = $this->get_registered_on_hubs();
+            if (empty($hubs)) {
+                mtrace(get_string('registrationwarning', 'admin'));
+            }
+            foreach ($hubs as $hub) {
+                // Update the registration.
+                $siteinfo = $this->get_site_info($hub->huburl);
+                $params = array('siteinfo' => $siteinfo);
+                $serverurl = $hub->huburl . "/local/hub/webservice/webservices.php";
+                $xmlrpcclient = new webservice_xmlrpc_client($serverurl, $hub->token);
+                try {
+                    $result = $xmlrpcclient->call($function, $params);
+                    $this->update_registeredhub($hub); // To update timemodified.
+                    mtrace(get_string('siteupdatedcron', 'hub', $hub->hubname));
+                } catch (Exception $e) {
+                    $errorparam = new stdClass();
+                    $errorparam->errormessage = $e->getMessage();
+                    $errorparam->hubname = $hub->hubname;
+                    mtrace(get_string('errorcron', 'hub', $errorparam));
                 }
-                set_config('crontime', time(), 'registration');
             }
         } else {
             mtrace(get_string('errorcronnoxmlrpc', 'hub'));
index 31fd40c..e01490e 100644 (file)
@@ -264,6 +264,7 @@ if (($action == 'edit') || ($action == 'new')) {
     $strshow = get_string('on', 'repository');
     $strhide = get_string('off', 'repository');
     $strdelete = get_string('disabled', 'repository');
+    $struninstall = get_string('uninstallplugin', 'core_admin');
 
     $actionchoicesforexisting = array(
         'show' => $strshow,
@@ -286,9 +287,9 @@ if (($action == 'edit') || ($action == 'new')) {
 
     // Table to list plug-ins
     $table = new html_table();
-    $table->head = array(get_string('name'), get_string('isactive', 'repository'), get_string('order'), $settingsstr);
+    $table->head = array(get_string('name'), get_string('isactive', 'repository'), get_string('order'), $settingsstr, $struninstall);
 
-    $table->colclasses = array('leftalign', 'centeralign', 'centeralign', 'centeralign', 'centeralign');
+    $table->colclasses = array('leftalign', 'centeralign', 'centeralign', 'centeralign', 'centeralign', 'centeralign');
     $table->id = 'repositoriessetting';
     $table->data = array();
     $table->attributes['class'] = 'admintable generaltable';
@@ -384,7 +385,12 @@ if (($action == 'edit') || ($action == 'new')) {
 
             $updowncount++;
 
-            $table->data[] = array($i->get_readablename(), $OUTPUT->render($select), $updown, $settings);
+            $uninstall = '';
+            if ($uninstallurl = core_plugin_manager::instance()->get_uninstall_url('repository_' . $typename, 'manage')) {
+                $uninstall = html_writer::link($uninstallurl, $struninstall);
+            }
+
+            $table->data[] = array($i->get_readablename(), $OUTPUT->render($select), $updown, $settings, $uninstall);
 
             if (!in_array($typename, $alreadyplugins)) {
                 $alreadyplugins[] = $typename;
@@ -400,7 +406,11 @@ if (($action == 'edit') || ($action == 'new')) {
             if (!in_array($plugin, $alreadyplugins)) {
                 $select = new single_select(repository_action_url($plugin, 'repos'), 'action', $actionchoicesfornew, 'delete', null, 'applyto' . basename($plugin));
                 $select->set_label(get_string('action'), array('class' => 'accesshide'));
-                $table->data[] = array(get_string('pluginname', 'repository_'.$plugin), $OUTPUT->render($select), '', '');
+                $uninstall = '';
+                if ($uninstallurl = core_plugin_manager::instance()->get_uninstall_url('repository_' . $plugin, 'manage')) {
+                    $uninstall = html_writer::link($uninstallurl, $struninstall);
+                }
+                $table->data[] = array(get_string('pluginname', 'repository_'.$plugin), $OUTPUT->render($select), '', '', $uninstall);
             }
         }
     }
index 52f783f..d4300d9 100644 (file)
@@ -96,17 +96,23 @@ if ($options['parallel']) {
 $cwd = getcwd();
 $output = null;
 
+$installcomposer = true;
 // If behat dependencies not downloaded then do it first, else symfony/process can't be used.
 if ($options['parallel'] && !file_exists(__DIR__ . "/../../../../vendor/autoload.php")) {
-    $code = BEHAT_EXITCODE_COMPOSER;
-} else {
-    chdir(__DIR__);
-    exec("php $utilfile --diag $paralleloption", $output, $code);
+    $installcomposer = false;
+    testing_update_composer_dependencies();
 }
 
+chdir(__DIR__);
+exec("php $utilfile --diag $paralleloption", $output, $code);
+
 // Check if composer needs to be updated.
-if (($code == BEHAT_EXITCODE_INSTALL) || $code == BEHAT_EXITCODE_REINSTALL || $code == BEHAT_EXITCODE_COMPOSER) {
+if ($installcomposer &&
+        ($code == BEHAT_EXITCODE_INSTALL || $code == BEHAT_EXITCODE_REINSTALL || $code == BEHAT_EXITCODE_COMPOSER)) {
     testing_update_composer_dependencies();
+    // Check again for behat test site and see if it's install or re-install.
+    chdir(__DIR__);
+    exec("php $utilfile --diag $paralleloption", $output, $code);
 }
 
 if ($code == 0) {
@@ -137,16 +143,6 @@ if ($code == 0) {
         exit($code);
     }
 
-} else if ($code == BEHAT_EXITCODE_COMPOSER) {
-    // Missing Behat dependencies.
-    // Returning to admin/tool/behat/cli.
-    chdir(__DIR__);
-    passthru("php $utilfile --install $paralleloption", $code);
-    if ($code != 0) {
-        chdir($cwd);
-        exit($code);
-    }
-
 } else {
     // Generic error, we just output it.
     echo implode("\n", $output)."\n";
index 92c393c..4240747 100644 (file)
@@ -134,13 +134,19 @@ $tags = '';
 
 if ($options['profile']) {
     $profile = $options['profile'];
-    if (empty($CFG->behat_config[$profile]['filters']['tags'])) {
-        echo "Invaid profile passed: " . $profile;
+    if (!isset($CFG->behat_config[$profile])) {
+        echo "Invalid profile passed: " . $profile;
         exit(1);
     }
-    $tags = $CFG->behat_config[$profile]['filters']['tags'];
     $extraopts[] = '--profile=\'' . $profile . "'";
-} else if ($options['tags']) {
+    // By default, profile tags will be used.
+    if (!empty($CFG->behat_config[$profile]['filters']['tags'])) {
+        $tags = $CFG->behat_config[$profile]['filters']['tags'];
+    }
+}
+
+// Command line tags have precedence (std behat behavior).
+if ($options['tags']) {
     $tags = $options['tags'];
     $extraopts[] = '--tags="' . $tags . '"';
 }
index c761eba..edad7c9 100644 (file)
@@ -825,7 +825,7 @@ class backup_badges_structure_step extends backup_structure_step {
 
         $criteria = new backup_nested_element('criteria');
         $criterion = new backup_nested_element('criterion', array('id'), array('badgeid',
-                'criteriatype', 'method'));
+                'criteriatype', 'method', 'description', 'descriptionformat'));
 
         $parameters = new backup_nested_element('parameters');
         $parameter = new backup_nested_element('parameter', array('id'), array('critid',
index ca66102..0ee1f4c 100644 (file)
@@ -1483,13 +1483,31 @@ class restore_section_structure_step extends restore_structure_step {
 
     public function process_course_format_options($data) {
         global $DB;
-        $data = (object)$data;
-        $oldid = $data->id;
-        unset($data->id);
-        $data->sectionid = $this->task->get_sectionid();
-        $data->courseid = $this->get_courseid();
-        $newid = $DB->insert_record('course_format_options', $data);
-        $this->set_mapping('course_format_options', $oldid, $newid);
+        static $courseformats = array();
+        $courseid = $this->get_courseid();
+        if (!array_key_exists($courseid, $courseformats)) {
+            // It is safe to have a static cache of course formats because format can not be changed after this point.
+            $courseformats[$courseid] = $DB->get_field('course', 'format', array('id' => $courseid));
+        }
+        $data = (array)$data;
+        if ($courseformats[$courseid] === $data['format']) {
+            // Import section format options only if both courses (the one that was backed up
+            // and the one we are restoring into) have same formats.
+            $params = array(
+                'courseid' => $this->get_courseid(),
+                'sectionid' => $this->task->get_sectionid(),
+                'format' => $data['format'],
+                'name' => $data['name']
+            );
+            if ($record = $DB->get_record('course_format_options', $params, 'id, value')) {
+                // Do not overwrite existing information.
+                $newid = $record->id;
+            } else {
+                $params['value'] = $data['value'];
+                $newid = $DB->insert_record('course_format_options', $params);
+            }
+            $this->set_mapping('course_format_options', $data['id'], $newid);
+        }
     }
 
     protected function after_execute() {
@@ -2269,9 +2287,11 @@ class restore_badges_structure_step extends restore_structure_step {
         $data = (object)$data;
 
         $params = array(
-                'badgeid'      => $this->get_new_parentid('badge'),
-                'criteriatype' => $data->criteriatype,
-                'method'       => $data->method
+                'badgeid'           => $this->get_new_parentid('badge'),
+                'criteriatype'      => $data->criteriatype,
+                'method'            => $data->method,
+                'description'       => isset($data->description) ? $data->description : '',
+                'descriptionformat' => isset($data->descriptionformat) ? $data->descriptionformat : 0,
         );
         $newid = $DB->insert_record('badge_criteria', $params);
         $this->set_mapping('criterion', $data->id, $newid);
index 8cc0a08..58ccf86 100644 (file)
@@ -88,9 +88,40 @@ $BADGE_CRITERIA_TYPES = array(
  */
 abstract class award_criteria {
 
+    /**
+     * ID of the criterion.
+     * @var integer
+     */
     public $id;
+
+    /**
+     * Aggregation method [BADGE_CRITERIA_AGGREGATION_ANY, BADGE_CRITERIA_AGGREGATION_ALL].
+     * @var integer
+     */
     public $method;
+
+    /**
+     * ID of a badge this criterion belongs to.
+     * @var integer
+     */
     public $badgeid;
+
+    /**
+     * Criterion HTML/plain text description.
+     * @var string
+     */
+    public $description;
+
+    /**
+     * Format of the criterion description.
+     * @var integer
+     */
+    public $descriptionformat;
+
+    /**
+     * Any additional parameters.
+     * @var array
+     */
     public $params = array();
 
     /**
@@ -102,6 +133,8 @@ abstract class award_criteria {
         $this->id = isset($params['id']) ? $params['id'] : 0;
         $this->method = isset($params['method']) ? $params['method'] : BADGE_CRITERIA_AGGREGATION_ANY;
         $this->badgeid = $params['badgeid'];
+        $this->description = isset($params['description']) ? $params['description'] : '';
+        $this->descriptionformat = isset($params['descriptionformat']) ? $params['descriptionformat'] : FORMAT_HTML;
         if (isset($params['id'])) {
             $this->params = $this->get_params($params['id']);
         }
@@ -220,6 +253,14 @@ abstract class award_criteria {
         }
         echo $OUTPUT->heading($this->get_title() . $OUTPUT->help_icon('criteria_' . $this->criteriatype, 'badges'), 3, 'main help');
 
+        if (!empty($this->description)) {
+            $badge = new badge($this->badgeid);
+            echo $OUTPUT->box(
+                format_text($this->description, $this->descriptionformat, array('context' => $badge->get_context())),
+                'criteria-description'
+                );
+        }
+
         if (!empty($this->params)) {
             if (count($this->params) > 1) {
                 echo $OUTPUT->box(get_string('criteria_descr_' . $this->criteriatype, 'badges',
@@ -305,23 +346,38 @@ abstract class award_criteria {
 
     /**
      * Saves intial criteria records with required parameters set up.
+     *
+     * @param array $params Values from the form or any other array.
      */
     public function save($params = array()) {
         global $DB;
+
+        // Figure out criteria description.
+        // If it is coming from the form editor, it is an array(text, format).
+        $description = '';
+        $descriptionformat = FORMAT_HTML;
+        if (isset($params['description']['text'])) {
+            $description = $params['description']['text'];
+            $descriptionformat = $params['description']['format'];
+        } else if (isset($params['description'])) {
+            $description = $params['description'];
+        }
+
         $fordb = new stdClass();
         $fordb->criteriatype = $this->criteriatype;
-        $fordb->method = isset($params->agg) ? $params->agg : $params['agg'];
+        $fordb->method = isset($params['agg']) ? $params['agg'] : BADGE_CRITERIA_AGGREGATION_ALL;
         $fordb->badgeid = $this->badgeid;
+        $fordb->description = $description;
+        $fordb->descriptionformat = $descriptionformat;
         $t = $DB->start_delegated_transaction();
 
-        // Unset unnecessary parameters supplied with form.
-        if (isset($params->agg)) {
-            unset($params->agg);
-        } else {
-            unset($params['agg']);
-        }
-        unset($params->submitbutton);
-        $params = array_filter((array)$params);
+        // Pick only params that are required by this criterion.
+        // Filter out empty values first.
+        $params = array_filter($params);
+        // Find out which param matches optional and required ones.
+        $match = array_merge($this->optional_params, array($this->required_param));
+        $regex = implode('|', array_map(create_function('$a', 'return $a . "_";'), $match));
+        $requiredkeys = preg_grep('/^(' . $regex . ').*$/', array_keys($params));
 
         if ($this->id !== 0) {
             $cid = $this->id;
@@ -331,7 +387,7 @@ abstract class award_criteria {
             $DB->update_record('badge_criteria', $fordb, true);
 
             $existing = $DB->get_fieldset_select('badge_criteria_param', 'name', 'critid = ?', array($cid));
-            $todelete = array_diff($existing, array_keys($params));
+            $todelete = array_diff($existing, $requiredkeys);
 
             if (!empty($todelete)) {
                 // A workaround to add some disabled elements that are still being submitted from the form.
@@ -349,32 +405,32 @@ abstract class award_criteria {
                 $DB->delete_records_select('badge_criteria_param', 'critid = :critid AND name ' . $sql, $sqlparams);
             }
 
-            foreach ($params as $key => $value) {
+            foreach ($requiredkeys as $key) {
                 if (in_array($key, $existing)) {
                     $updp = $DB->get_record('badge_criteria_param', array('name' => $key, 'critid' => $cid));
-                    $updp->value = $value;
+                    $updp->value = $params[$key];
                     $DB->update_record('badge_criteria_param', $updp, true);
                 } else {
                     $newp = new stdClass();
                     $newp->critid = $cid;
                     $newp->name = $key;
-                    $newp->value = $value;
+                    $newp->value = $params[$key];
                     $DB->insert_record('badge_criteria_param', $newp);
                 }
             }
         } else {
             $cid = $DB->insert_record('badge_criteria', $fordb, true);
             if ($cid) {
-                foreach ($params as $key => $value) {
+                foreach ($requiredkeys as $key) {
                     $newp = new stdClass();
                     $newp->critid = $cid;
                     $newp->name = $key;
-                    $newp->value = $value;
+                    $newp->value = $params[$key];
                     $DB->insert_record('badge_criteria_param', $newp, false, true);
                 }
             }
-         }
-         $t->allow_commit();
+        }
+        $t->allow_commit();
     }
 
     /**
@@ -387,6 +443,8 @@ abstract class award_criteria {
         $fordb->criteriatype = $this->criteriatype;
         $fordb->method = $this->method;
         $fordb->badgeid = $newbadgeid;
+        $fordb->description = $this->description;
+        $fordb->descriptionformat = $this->descriptionformat;
         if (($newcrit = $DB->insert_record('badge_criteria', $fordb, true)) && isset($this->params)) {
             foreach ($this->params as $k => $param) {
                 foreach ($param as $key => $value) {
index 295d927..2582365 100644 (file)
@@ -75,6 +75,15 @@ class award_criteria_course extends award_criteria {
         }
         echo $OUTPUT->heading($this->get_title() . $OUTPUT->help_icon('criteria_' . $this->criteriatype, 'badges'), 3, 'main help');
 
+        if (!empty($this->description)) {
+            echo $OUTPUT->box(
+                format_text($this->description, $this->descriptionformat,
+                        array('context' => context_course::instance($this->courseid))
+                ),
+                'criteria-description'
+            );
+        }
+
         if (!empty($this->params)) {
             echo $OUTPUT->box(get_string('criteria_descr_' . $this->criteriatype, 'badges') . $this->get_details(), array('clearfix'));
         }
index 91a6a9d..7d6aad8 100644 (file)
@@ -45,10 +45,27 @@ class award_criteria_overall extends award_criteria {
         $prefix = 'criteria-' . $this->id;
         if (count($data->criteria) > 2) {
             echo $OUTPUT->box_start();
+            if (!empty($this->description)) {
+                $badge = new badge($this->badgeid);
+                echo $OUTPUT->box(
+                    format_text($this->description, $this->descriptionformat, array('context' => $badge->get_context())),
+                    'criteria-description');
+            }
             echo $OUTPUT->heading($this->get_title(), 2);
 
             $agg = $data->get_aggregation_methods();
             if (!$data->is_locked() && !$data->is_active()) {
+                $editurl = new moodle_url('/badges/criteria_settings.php',
+                               array('badgeid' => $this->badgeid,
+                                   'edit' => true,
+                                   'type' => $this->criteriatype,
+                                   'crit' => $this->id
+                               )
+                        );
+                $editaction = $OUTPUT->action_icon($editurl, new pix_icon('t/edit', get_string('edit')), null,
+                              array('class' => 'criteria-action'));
+                echo $OUTPUT->box($editaction, array('criteria-header'));
+
                 $url = new moodle_url('criteria.php', array('id' => $data->id, 'sesskey' => sesskey()));
                 $table = new html_table();
                 $table->attributes = array('class' => 'clearfix');
@@ -155,4 +172,38 @@ class award_criteria_overall extends award_criteria {
      */
     public function get_params($cid) {
     }
-}
\ No newline at end of file
+
+    /**
+     * Saves overall badge criteria description.
+     *
+     * @param array $params Values from the form or any other array.
+     */
+    public function save($params = array()) {
+        global $DB;
+
+        // Sort out criteria description.
+        // If it is coming from the form editor, it is an array of (text, format).
+        $description = '';
+        $descriptionformat = FORMAT_HTML;
+        if (isset($params['description']['text'])) {
+            $description = $params['description']['text'];
+            $descriptionformat = $params['description']['format'];
+        } else if (isset($params['description'])) {
+            $description = $params['description'];
+        }
+
+        $fordb = new stdClass();
+        $fordb->criteriatype = $this->criteriatype;
+        $fordb->badgeid = $this->badgeid;
+        $fordb->description = $description;
+        $fordb->descriptionformat = $descriptionformat;
+        if ($this->id !== 0) {
+            $fordb->id = $this->id;
+            $DB->update_record('badge_criteria', $fordb);
+        } else {
+            // New record in DB, set aggregation to ALL by default.
+            $fordb->method = BADGE_CRITERIA_AGGREGATION_ALL;
+            $DB->insert_record('badge_criteria', $fordb);
+        }
+    }
+}
index 3af6984..aef6ca0 100644 (file)
@@ -61,6 +61,9 @@ $PAGE->set_heading($badge->name);
 $PAGE->set_title($badge->name);
 
 if ($delete && has_capability('moodle/badges:configurecriteria', $context)) {
+    if ($type == BADGE_CRITERIA_TYPE_OVERALL) {
+        redirect($return, get_string('error:cannotdeletecriterion', 'badges'));
+    }
     if (!$confirm) {
         $optionsyes = array('confirm' => 1, 'sesskey' => sesskey(), 'badgeid' => $badgeid, 'delete' => true, 'type' => $type);
 
index 208060d..c8d18d1 100644 (file)
@@ -55,6 +55,15 @@ class edit_criteria_form extends moodleform {
                 $mform->addElement('html', html_writer::tag('div', $message));
                 $mform->addElement('submit', 'cancel', get_string('continue'));
             } else {
+                $mform->addElement('header', 'description_header', get_string('description'));
+                $mform->addElement('editor', 'description', '', null, null);
+                $mform->setType('description', PARAM_RAW);
+                $mform->setDefault('description', array(
+                        'text' => $criteria->description,
+                        'format' => $criteria->descriptionformat
+                    )
+                );
+
                 $mform->closeHeaderBefore('buttonar');
                 $this->add_action_buttons(true, get_string('save', 'badges'));
             }
@@ -69,7 +78,7 @@ class edit_criteria_form extends moodleform {
         $errors = parent::validation($data, $files);
         $addcourse = $this->_customdata['addcourse'];
 
-        if (!$addcourse) {
+        if (!$addcourse && isset($this->_customdata['criteria']->required_param)) {
             $required = $this->_customdata['criteria']->required_param;
             $pattern1 = '/^' . $required . '_(\d+)$/';
             $pattern2 = '/^' . $required . '_(\w+)$/';
@@ -91,4 +100,4 @@ class edit_criteria_form extends moodleform {
         }
         return $errors;
     }
-}
\ No newline at end of file
+}
index 32efa61..d31f3ab 100644 (file)
@@ -65,8 +65,9 @@ if ($badge->type == BADGE_TYPE_COURSE) {
     navigation_node::override_active_url($navurl, true);
 }
 
+$urlparams = array('badgeid' => $badgeid, 'edit' => $edit, 'type' => $type, 'crit' => $crit);
 $PAGE->set_context($context);
-$PAGE->set_url('/badges/criteria_settings.php');
+$PAGE->set_url('/badges/criteria_settings.php', $urlparams);
 $PAGE->set_heading($badge->name);
 $PAGE->set_title($badge->name);
 $PAGE->navbar->add($badge->name, new moodle_url('overview.php', array('id' => $badge->id)))->add(get_string('criteria_' . $type, 'badges'));
@@ -100,7 +101,7 @@ if (!empty($addcourse)) {
         $criteria_overall = award_criteria::build(array('criteriatype' => BADGE_CRITERIA_TYPE_OVERALL, 'badgeid' => $badge->id));
         $criteria_overall->save(array('agg' => BADGE_CRITERIA_AGGREGATION_ALL));
     }
-    $criteria->save($data);
+    $criteria->save((array)$data);
     $return->param('msg', $msg);
     redirect($return);
 }
index 3632182..d4fad08 100644 (file)
@@ -704,32 +704,81 @@ class core_badges_renderer extends plugin_renderer_base {
         return null;
     }
 
-    // Prints badge criteria.
+    /**
+     * Returns information about badge criteria in a list form.
+     *
+     * @param badge $badge Badge objects
+     * @param string $short Indicates whether to print full info about this badge
+     * @return string $output HTML string to output
+     */
     public function print_badge_criteria(badge $badge, $short = '') {
-        $output = "";
         $agg = $badge->get_aggregation_methods();
         if (empty($badge->criteria)) {
             return get_string('nocriteria', 'badges');
-        } else if (count($badge->criteria) == 2) {
+        }
+
+        $overalldescr = '';
+        $overall = $badge->criteria[BADGE_CRITERIA_TYPE_OVERALL];
+        if (!$short && !empty($overall->description)) {
+            $overalldescr = $this->output->box(
+                format_text($overall->description, $overall->descriptionformat, array('context' => $badge->get_context())),
+                'criteria-description'
+                );
+        }
+
+        // Get the condition string.
+        if (count($badge->criteria) == 2) {
+            $condition = '';
             if (!$short) {
-                $output .= get_string('criteria_descr', 'badges');
+                $condition = get_string('criteria_descr', 'badges');
             }
         } else {
-            $output .= get_string('criteria_descr_' . $short . BADGE_CRITERIA_TYPE_OVERALL, 'badges',
-                                    core_text::strtoupper($agg[$badge->get_aggregation_method()]));
+            $condition = get_string('criteria_descr_' . $short . BADGE_CRITERIA_TYPE_OVERALL, 'badges',
+                                      core_text::strtoupper($agg[$badge->get_aggregation_method()]));
         }
-        $items = array();
+
         unset($badge->criteria[BADGE_CRITERIA_TYPE_OVERALL]);
-        foreach ($badge->criteria as $type => $c) {
+
+        $items = array();
+        // If only one criterion left, make sure its description goe to the top.
+        if (count($badge->criteria) == 1) {
+            $c = reset($badge->criteria);
+            if (!$short && !empty($c->description)) {
+                $overalldescr = $this->output->box(
+                    format_text($c->description, $c->descriptionformat, array('context' => $badge->get_context())),
+                    'criteria-description'
+                    );
+            }
             if (count($c->params) == 1) {
-                $items[] = get_string('criteria_descr_single_' . $short . $type , 'badges') . $c->get_details($short);
+                $items[] = get_string('criteria_descr_single_' . $short . $c->criteriatype , 'badges') .
+                           $c->get_details($short);
             } else {
-                $items[] = get_string('criteria_descr_' . $short . $type , 'badges',
-                        core_text::strtoupper($agg[$badge->get_aggregation_method($type)])) . $c->get_details($short);
+                $items[] = get_string('criteria_descr_' . $short . $c->criteriatype, 'badges',
+                        core_text::strtoupper($agg[$badge->get_aggregation_method($c->criteriatype)])) .
+                        $c->get_details($short);
+            }
+        } else {
+            foreach ($badge->criteria as $type => $c) {
+                $criteriadescr = '';
+                if (!$short && !empty($c->description)) {
+                    $criteriadescr = $this->output->box(
+                        format_text($c->description, $c->descriptionformat, array('context' => $badge->get_context())),
+                        'criteria-description'
+                        );
+                }
+                if (count($c->params) == 1) {
+                    $items[] = get_string('criteria_descr_single_' . $short . $type , 'badges') .
+                               $c->get_details($short) . $criteriadescr;
+                } else {
+                    $items[] = get_string('criteria_descr_' . $short . $type , 'badges',
+                            core_text::strtoupper($agg[$badge->get_aggregation_method($type)])) .
+                            $c->get_details($short) .
+                            $criteriadescr;
+                }
             }
         }
-        $output .= html_writer::alist($items, array(), 'ul');
-        return $output;
+
+        return $overalldescr . $condition . html_writer::alist($items, array(), 'ul');;
     }
 
     // Prints criteria actions for badge editing.
index dc3f151..b628431 100644 (file)
@@ -152,6 +152,28 @@ class core_badges_badgeslib_testcase extends advanced_testcase {
         $this->assertCount(2, $badge->get_criteria());
     }
 
+    public function test_add_badge_criteria_description() {
+        $criteriaoverall = award_criteria::build(array('criteriatype' => BADGE_CRITERIA_TYPE_OVERALL, 'badgeid' => $this->badgeid));
+        $criteriaoverall->save(array(
+                'agg' => BADGE_CRITERIA_AGGREGATION_ALL,
+                'description' => 'Overall description',
+                'descriptionformat' => FORMAT_HTML
+        ));
+
+        $criteriaprofile = award_criteria::build(array('criteriatype' => BADGE_CRITERIA_TYPE_PROFILE, 'badgeid' => $this->badgeid));
+        $params = array(
+                'agg' => BADGE_CRITERIA_AGGREGATION_ALL,
+                'field_address' => 'address',
+                'description' => 'Description',
+                'descriptionformat' => FORMAT_HTML
+        );
+        $criteriaprofile->save($params);
+
+        $badge = new badge($this->badgeid);
+        $this->assertEquals('Overall description', $badge->criteria[BADGE_CRITERIA_TYPE_OVERALL]->description);
+        $this->assertEquals('Description', $badge->criteria[BADGE_CRITERIA_TYPE_PROFILE]->description);
+    }
+
     public function test_delete_badge_criteria() {
         $criteria_overall = award_criteria::build(array('criteriatype' => BADGE_CRITERIA_TYPE_OVERALL, 'badgeid' => $this->badgeid));
         $criteria_overall->save(array('agg' => BADGE_CRITERIA_AGGREGATION_ALL));
index bf504b0..a4e5cd4 100644 (file)
@@ -16,13 +16,17 @@ Feature: Award badges
     And I upload "badges/tests/behat/badge.png" file to "Image" filemanager
     And I press "Create badge"
     And I set the field "type" to "Profile completion"
+    And I expand all fieldsets
     And I set the field "First name" to "1"
     And I set the field "Email address" to "1"
     And I set the field "Phone" to "1"
+    And I set the field "id_description" to "Criterion description"
     When I press "Save"
     Then I should see "Profile completion"
     And I should see "First name"
     And I should see "Email address"
+    And I should see "Phone"
+    And I should see "Criterion description"
     And I should not see "Criteria for this badge have not been set up yet."
     And I press "Enable access"
     And I press "Continue"
diff --git a/blocks/activity_results/backup/moodle2/restore_activity_results_block_task.class.php b/blocks/activity_results/backup/moodle2/restore_activity_results_block_task.class.php
new file mode 100644 (file)
index 0000000..42be292
--- /dev/null
@@ -0,0 +1,115 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Define all the backup steps that will be used by the backup_block_task
+ * @package    block_activity_results
+ * @copyright  2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
+ * @copyright  2015 Stephen Bourget
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * Specialised restore task for the activity_results block
+ * (using execute_after_tasks for recoding of target activity)
+ *
+ * @copyright  2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class restore_activity_results_block_task extends restore_block_task {
+
+    /**
+     * Define (add) particular settings this activity can have
+     */
+    protected function define_my_settings() {
+    }
+
+    /**
+     * Define (add) particular steps this activity can have
+     */
+    protected function define_my_steps() {
+    }
+
+    /**
+     * Define the associated file areas
+     */
+    public function get_fileareas() {
+        return array(); // No associated fileareas.
+    }
+
+    /**
+     * Define special handling of configdata.
+     */
+    public function get_configdata_encoded_attributes() {
+        return array(); // No special handling of configdata.
+    }
+
+    /**
+     * This function, executed after all the tasks in the plan
+     * have been executed, will perform the recode of the
+     * target activity for the block. This must be done here
+     * and not in normal execution steps because the activity
+     * can be restored after the block.
+     */
+    public function after_restore() {
+        global $DB;
+
+        // Get the blockid.
+        $blockid = $this->get_blockid();
+
+        if ($configdata = $DB->get_field('block_instances', 'configdata', array('id' => $blockid))) {
+            $config = unserialize(base64_decode($configdata));
+            if (!empty($config->activityparentid)) {
+                // Get the mapping and replace it in config.
+                if ($mapping = restore_dbops::get_backup_ids_record($this->get_restoreid(),
+                    $config->activityparent, $config->activityparentid)) {
+
+                    // Update the parent module id (the id from mdl_quiz etc...)
+                    $config->activityparentid = $mapping->newitemid;
+
+                    // Get the grade_items record to update the activitygradeitemid.
+                    $info = $DB->get_record('grade_items',
+                            array('iteminstance' => $config->activityparentid, 'itemmodule' => $config->activityparent));
+
+                    // Update the activitygradeitemid the id from the grade_items table.
+                    $config->activitygradeitemid = $info->id;
+
+                    // Encode and save the config.
+                    $configdata = base64_encode(serialize($config));
+                    $DB->set_field('block_instances', 'configdata', $configdata, array('id' => $blockid));
+                }
+            }
+        }
+    }
+
+    /**
+     * Define the contents in the activity that must be
+     * processed by the link decoder
+     */
+    static public function define_decode_contents() {
+        return array();
+    }
+
+    /**
+     * Define the decoding rules for links belonging
+     * to the activity to be executed by the link decoder
+     */
+    static public function define_decode_rules() {
+        return array();
+    }
+}
diff --git a/blocks/activity_results/block_activity_results.php b/blocks/activity_results/block_activity_results.php
new file mode 100644 (file)
index 0000000..90cbf5f
--- /dev/null
@@ -0,0 +1,693 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Classes to enforce the various access rules that can apply to a activity.
+ *
+ * @package    block_activity_results
+ * @copyright  2009 Tim Hunt
+ * @copyright  2015 Stephen Bourget
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+require_once($CFG->dirroot . '/lib/grade/constants.php');
+
+define('B_ACTIVITYRESULTS_NAME_FORMAT_FULL', 1);
+define('B_ACTIVITYRESULTS_NAME_FORMAT_ID',   2);
+define('B_ACTIVITYRESULTS_NAME_FORMAT_ANON', 3);
+define('B_ACTIVITYRESULTS_GRADE_FORMAT_PCT', 1);
+define('B_ACTIVITYRESULTS_GRADE_FORMAT_FRA', 2);
+define('B_ACTIVITYRESULTS_GRADE_FORMAT_ABS', 3);
+define('B_ACTIVITYRESULTS_GRADE_FORMAT_SCALE', 4);
+
+/**
+ * Block activity_results class definition.
+ *
+ * This block can be added to a course page or a activity page to display of list of
+ * the best/worst students/groups in a particular activity.
+ *
+ * @package    block_activity_results
+ * @copyright  2009 Tim Hunt
+ * @copyright  2015 Stephen Bourget
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class block_activity_results extends block_base {
+
+    /**
+     * Core function used to initialize the block.
+     */
+    public function init() {
+        $this->title = get_string('pluginname', 'block_activity_results');
+    }
+
+    /**
+     * Core function, specifies where the block can be used.
+     * @return array
+     */
+    public function applicable_formats() {
+        return array('course-view' => true, 'mod' => true);
+    }
+
+    /**
+     * If this block belongs to a activity context, then return that activity's id.
+     * Otherwise, return 0.
+     * @return stdclass the activity record.
+     */
+    public function get_owning_activity() {
+        global $DB;
+
+        // Set some defaults.
+        $result = new stdClass();
+        $result->id = 0;
+
+        if (empty($this->instance->parentcontextid)) {
+            return $result;
+        }
+        $parentcontext = context::instance_by_id($this->instance->parentcontextid);
+        if ($parentcontext->contextlevel != CONTEXT_MODULE) {
+            return $result;
+        }
+        $cm = get_coursemodule_from_id($this->page->cm->modname, $parentcontext->instanceid);
+        if (!$cm) {
+            return $result;
+        }
+        // Get the grade_items id.
+        $rec = $DB->get_record('grade_items', array('iteminstance' => $cm->instance, 'itemmodule' => $this->page->cm->modname));
+        if (!$rec) {
+            return $result;
+        }
+        // See if it is a gradable activity.
+        if (($rec->gradetype != GRADE_TYPE_VALUE) || ($rec->gradetype != GRADE_TYPE_SCALE)) {
+            return $result;
+        }
+        return $rec;
+    }
+
+    /**
+     * Used to save the form config data
+     * @param stdclass $data
+     * @param bool $nolongerused
+     */
+    public function instance_config_save($data, $nolongerused = false) {
+        global $DB;
+        if (empty($data->activitygradeitemid)) {
+            // Figure out info about parent module.
+            $info = $this->get_owning_activity();
+            $data->activitygradeitemid = $info->id;
+            if ($info->id < 1) {
+                // No activity was selected.
+                $info->itemmodule = '';
+                $info->iteminstance = '';
+            } else {
+                $data->activityparent = $info->itemmodule;
+                $data->activityparentid = $info->iteminstance;
+            }
+        } else {
+            // Lookup info about the parent module (we have the id from mdl_grade_items.
+            $info = $DB->get_record('grade_items', array('id' => $data->activitygradeitemid));
+            $data->activityparent = $info->itemmodule;
+            $data->activityparentid = $info->iteminstance;
+        }
+        parent::instance_config_save($data);
+    }
+
+    /**
+     * Used to generate the content for the block.
+     * @return string
+     */
+    public function get_content() {
+        global $USER, $CFG, $DB;
+
+        if ($this->content !== null) {
+            return $this->content;
+        }
+
+        $this->content = new stdClass;
+        $this->content->text = '';
+        $this->content->footer = '';
+
+        if (empty($this->instance)) {
+            return $this->content;
+        }
+
+        // We are configured so use the configuration.
+        if (!empty($this->config->activitygradeitemid)) {
+            // We are configured.
+            $activitygradeitemid = $this->config->activitygradeitemid;
+
+            // Lookup the module in the grade_items table.
+            $activity = $DB->get_record('grade_items', array('id' => $activitygradeitemid));
+            if (empty($activity)) {
+                // Activity does not exist.
+                $this->content->text = get_string('error_emptyactivityrecord', 'block_activity_results');
+                return $this->content;
+            }
+            $courseid = $activity->courseid;
+            $inactivity = false;
+        } else {
+            // Not configured.
+            $activitygradeitemid = 0;
+        }
+
+        // Check to see if we are in the moule we are displaying results for.
+        if (!empty($this->config->activitygradeitemid)) {
+            if ($this->get_owning_activity()->id == $this->config->activitygradeitemid) {
+                $inactivity = true;
+            } else {
+                $inactivity = false;
+            }
+        }
+
+        // Activity ID is missing.
+        if (empty($activitygradeitemid)) {
+            $this->content->text = get_string('error_emptyactivityid', 'block_activity_results');
+            return $this->content;
+        }
+
+        // Check to see if we are configured.
+        if (empty($this->config->showbest) && empty($this->config->showworst)) {
+            $this->content->text = get_string('configuredtoshownothing', 'block_activity_results');
+            return $this->content;
+        }
+
+        // Check to see if it is a supported grade type.
+        if (empty($activity->gradetype) || ($activity->gradetype != GRADE_TYPE_VALUE && $activity->gradetype != GRADE_TYPE_SCALE)) {
+            $this->content->text = get_string('error_unsupportedgradetype', 'block_activity_results');
+            return $this->content;
+        }
+
+        // Get the grades for this activity.
+        $sql = 'SELECT * FROM {grade_grades}
+                 WHERE itemid = ? AND finalgrade is not NULL
+                 ORDER BY finalgrade, timemodified DESC';
+
+        $grades = $DB->get_records_sql($sql, array( $activitygradeitemid));
+
+        if (empty($grades) || $activity->hidden) {
+            // No grades available, The block will hide itself in this case.
+            return $this->content;
+        }
+
+        // Set up results.
+        $groupmode = NOGROUPS;
+        $best      = array();
+        $worst     = array();
+
+        if (!empty($this->config->nameformat)) {
+            $nameformat = $this->config->nameformat;
+        } else {
+            $nameformat = B_ACTIVITYRESULTS_NAME_FORMAT_FULL;
+        }
+
+        // Get $cm and context.
+        if ($inactivity) {
+            $cm = $this->page->cm;
+            $context = $this->page->context;
+        } else {
+            $cm = get_coursemodule_from_instance($activity->itemmodule, $activity->iteminstance, $courseid);
+            $context = context_module::instance($cm->id);
+        }
+
+        if (!empty($this->config->usegroups)) {
+            $groupmode = groups_get_activity_groupmode($cm);
+
+            if ($groupmode == SEPARATEGROUPS && has_capability('moodle/site:accessallgroups', $context)) {
+                // If you have the ability to see all groups then lets show them.
+                $groupmode = VISIBLEGROUPS;
+            }
+        }
+
+        switch ($groupmode) {
+            case VISIBLEGROUPS:
+                // Display group-mode results.
+                $groups = groups_get_all_groups($courseid);
+
+                if (empty($groups)) {
+                    // No groups exist, sorry.
+                    $this->content->text = get_string('error_nogroupsexist', 'block_activity_results');
+                    return $this->content;
+                }
+
+                // Find out all the userids which have a submitted grade.
+                $userids = array();
+                $gradeforuser = array();
+                foreach ($grades as $grade) {
+                    $userids[] = $grade->userid;
+                    $gradeforuser[$grade->userid] = (float)$grade->finalgrade;
+                }
+
+                // Now find which groups these users belong in.
+                list($usertest, $params) = $DB->get_in_or_equal($userids);
+                $params[] = $courseid;
+                $usergroups = $DB->get_records_sql('
+                        SELECT gm.id, gm.userid, gm.groupid, g.name
+                        FROM {groups} g
+                        LEFT JOIN {groups_members} gm ON g.id = gm.groupid
+                        WHERE gm.userid ' . $usertest . ' AND g.courseid = ?', $params);
+
+                // Now, iterate the grades again and sum them up for each group.
+                $groupgrades = array();
+                foreach ($usergroups as $usergroup) {
+                    if (!isset($groupgrades[$usergroup->groupid])) {
+                        $groupgrades[$usergroup->groupid] = array(
+                                'sum' => (float)$gradeforuser[$usergroup->userid],
+                                'number' => 1,
+                                'group' => $usergroup->name);
+                    } else {
+                        $groupgrades[$usergroup->groupid]['sum'] += $gradeforuser[$usergroup->userid];
+                        $groupgrades[$usergroup->groupid]['number'] += 1;
+                    }
+                }
+
+                foreach ($groupgrades as $groupid => $groupgrade) {
+                    $groupgrades[$groupid]['average'] = $groupgrades[$groupid]['sum'] / $groupgrades[$groupid]['number'];
+                }
+
+                // Sort groupgrades according to average grade, ascending.
+                uasort($groupgrades, create_function('$a, $b',
+                        'if($a["average"] == $b["average"]) return 0; return ($a["average"] > $b["average"] ? 1 : -1);'));
+
+                // How many groups do we have with graded member submissions to show?
+                $numbest  = empty($this->config->showbest) ? 0 : min($this->config->showbest, count($groupgrades));
+                $numworst = empty($this->config->showworst) ? 0 : min($this->config->showworst, count($groupgrades) - $numbest);
+
+                // Collect all the group results we are going to use in $best and $worst.
+                $remaining = $numbest;
+                $groupgrade = end($groupgrades);
+                while ($remaining--) {
+                    $best[key($groupgrades)] = $groupgrade['average'];
+                    $groupgrade = prev($groupgrades);
+                }
+
+                $remaining = $numworst;
+                $groupgrade = reset($groupgrades);
+                while ($remaining--) {
+                    $worst[key($groupgrades)] = $groupgrade['average'];
+                    $groupgrade = next($groupgrades);
+                }
+
+                // Ready for output!
+                if ($activity->gradetype == GRADE_TYPE_SCALE) {
+                    // We must display the results using scales.
+                    $gradeformat = B_ACTIVITYRESULTS_GRADE_FORMAT_SCALE;
+                    // Preload the scale.
+                    $scale = $this->get_scale($activity->scaleid);
+                } else if (intval(empty($this->config->gradeformat))) {
+                    $gradeformat = B_ACTIVITYRESULTS_GRADE_FORMAT_PCT;
+                } else {
+                    $gradeformat = $this->config->gradeformat;
+                }
+
+                // Generate the header.
+                $this->content->text .= $this->activity_link($activity, $cm);
+
+                if ($nameformat == B_ACTIVITYRESULTS_NAME_FORMAT_FULL) {
+                    if (has_capability('moodle/course:managegroups', $context)) {
+                        $grouplink = $CFG->wwwroot.'/group/overview.php?id='.$courseid.'&amp;group=';
+                    } else if (has_capability('moodle/course:viewparticipants', $context)) {
+                        $grouplink = $CFG->wwwroot.'/user/index.php?id='.$courseid.'&amp;group=';
+                    } else {
+                        $grouplink = '';
+                    }
+                }
+
+                $rank = 0;
+                if (!empty($best)) {
+                    $this->content->text .= '<table class="grades"><caption>';
+                    if ($numbest == 1) {
+                        $this->content->text .= get_string('bestgroupgrade', 'block_activity_results');
+                    } else {
+                        $this->content->text .= get_string('bestgroupgrades', 'block_activity_results', $numbest);
+                    }
+                    $this->content->text .= '</caption><colgroup class="number" />';
+                    $this->content->text .= '<colgroup class="name" /><colgroup class="grade" /><tbody>';
+                    foreach ($best as $groupid => $averagegrade) {
+                        switch ($nameformat) {
+                            case B_ACTIVITYRESULTS_NAME_FORMAT_ANON:
+                            case B_ACTIVITYRESULTS_NAME_FORMAT_ID:
+                                $thisname = get_string('group');
+                            break;
+                            default:
+                            case B_ACTIVITYRESULTS_NAME_FORMAT_FULL:
+                                if ($grouplink) {
+                                    $thisname = '<a href="'.$grouplink.$groupid.'">'.$groupgrades[$groupid]['group'].'</a>';
+                                } else {
+                                    $thisname = $groupgrades[$groupid]['group'];
+                                }
+                            break;
+                        }
+                        $this->content->text .= '<tr><td>'.(++$rank).'.</td><td>'.$thisname.'</td><td>';
+                        switch ($gradeformat) {
+                            case B_ACTIVITYRESULTS_GRADE_FORMAT_SCALE:
+                                // Round answer up and locate appropriate scale.
+                                $answer = (round($averagegrade, 0, PHP_ROUND_HALF_UP) - 1);
+                                if (isset($scale[$answer])) {
+                                    $this->content->text .= $scale[$answer];
+                                } else {
+                                    // Value is not in the scale.
+                                    $this->content->text .= get_string('unknown', 'block_activity_results');
+                                }
+                            break;
+                            case B_ACTIVITYRESULTS_GRADE_FORMAT_FRA:
+                                $this->content->text .= $this->activity_format_grade($averagegrade)
+                                    . '/' . $this->activity_format_grade($activity->grademax);
+                            break;
+                            case B_ACTIVITYRESULTS_GRADE_FORMAT_ABS:
+                                $this->content->text .= $this->activity_format_grade($averagegrade);
+                            break;
+                            default:
+                            case B_ACTIVITYRESULTS_GRADE_FORMAT_PCT:
+                                $this->content->text .= $this->activity_format_grade((float)$averagegrade /
+                                        (float)$activity->grademax * 100).'%';
+                            break;
+                        }
+                        $this->content->text .= '</td></tr>';
+                    }
+                    $this->content->text .= '</tbody></table>';
+                }
+
+                $rank = 0;
+                if (!empty($worst)) {
+                    $worst = array_reverse($worst, true);
+                    $this->content->text .= '<table class="grades"><caption>';
+                    if ($numworst == 1) {
+                        $this->content->text .= get_string('worstgroupgrade', 'block_activity_results');
+                    } else {
+                        $this->content->text .= get_string('worstgroupgrades', 'block_activity_results', $numworst);
+                    }
+                    $this->content->text .= '</caption><colgroup class="number" />';
+                    $this->content->text .= '<colgroup class="name" /><colgroup class="grade" /><tbody>';
+                    foreach ($worst as $groupid => $averagegrade) {
+                        switch ($nameformat) {
+                            case B_ACTIVITYRESULTS_NAME_FORMAT_ANON:
+                            case B_ACTIVITYRESULTS_NAME_FORMAT_ID:
+                                $thisname = get_string('group');
+                            break;
+                            default:
+                            case B_ACTIVITYRESULTS_NAME_FORMAT_FULL:
+                                if ($grouplink) {
+                                    $thisname = '<a href="'.$grouplink.$groupid.'">'.$groupgrades[$groupid]['group'].'</a>';
+                                } else {
+                                    $thisname = $groupgrades[$groupid]['group'];
+                                }
+                            break;
+                        }
+                        $this->content->text .= '<tr><td>'.(++$rank).'.</td><td>'.$thisname.'</td><td>';
+                        switch ($gradeformat) {
+                            case B_ACTIVITYRESULTS_GRADE_FORMAT_SCALE:
+                                // Round answer up and locate appropriate scale.
+                                $answer = (round($averagegrade, 0, PHP_ROUND_HALF_UP) - 1);
+                                if (isset($scale[$answer])) {
+                                    $this->content->text .= $scale[$answer];
+                                } else {
+                                    // Value is not in the scale.
+                                    $this->content->text .= get_string('unknown', 'block_activity_results');
+                                }
+                            break;
+                            case B_ACTIVITYRESULTS_GRADE_FORMAT_FRA:
+                                $this->content->text .= $this->activity_format_grade($averagegrade)
+                                    . '/' . $this->activity_format_grade($activity->grademax);
+                            break;
+                            case B_ACTIVITYRESULTS_GRADE_FORMAT_ABS:
+                                $this->content->text .= $this->activity_format_grade($averagegrade);
+                            break;
+                            default:
+                            case B_ACTIVITYRESULTS_GRADE_FORMAT_PCT:
+                                $this->content->text .= $this->activity_format_grade((float)$averagegrade /
+                                        (float)$activity->grademax * 100).'%';
+                            break;
+                        }
+                        $this->content->text .= '</td></tr>';
+                    }
+                    $this->content->text .= '</tbody></table>';
+                }
+            break;
+
+            case SEPARATEGROUPS:
+                // This is going to be just like no-groups mode, only we 'll filter
+                // out the grades from people not in our group.
+                if (!isloggedin()) {
+                    // Not logged in, so show nothing.
+                    return $this->content;
+                }
+
+                $mygroups = groups_get_all_groups($courseid, $USER->id);
+                if (empty($mygroups)) {
+                    // Not member of a group, show nothing.
+                    return $this->content;
+                }
+
+                // Get users from the same groups as me.
+                list($grouptest, $params) = $DB->get_in_or_equal(array_keys($mygroups));
+                $mygroupsusers = $DB->get_records_sql_menu(
+                        'SELECT DISTINCT userid, 1 FROM {groups_members} WHERE groupid ' . $grouptest,
+                        $params);
+
+                // Filter out the grades belonging to other users, and proceed as if there were no groups.
+                foreach ($grades as $key => $grade) {
+                    if (!isset($mygroupsusers[$grade->userid])) {
+                        unset($grades[$key]);
+                    }
+                }
+
+                // No break, fall through to the default case now we have filtered the $grades array.
+            default:
+            case NOGROUPS:
+                // Single user mode.
+                $numbest  = empty($this->config->showbest) ? 0 : min($this->config->showbest, count($grades));
+                $numworst = empty($this->config->showworst) ? 0 : min($this->config->showworst, count($grades) - $numbest);
+
+                // Collect all the usernames we are going to need.
+                $remaining = $numbest;
+                $grade = end($grades);
+                while ($remaining--) {
+                    $best[$grade->userid] = $grade->id;
+                    $grade = prev($grades);
+                }
+
+                $remaining = $numworst;
+                $grade = reset($grades);
+                while ($remaining--) {
+                    $worst[$grade->userid] = $grade->id;
+                    $grade = next($grades);
+                }
+
+                if (empty($best) && empty($worst)) {
+                    // Nothing to show, for some reason...
+                    return $this->content;
+                }
+
+                // Now grab all the users from the database.
+                $userids = array_merge(array_keys($best), array_keys($worst));
+                $fields = array_merge(array('id', 'idnumber'), get_all_user_name_fields());
+                $fields = implode(',', $fields);
+                $users = $DB->get_records_list('user', 'id', $userids, '', $fields);
+
+                // Ready for output!
+                if ($activity->gradetype == GRADE_TYPE_SCALE) {
+                    // We must display the results using scales.
+                    $gradeformat = B_ACTIVITYRESULTS_GRADE_FORMAT_SCALE;
+                    // Preload the scale.
+                    $scale = $this->get_scale($activity->scaleid);
+                } else if (intval(empty($this->config->gradeformat))) {
+                    $gradeformat = B_ACTIVITYRESULTS_GRADE_FORMAT_PCT;
+                } else {
+                    $gradeformat = $this->config->gradeformat;
+                }
+
+                // Generate the header.
+                $this->content->text .= $this->activity_link($activity, $cm);
+
+                $rank = 0;
+                if (!empty($best)) {
+                    $this->content->text .= '<table class="grades"><caption>';
+                    if ($numbest == 1) {
+                        $this->content->text .= get_string('bestgrade', 'block_activity_results');
+                    } else {
+                        $this->content->text .= get_string('bestgrades', 'block_activity_results', $numbest);
+                    }
+                    $this->content->text .= '</caption><colgroup class="number" />';
+                    $this->content->text .= '<colgroup class="name" /><colgroup class="grade" /><tbody>';
+                    foreach ($best as $userid => $gradeid) {
+                        switch ($nameformat) {
+                            case B_ACTIVITYRESULTS_NAME_FORMAT_ID:
+                                $thisname = get_string('user').' '.$users[$userid]->idnumber;
+                            break;
+                            case B_ACTIVITYRESULTS_NAME_FORMAT_ANON:
+                                $thisname = get_string('user');
+                            break;
+                            default:
+                            case B_ACTIVITYRESULTS_NAME_FORMAT_FULL:
+                                if (has_capability('moodle/user:viewdetails', $context)) {
+                                    $thisname = html_writer::link(new moodle_url('/user/view.php',
+                                        array('id' => $userid, 'course' => $courseid)), fullname($users[$userid]));
+                                } else {
+                                    $thisname = fullname($users[$userid]);
+                                }
+                            break;
+                        }
+                        $this->content->text .= '<tr><td>'.(++$rank).'.</td><td>'.$thisname.'</td><td>';
+                        switch ($gradeformat) {
+                            case B_ACTIVITYRESULTS_GRADE_FORMAT_SCALE:
+                                // Round answer up and locate appropriate scale.
+                                $answer = (round($grades[$gradeid]->finalgrade, 0, PHP_ROUND_HALF_UP) - 1);
+                                if (isset($scale[$answer])) {
+                                    $this->content->text .= $scale[$answer];
+                                } else {
+                                    // Value is not in the scale.
+                                    $this->content->text .= get_string('unknown', 'block_activity_results');
+                                }
+                            break;
+                            case B_ACTIVITYRESULTS_GRADE_FORMAT_FRA:
+                                $this->content->text .= $this->activity_format_grade($grades[$gradeid]->finalgrade);
+                                $this->content->text .= '/'.$this->activity_format_grade($activity->grademax);
+                            break;
+                            case B_ACTIVITYRESULTS_GRADE_FORMAT_ABS:
+                                $this->content->text .= $this->activity_format_grade($grades[$gradeid]->finalgrade);
+                            break;
+                            default:
+                            case B_ACTIVITYRESULTS_GRADE_FORMAT_PCT:
+                                if ($activity->grademax) {
+                                    $this->content->text .= $this->activity_format_grade((float)$grades[$gradeid]->finalgrade /
+                                            (float)$activity->grademax * 100).'%';
+                                } else {
+                                    $this->content->text .= '--%';
+                                }
+                            break;
+                        }
+                        $this->content->text .= '</td></tr>';
+                    }
+                    $this->content->text .= '</tbody></table>';
+                }
+
+                $rank = 0;
+                if (!empty($worst)) {
+                    $worst = array_reverse($worst, true);
+                    $this->content->text .= '<table class="grades"><caption>';
+                    if ($numbest == 1) {
+                        $this->content->text .= get_string('worstgrade', 'block_activity_results');
+                    } else {
+                        $this->content->text .= get_string('worstgrades', 'block_activity_results', $numworst);
+                    }
+                    $this->content->text .= '</caption><colgroup class="number" />';
+                    $this->content->text .= '<colgroup class="name" /><colgroup class="grade" /><tbody>';
+                    foreach ($worst as $userid => $gradeid) {
+                        switch ($nameformat) {
+                            case B_ACTIVITYRESULTS_NAME_FORMAT_ID:
+                                $thisname = get_string('user').' '.$users[$userid]->idnumber;
+                            break;
+                            case B_ACTIVITYRESULTS_NAME_FORMAT_ANON:
+                                $thisname = get_string('user');
+                            break;
+                            default:
+                            case B_ACTIVITYRESULTS_NAME_FORMAT_FULL:
+                                if (has_capability('moodle/user:viewdetails', $context)) {
+                                    $thisname = html_writer::link(new moodle_url('/user/view.php',
+                                        array('id' => $userid, 'course' => $courseid)), fullname($users[$userid]));
+                                } else {
+                                    $thisname = fullname($users[$userid]);
+                                }
+                            break;
+                        }
+                        $this->content->text .= '<tr><td>'.(++$rank).'.</td><td>'.$thisname.'</td><td>';
+                        switch ($gradeformat) {
+                            case B_ACTIVITYRESULTS_GRADE_FORMAT_SCALE:
+                                // Round answer up and locate appropriate scale.
+                                $answer = (round($grades[$gradeid]->finalgrade, 0, PHP_ROUND_HALF_UP) - 1);
+                                if (isset($scale[$answer])) {
+                                    $this->content->text .= $scale[$answer];
+                                } else {
+                                    // Value is not in the scale.
+                                    $this->content->text .= get_string('unknown', 'block_activity_results');
+                                }
+                            break;
+                            case B_ACTIVITYRESULTS_GRADE_FORMAT_FRA:
+                                $this->content->text .= $this->activity_format_grade($grades[$gradeid]->finalgrade);
+                                $this->content->text .= '/'.$this->activity_format_grade($activity->grademax);
+                            break;
+                            case B_ACTIVITYRESULTS_GRADE_FORMAT_ABS:
+                                $this->content->text .= $this->activity_format_grade($grades[$gradeid]->finalgrade);
+                            break;
+                            default:
+                            case B_ACTIVITYRESULTS_GRADE_FORMAT_PCT:
+                                if ($activity->grademax) {
+                                    $this->content->text .= $this->activity_format_grade((float)$grades[$gradeid]->finalgrade /
+                                            (float)$activity->grademax * 100).'%';
+                                } else {
+                                    $this->content->text .= '--%';
+                                }
+                            break;
+                        }
+                        $this->content->text .= '</td></tr>';
+                    }
+                    $this->content->text .= '</tbody></table>';
+                }
+            break;
+        }
+
+        return $this->content;
+    }
+
+    /**
+     * Allows the block to be added multiple times to a single page
+     * @return boolean
+     */
+    public function instance_allow_multiple() {
+        return true;
+    }
+
+    /**
+     * Formats the grade to the specified decimal points
+     * @param float $grade
+     * @return string
+     */
+    private function activity_format_grade($grade) {
+        if (is_null($grade)) {
+            return get_string('notyetgraded', 'block_activity_results');
+        }
+        return format_float($grade, $this->config->decimalpoints);
+    }
+
+    /**
+     * Generates the Link to the activity module when displaed outside of the module
+     * @param stdclass $activity
+     * @param stdclass $cm
+     * @return string
+     */
+    private function activity_link($activity, $cm) {
+
+        $o = html_writer::start_tag('h3');
+        $o .= html_writer::link(new moodle_url('/mod/'.$activity->itemmodule.'/view.php',
+        array('id' => $cm->id)), $activity->itemname);
+        $o .= html_writer::end_tag('h3');
+        return $o;
+    }
+
+    /**
+     * Generates a numeric array of scale entries
+     * @param int $scaleid
+     * @return array
+     */
+    private function get_scale($scaleid) {
+        global $DB;
+        $scaletext = $DB->get_field('scale', 'scale', array('id' => $scaleid), IGNORE_MISSING);
+        $scale = explode ( ',', $scaletext);
+        return $scale;
+
+    }
+}
\ No newline at end of file
diff --git a/blocks/activity_results/db/access.php b/blocks/activity_results/db/access.php
new file mode 100644 (file)
index 0000000..70cdede
--- /dev/null
@@ -0,0 +1,41 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Activity results block caps.
+ *
+ * @package    block_activity_results
+ * @copyright  2015 Stephen Bourget
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+$capabilities = array(
+
+    'block/activity_results:addinstance' => array(
+        'riskbitmask' => RISK_SPAM | RISK_XSS,
+
+        'captype' => 'write',
+        'contextlevel' => CONTEXT_BLOCK,
+        'archetypes' => array(
+            'editingteacher' => CAP_ALLOW,
+            'manager' => CAP_ALLOW
+        ),
+
+        'clonepermissionsfrom' => 'moodle/site:manageblocks'
+    ),
+);
diff --git a/blocks/activity_results/edit_form.php b/blocks/activity_results/edit_form.php
new file mode 100644 (file)
index 0000000..0a07151
--- /dev/null
@@ -0,0 +1,104 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Defines the form for editing Quiz results block instances.
+ *
+ * @package    block_activity_results
+ * @copyright  2009 Tim Hunt
+ * @copyright  2015 Stephen Bourget
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+require_once($CFG->dirroot . '/lib/grade/constants.php');
+
+/**
+ * Form for editing activity results block instances.
+ *
+ * @copyright 2009 Tim Hunt
+ * @copyright 2015 Stephen Bourget
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class block_activity_results_edit_form extends block_edit_form {
+    /**
+     * The definition of the fields to use.
+     *
+     * @param MoodleQuickForm $mform
+     */
+    protected function specific_definition($mform) {
+        global $DB;
+
+        // Fields for editing activity_results block title and contents.
+        $mform->addElement('header', 'configheader', get_string('blocksettings', 'block'));
+
+        // Get supported modules (Only modules using grades or scales will be listed).
+        $sql = 'SELECT id, itemname FROM {grade_items} WHERE courseid = ? and itemtype = ? and (gradetype = ? or gradetype = ?)';
+        $params = array($this->page->course->id, 'mod', GRADE_TYPE_VALUE, GRADE_TYPE_SCALE);
+        $activities = $DB->get_records_sql_menu($sql, $params);
+
+        if (empty($activities)) {
+            $mform->addElement('static', 'noactivitieswarning', get_string('config_select_activity', 'block_activity_results'),
+                    get_string('config_no_activities_in_course', 'block_activity_results'));
+        } else {
+            foreach ($activities as $id => $name) {
+                $activities[$id] = strip_tags(format_string($name));
+            }
+            $mform->addElement('select', 'config_activitygradeitemid',
+                    get_string('config_select_activity', 'block_activity_results'), $activities);
+            $mform->setDefault('config_activitygradeitemid', $this->block->get_owning_activity()->id);
+        }
+
+        $mform->addElement('text', 'config_showbest',
+                get_string('config_show_best', 'block_activity_results'), array('size' => 3));
+        $mform->setDefault('config_showbest', 3);
+        $mform->setType('config_showbest', PARAM_INT);
+
+        $mform->addElement('text', 'config_showworst',
+                get_string('config_show_worst', 'block_activity_results'), array('size' => 3));
+        $mform->setDefault('config_showworst', 0);
+        $mform->setType('config_showworst', PARAM_INT);
+
+        $mform->addElement('selectyesno', 'config_usegroups', get_string('config_use_groups', 'block_activity_results'));
+
+        $nameoptions = array(
+            B_ACTIVITYRESULTS_NAME_FORMAT_FULL => get_string('config_names_full', 'block_activity_results'),
+            B_ACTIVITYRESULTS_NAME_FORMAT_ID => get_string('config_names_id', 'block_activity_results'),
+            B_ACTIVITYRESULTS_NAME_FORMAT_ANON => get_string('config_names_anon', 'block_activity_results')
+        );
+        $mform->addElement('select', 'config_nameformat',
+                get_string('config_name_format', 'block_activity_results'), $nameoptions);
+        $mform->setDefault('config_nameformat', B_ACTIVITYRESULTS_NAME_FORMAT_FULL);
+
+        $gradeeoptions = array(
+            B_ACTIVITYRESULTS_GRADE_FORMAT_PCT => get_string('config_format_percentage', 'block_activity_results'),
+            B_ACTIVITYRESULTS_GRADE_FORMAT_FRA => get_string('config_format_fraction', 'block_activity_results'),
+            B_ACTIVITYRESULTS_GRADE_FORMAT_ABS => get_string('config_format_absolute', 'block_activity_results')
+        );
+        $mform->addElement('select', 'config_gradeformat',
+                get_string('config_grade_format', 'block_activity_results'), $gradeeoptions);
+        $mform->setDefault('config_gradeformat', B_ACTIVITYRESULTS_GRADE_FORMAT_PCT);
+
+        $options = array();
+        for ($i = 0; $i <= 5; $i++) {
+            $options[$i] = $i;
+        }
+        $mform->addElement('select', 'config_decimalpoints', get_string('config_decimalplaces', 'block_activity_results'),
+                $options);
+        $mform->setDefault('config_decimalpoints', 2);
+        $mform->setType('config_decimalpoints', PARAM_INT);
+    }
+}
\ No newline at end of file
diff --git a/blocks/activity_results/lang/en/block_activity_results.php b/blocks/activity_results/lang/en/block_activity_results.php
new file mode 100644 (file)
index 0000000..7269799
--- /dev/null
@@ -0,0 +1,55 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Strings for component 'block_activity_results', language 'en', branch 'MOODLE_20_STABLE'
+ *
+ * @package    block_activity_results
+ * @copyright  2015 Stephen Bourget
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+$string['activity_results:addinstance'] = 'Add a new activity results block';
+$string['bestgrade'] = 'The highest grade:';
+$string['bestgrades'] = 'The {$a} highest grades:';
+$string['bestgroupgrade'] = 'The group with the highest average:';
+$string['bestgroupgrades'] = 'The {$a} groups with the highest average:';
+$string['config_format_absolute'] = 'Absolute numbers';
+$string['config_format_fraction'] = 'Fractions';
+$string['config_format_percentage'] = 'Percentages';
+$string['config_decimalplaces'] = 'Decimal places to display';
+$string['config_grade_format'] = 'Display grades as:';
+$string['config_name_format'] = 'Privacy level for displayed results:';
+$string['config_names_anon'] = 'Anonymous results';
+$string['config_names_full'] = 'Display full names';
+$string['config_names_id'] = 'Display only ID numbers';
+$string['config_no_activities_in_course'] = 'This course does not contain any activity activities . You must add at least one before you are able to use this block correctly.';
+$string['config_select_activity'] = 'Which activity should this block display results from?';
+$string['config_show_best'] = 'How many of the highest grades should be shown (0 to disable)?';
+$string['config_show_worst'] = 'How many of the lowest grades should be shown (0 to disable)?';
+$string['configuredtoshownothing'] = 'This block\'s configuration currently does not allow it to show any results. You may want to either configure it or hide it.';
+$string['config_use_groups'] = 'Show groups instead of students (only if the activity supports groups)?';
+$string['error_emptyactivityid'] = 'There is an error right now with this block: you need to select which activity it should display results from.';
+$string['error_emptyactivityrecord'] = 'There is an error right now with this block: the selected activity does not seem to exist in the database.';
+$string['error_nogroupsexist'] = 'There is an error right now with this block: it is set to display grades in group mode, but the course has no defined groups.';
+$string['error_unsupportedgradetype'] = 'There is an error right now with this block: The activity selected is configured to use a grading method that is not supported by this block.';
+$string['notyetgraded'] = 'Not yet graded';
+$string['pluginname'] = 'Activity results';
+$string['unknown'] = 'Unknown scale';
+$string['worstgrade'] = 'The lowest grade:';
+$string['worstgrades'] = 'The {$a} lowest grades:';
+$string['worstgroupgrade'] = 'The group with the lowest average:';
+$string['worstgroupgrades'] = 'The {$a} groups with the lowest average:';
diff --git a/blocks/activity_results/styles.css b/blocks/activity_results/styles.css
new file mode 100644 (file)
index 0000000..39ea1cc
--- /dev/null
@@ -0,0 +1,6 @@
+.block_activity_results {text-align: center;}
+.block_activity_results h1 {margin: 4px;font-size: 1.1em;}
+.block_activity_results table.grades {text-align: left;width: 100%;}
+.block_activity_results table.grades .number{text-align: right;width:10%;}
+.block_activity_results table.grades .grade {text-align: right;}
+.block_activity_results table.grades caption {margin: 1em 0px 0px 0px;border-bottom-width: 1px;border-bottom-style: solid;font-weight: bold;}
diff --git a/blocks/activity_results/tests/behat/addblockinactivity.feature b/blocks/activity_results/tests/behat/addblockinactivity.feature
new file mode 100644 (file)
index 0000000..189aaaa
--- /dev/null
@@ -0,0 +1,66 @@
+@block @block_activity_results
+Feature: The activity results block displays student scores
+  In order to be display student scores
+  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@asd.com | T1 |
+      | student1 | Student | 1 | student1@asd.com | S1 |
+      | student2 | Student | 2 | student2@asd.com | S2 |
+      | student3 | Student | 3 | student3@asd.com | S3 |
+      | student4 | Student | 4 | student4@asd.com | S4 |
+      | student5 | Student | 5 | student5@asd.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 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 |
+    And I follow "Course 1"
+    And I follow "Grades"
+    And I turn editing mode on
+    And I give the grade "90.00" to the user "Student 1" for the grade item "Test assignment"
+    And I give the grade "80.00" to the user "Student 2" for the grade item "Test assignment"
+    And I give the grade "70.00" to the user "Student 3" for the grade item "Test assignment"
+    And I give the grade "60.00" to the user "Student 4" for the grade item "Test assignment"
+    And I give the grade "50.00" 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 a non-graded activity to show 3 high scores
+    Given I add a "Page" to section "1"
+    And I set the following fields to these values:
+      | Name | Test page name |
+      | Description | Test page description |
+      | page | This is a page |
+    And I press "Save and display"
+    When I add the "Activity results" block
+    And I configure the "Activity results" block
+    And I set the following fields to these values:
+      | id_config_activitygradeitemid | Test assignment |
+      | id_config_showbest | 3 |
+      | id_config_showworst | 0 |
+      | id_config_gradeformat | Absolute numbers |
+      | 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 "90.00" in the "Activity results" "block"
+    And I should see "Student 2" in the "Activity results" "block"
+    And I should see "80.00" in the "Activity results" "block"
+    And I should see "Student 3" in the "Activity results" "block"
+    And I should see "70.00" in the "Activity results" "block"
\ No newline at end of file
diff --git a/blocks/activity_results/tests/behat/addunconfiguredblock.feature b/blocks/activity_results/tests/behat/addunconfiguredblock.feature
new file mode 100644 (file)
index 0000000..b27874d
--- /dev/null
@@ -0,0 +1,43 @@
+@block @block_activity_results
+Feature: The activity results block displays student scores
+  In order to be display student scores
+  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@asd.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 |
+    And I log in as "teacher1"
+    And I follow "Course 1"
+    And I turn editing mode on
+
+  Scenario: Add the block to a the course
+    Given I add the "Activity results" block
+    Then I should see "There is an error right now with this block: you need to select which activity it should display results from." in the "Activity results" "block"
+
+  Scenario: Try to configure the block on the course page in a course without activities
+    Given I add the "Activity results" block
+    When I configure the "Activity results" block
+    And I should see "This course does not contain any activity activities . You must add at least one before you are able to use this block correctly."
+    And I press "Save changes"
+    Then I should see "There is an error right now with this block: you need to select which activity it should display results from." in the "Activity results" "block"
+
+  Scenario: Try to configure the block on a resource page in a course without activities
+    Given I add a "Page" to section "1"
+    And I set the following fields to these values:
+      | Name | Test page name |
+      | Description | Test page description |
+      | page | This is a page |
+    And I press "Save and display"
+    When I add the "Activity results" block
+    And I configure the "Activity results" block
+    And I should see "This course does not contain any activity activities . You must add at least one before you are able to use this block correctly."
+    And I press "Save changes"
+    Then I should see "There is an error right now with this block: you need to select which activity it should display results from." in the "Activity results" "block"
diff --git a/blocks/activity_results/tests/behat/addunsupportedactivity.feature b/blocks/activity_results/tests/behat/addunsupportedactivity.feature
new file mode 100644 (file)
index 0000000..e77a8b8
--- /dev/null
@@ -0,0 +1,40 @@
+@block @block_activity_results
+Feature: The activity results block displays student scores
+  In order to be display student scores
+  As a user
+  I need to properly configure the activity results block
+
+  Background:
+    Given the following "users" exist:
+      | username | firstname | lastname | email | idnumber |
+      | teacher1 | Teacher | 1 | teacher1@asd.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 |
+    And I log in as "teacher1"
+    And I follow "Course 1"
+    And I turn editing mode on
+
+  Scenario: Try to configure the block to use an activity without grades
+    Given I add a "Assignment" to section "1" and I fill the form with:
+      | Assignment name | Test assignment |
+      | Description | Offline text |
+      | assignsubmission_file_enabled | 0 |
+    And I follow "C1"
+    And I add the "Activity results" block
+    And 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_gradeformat | Percentages |
+      | id_config_nameformat | Display full names |
+    And I press "Save changes"
+    When I follow "Test assignment"
+    And I click on "Edit settings" "link" in the "Administration" "block"
+    And I set the following fields to these values:
+      | id_modgrade_type | None |
+    And I press "Save and return to course"
+    Then I should see "There is an error right now with this block: The activity selected is configured to use a grading method that is not supported by this block." in the "Activity results" "block"
diff --git a/blocks/activity_results/tests/behat/highscoreswithoutgroups.feature b/blocks/activity_results/tests/behat/highscoreswithoutgroups.feature
new file mode 100644 (file)
index 0000000..d1a6d20
--- /dev/null
@@ -0,0 +1,170 @@
+@block @block_activity_results
+Feature: The activity results block displays student scores
+  In order to be display student scores
+  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@asd.com | T1 |
+      | student1 | Student | 1 | student1@asd.com | S1 |
+      | student2 | Student | 2 | student2@asd.com | S2 |
+      | student3 | Student | 3 | student3@asd.com | S3 |
+      | student4 | Student | 4 | student4@asd.com | S4 |
+      | student5 | Student | 5 | student5@asd.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 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 |
+    And I follow "Course 1"
+    And I follow "Grades"
+    And I turn editing mode on
+    And I give the grade "90.00" to the user "Student 1" for the grade item "Test assignment"
+    And I give the grade "80.00" to the user "Student 2" for the grade item "Test assignment"
+    And I give the grade "70.00" to the user "Student 3" for the grade item "Test assignment"
+    And I give the grade "60.00" to the user "Student 4" for the grade item "Test assignment"
+    And I give the grade "50.00" 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 0 high scores
+    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 | 0 |
+      | id_config_gradeformat | Percentages |
+      | id_config_nameformat | Display full names |
+    And I press "Save changes"
+    Then I should see "This block's configuration currently does not allow it to show any results." in 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 |
+      | id_config_showworst | 0 |
+      | id_config_gradeformat | Percentages |
+      | 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 "90%" in the "Activity results" "block"
+
+  Scenario: Try to configure the block on the course page to show 1 high score as a fraction
+    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_gradeformat | Fractions |
+      | 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 "90.00/100.00" in the "Activity results" "block"
+
+  Scenario: Try to configure the block on the course page to show 1 high score as a absolute 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 | 1 |
+      | id_config_showworst | 0 |
+      | id_config_gradeformat | Absolute numbers |
+      | 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 "90.00" in the "Activity results" "block"
+
+  Scenario: Try to configure the block on the course page to show multiple high scores as percentages
+    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_gradeformat | Percentages |
+      | 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 "90%" in the "Activity results" "block"
+    And I should see "Student 2" in the "Activity results" "block"
+    And I should see "80%" in the "Activity results" "block"
+    And I should see "Student 3" in the "Activity results" "block"
+    And I should see "70%" in the "Activity results" "block"
+
+  Scenario: Try to configure the block on the course page to show multiple high scores as fractions
+    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_gradeformat | Fractions |
+      | 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 "90.00/100.00" in the "Activity results" "block"
+    And I should see "Student 2" in the "Activity results" "block"
+    And I should see "80.00/100.00" in the "Activity results" "block"
+    And I should see "Student 3" in the "Activity results" "block"
+    And I should see "70.00/100.00" in the "Activity results" "block"
+
+  Scenario: Try to configure the block on the course page to show multiple high scores as absolute 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_gradeformat | Absolute numbers |
+      | 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 "90.00" in the "Activity results" "block"
+    And I should see "Student 2" in the "Activity results" "block"
+    And I should see "80.00" in the "Activity results" "block"
+    And I should see "Student 3" in the "Activity results" "block"
+    And I should see "70.00" 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_gradeformat | Percentages |
+      | 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 "90.00%" in the "Activity results" "block"
+    And I should see "User S2" in the "Activity results" "block"
+    And I should see "80.00%" in the "Activity results" "block"
+    And I should see "User S3" in the "Activity results" "block"
+    And I should see "70.00%" 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_gradeformat | Percentages |
+      | id_config_nameformat | Anonymous results |
+    And I press "Save changes"
+    Then I should see "User" in the "Activity results" "block"
+    And I should see "90.00%" in the "Activity results" "block"
+    And I should see "80.00%" in the "Activity results" "block"
+    And I should see "70.00%" in the "Activity results" "block"
\ No newline at end of file
diff --git a/blocks/activity_results/tests/behat/highscoreswithseperategroups.feature b/blocks/activity_results/tests/behat/highscoreswithseperategroups.feature
new file mode 100644 (file)
index 0000000..e6e7063
--- /dev/null
@@ -0,0 +1,433 @@
+@block @block_activity_results
+Feature: The activity results block displays student scores
+  In order to be display student scores
+  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@asd.com | T1 |
+      | student1 | Student | 1 | student1@asd.com | S1 |
+      | student2 | Student | 2 | student2@asd.com | S2 |
+      | student3 | Student | 3 | student3@asd.com | S3 |
+      | student4 | Student | 4 | student4@asd.com | S4 |
+      | student5 | Student | 5 | student5@asd.com | S5 |
+      | student6 | Student | 6 | student6@asd.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 |
+
+  @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@asd.com)" user to "Group 1" group members
+    And I add "Student 2 (student2@asd.com)" user to "Group 1" group members
+    And I add "Student 3 (student3@asd.com)" user to "Group 2" group members
+    And I add "Student 4 (student4@asd.com)" user to "Group 2" group members
+    And I add "Student 5 (student5@asd.com)" user to "Group 3" group members
+    And I add "Student 6 (student6@asd.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 follow "Grades"
+    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
+    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_gradeformat | Percentages |
+      | id_config_nameformat | Display full names |
+      | id_config_decimalpoints | 0 |
+      | id_config_usegroups | Yes |
+    And I press "Save changes"
+    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@asd.com)" user to "Group 1" group members
+    And I add "Student 2 (student2@asd.com)" user to "Group 1" group members
+    And I add "Student 3 (student3@asd.com)" user to "Group 2" group members
+    And I add "Student 4 (student4@asd.com)" user to "Group 2" group members
+    And I add "Student 5 (student5@asd.com)" user to "Group 3" group members
+    And I add "Student 6 (student6@asd.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 follow "Grades"
+    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
+    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_gradeformat | Fractions |
+      | 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 "95.00/100.00" 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 "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@asd.com)" user to "Group 1" group members
+    And I add "Student 2 (student2@asd.com)" user to "Group 1" group members
+    And I add "Student 3 (student3@asd.com)" user to "Group 2" group members
+    And I add "Student 4 (student4@asd.com)" user to "Group 2" group members
+    And I add "Student 5 (student5@asd.com)" user to "Group 3" group members
+    And I add "Student 6 (student6@asd.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 follow "Grades"
+    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
+    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_gradeformat | Absolute numbers |
+      | 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 "95.00" 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 "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@asd.com)" user to "Group 1" group members
+    And I add "Student 2 (student2@asd.com)" user to "Group 1" group members
+    And I add "Student 3 (student3@asd.com)" user to "Group 2" group members
+    And I add "Student 4 (student4@asd.com)" user to "Group 2" group members
+    And I add "Student 5 (student5@asd.com)" user to "Group 3" group members
+    And I add "Student 6 (student6@asd.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 follow "Grades"
+    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
+    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_gradeformat | Percentages |
+      | id_config_nameformat | Display full names |
+      | id_config_decimalpoints | 0 |
+      | id_config_usegroups | Yes |
+    And I press "Save changes"
+    Then I should see "Group 1" in the "Activity results" "block"
+    And I should see "95%" in the "Activity results" "block"
+    And I should see "Group 2" in the "Activity results" "block"
+    And I should see "85%" in the "Activity results" "block"
+    And I should see "Group 3" in the "Activity results" "block"
+    And I should see "75%" 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 "100%" in the "Activity results" "block"
+    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@asd.com)" user to "Group 1" group members
+    And I add "Student 2 (student2@asd.com)" user to "Group 1" group members
+    And I add "Student 3 (student3@asd.com)" user to "Group 2" group members
+    And I add "Student 4 (student4@asd.com)" user to "Group 2" group members
+    And I add "Student 5 (student5@asd.com)" user to "Group 3" group members
+    And I add "Student 6 (student6@asd.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 follow "Grades"
+    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
+    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_gradeformat | Fractions |
+      | 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 "95.00/100.00" in the "Activity results" "block"
+    And I should see "Group 2" in the "Activity results" "block"
+    And I should see "85.00/100.00" in the "Activity results" "block"
+    And I should see "Group 3" in the "Activity results" "block"
+    And I should see "75.00/100.00" 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 "90.00/100.00" in the "Activity results" "block"
+    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@asd.com)" user to "Group 1" group members
+    And I add "Student 2 (student2@asd.com)" user to "Group 1" group members
+    And I add "Student 3 (student3@asd.com)" user to "Group 2" group members
+    And I add "Student 4 (student4@asd.com)" user to "Group 2" group members
+    And I add "Student 5 (student5@asd.com)" user to "Group 3" group members
+    And I add "Student 6 (student6@asd.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 follow "Grades"
+    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
+    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_gradeformat | Absolute numbers |
+      | 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 "95.00" in the "Activity results" "block"
+    And I should see "Group 2" in the "Activity results" "block"
+    And I should see "85.00" in the "Activity results" "block"
+    And I should see "Group 3" in the "Activity results" "block"
+    And I should see "75.00" 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 "100.00" in the "Activity results" "block"
+    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@asd.com)" user to "Group 1" group members
+    And I add "Student 2 (student2@asd.com)" user to "Group 1" group members
+    And I add "Student 3 (student3@asd.com)" user to "Group 2" group members
+    And I add "Student 4 (student4@asd.com)" user to "Group 2" group members
+    And I add "Student 5 (student5@asd.com)" user to "Group 3" group members
+    And I add "Student 6 (student6@asd.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 follow "Grades"
+    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
+    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_gradeformat | Percentages |
+      | 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 "95.00%" in the "Activity results" "block"
+    And I should see "85.00%" in the "Activity results" "block"
+    And I should see "75.00%" 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 "100.00%" in the "Activity results" "block"
+    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@asd.com)" user to "Group 1" group members
+    And I add "Student 2 (student2@asd.com)" user to "Group 1" group members
+    And I add "Student 3 (student3@asd.com)" user to "Group 2" group members
+    And I add "Student 4 (student4@asd.com)" user to "Group 2" group members
+    And I add "Student 5 (student5@asd.com)" user to "Group 3" group members
+    And I add "Student 6 (student6@asd.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 follow "Grades"
+    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
+    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_gradeformat | Percentages |
+      | 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 "95.00%" in the "Activity results" "block"
+    And I should see "85.00%" in the "Activity results" "block"
+    And I should see "75.00%" 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 "100.00%" in the "Activity results" "block"
+    And I should see "90.00%" in the "Activity results" "block"
\ No newline at end of file
diff --git a/blocks/activity_results/tests/behat/highscoreswithvisiblegroups.feature b/blocks/activity_results/tests/behat/highscoreswithvisiblegroups.feature
new file mode 100644 (file)
index 0000000..ff6ee62
--- /dev/null
@@ -0,0 +1,410 @@
+@block @block_activity_results
+Feature: The activity results block displays student scores
+  In order to be display student scores
+  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@asd.com | T1 |
+      | student1 | Student | 1 | student1@asd.com | S1 |
+      | student2 | Student | 2 | student2@asd.com | S2 |
+      | student3 | Student | 3 | student3@asd.com | S3 |
+      | student4 | Student | 4 | student4@asd.com | S4 |
+      | student5 | Student | 5 | student5@asd.com | S5 |
+      | student6 | Student | 6 | student6@asd.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 |
+
+  @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@asd.com)" user to "Group 1" group members
+    And I add "Student 2 (student2@asd.com)" user to "Group 1" group members
+    And I add "Student 3 (student3@asd.com)" user to "Group 2" group members
+    And I add "Student 4 (student4@asd.com)" user to "Group 2" group members
+    And I add "Student 5 (student5@asd.com)" user to "Group 3" group members
+    And I add "Student 6 (student6@asd.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 follow "Grades"
+    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
+    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_gradeformat | Percentages |
+      | id_config_nameformat | Display full names |
+      | id_config_decimalpoints | 0 |
+      | id_config_usegroups | Yes |
+    And I press "Save changes"
+    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@asd.com)" user to "Group 1" group members
+    And I add "Student 2 (student2@asd.com)" user to "Group 1" group members
+    And I add "Student 3 (student3@asd.com)" user to "Group 2" group members
+    And I add "Student 4 (student4@asd.com)" user to "Group 2" group members
+    And I add "Student 5 (student5@asd.com)" user to "Group 3" group members
+    And I add "Student 6 (student6@asd.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 follow "Grades"
+    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
+    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_gradeformat | Fractions |
+      | id_config_nameformat | Display full names |
+      | id_config_usegroups | Yes |
+    And I press "Save changes"
+    And I log out
+    Then I log in as "student1"
+    And I follow "Course 1"
+    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@asd.com)" user to "Group 1" group members
+    And I add "Student 2 (student2@asd.com)" user to "Group 1" group members
+    And I add "Student 3 (student3@asd.com)" user to "Group 2" group members
+    And I add "Student 4 (student4@asd.com)" user to "Group 2" group members
+    And I add "Student 5 (student5@asd.com)" user to "Group 3" group members
+    And I add "Student 6 (student6@asd.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 follow "Grades"
+    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
+    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_gradeformat | Absolute numbers |
+      | id_config_nameformat | Display full names |
+      | id_config_usegroups | Yes |
+    And I press "Save changes"
+    And I log out
+    Then I log in as "student1"
+    And I follow "Course 1"
+    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@asd.com)" user to "Group 1" group members
+    And I add "Student 2 (student2@asd.com)" user to "Group 1" group members
+    And I add "Student 3 (student3@asd.com)" user to "Group 2" group members
+    And I add "Student 4 (student4@asd.com)" user to "Group 2" group members
+    And I add "Student 5 (student5@asd.com)" user to "Group 3" group members
+    And I add "Student 6 (student6@asd.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 follow "Grades"
+    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
+    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_gradeformat | Percentages |
+      | id_config_nameformat | Display full names |
+      | id_config_decimalpoints | 0 |
+      | id_config_usegroups | Yes |
+    And I press "Save changes"
+    And I log out
+    Then I log in as "student1"
+    And I follow "Course 1"
+    And I should see "Group 1" in the "Activity results" "block"
+    And I should see "95%" in the "Activity results" "block"
+    And I should see "Group 2" in the "Activity results" "block"
+    And I should see "85%" in the "Activity results" "block"
+    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@asd.com)" user to "Group 1" group members
+    And I add "Student 2 (student2@asd.com)" user to "Group 1" group members
+    And I add "Student 3 (student3@asd.com)" user to "Group 2" group members
+    And I add "Student 4 (student4@asd.com)" user to "Group 2" group members
+    And I add "Student 5 (student5@asd.com)" user to "Group 3" group members
+    And I add "Student 6 (student6@asd.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 follow "Grades"
+    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
+    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_gradeformat | Fractions |
+      | id_config_nameformat | Display full names |
+      | id_config_usegroups | Yes |
+    And I press "Save changes"
+    And I log out
+    Then I log in as "student1"
+    And I follow "Course 1"
+    And I should see "Group 1" in the "Activity results" "block"
+    And I should see "95.00/100.00" in the "Activity results" "block"
+    And I should see "Group 2" in the "Activity results" "block"
+    And I should see "85.00/100.00" in the "Activity results" "block"
+    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@asd.com)" user to "Group 1" group members
+    And I add "Student 2 (student2@asd.com)" user to "Group 1" group members
+    And I add "Student 3 (student3@asd.com)" user to "Group 2" group members
+    And I add "Student 4 (student4@asd.com)" user to "Group 2" group members
+    And I add "Student 5 (student5@asd.com)" user to "Group 3" group members
+    And I add "Student 6 (student6@asd.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 follow "Grades"
+    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
+    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_gradeformat | Absolute numbers |
+      | id_config_nameformat | Display full names |
+      | id_config_usegroups | Yes |
+    And I press "Save changes"
+    And I log out
+    Then I log in as "student1"
+    And I follow "Course 1"
+    And I should see "Group 1" in the "Activity results" "block"
+    And I should see "95.00" in the "Activity results" "block"
+    And I should see "Group 2" in the "Activity results" "block"
+    And I should see "85.00" in the "Activity results" "block"
+    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@asd.com)" user to "Group 1" group members
+    And I add "Student 2 (student2@asd.com)" user to "Group 1" group members
+    And I add "Student 3 (student3@asd.com)" user to "Group 2" group members
+    And I add "Student 4 (student4@asd.com)" user to "Group 2" group members
+    And I add "Student 5 (student5@asd.com)" user to "Group 3" group members
+    And I add "Student 6 (student6@asd.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 follow "Grades"
+    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
+    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_gradeformat | Percentages |
+      | id_config_nameformat | Display only ID numbers |
+      | id_config_usegroups | Yes |
+    And I press "Save changes"
+    And I log out
+    Then I log in as "student1"
+    And I follow "Course 1"
+    And I should see "Group" in the "Activity results" "block"
+    And I should see "95.00%" in the "Activity results" "block"
+    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@asd.com)" user to "Group 1" group members
+    And I add "Student 2 (student2@asd.com)" user to "Group 1" group members
+    And I add "Student 3 (student3@asd.com)" user to "Group 2" group members
+    And I add "Student 4 (student4@asd.com)" user to "Group 2" group members
+    And I add "Student 5 (student5@asd.com)" user to "Group 3" group members
+    And I add "Student 6 (student6@asd.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 follow "Grades"
+    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
+    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_gradeformat | Percentages |
+      | id_config_nameformat | Anonymous results |
+      | id_config_usegroups | Yes |
+    And I press "Save changes"
+    And I log out
+    Then I log in as "student1"
+    And I follow "Course 1"
+    And I should see "Group" in the "Activity results" "block"
+    And I should see "95.00%" in the "Activity results" "block"
+    And I should see "85.00%" in the "Activity results" "block"
+    And I should see "75.00%" in the "Activity results" "block"
\ No newline at end of file
diff --git a/blocks/activity_results/tests/behat/lowscoreswithoutgroups.feature b/blocks/activity_results/tests/behat/lowscoreswithoutgroups.feature
new file mode 100644 (file)
index 0000000..998eec5
--- /dev/null
@@ -0,0 +1,159 @@
+@block @block_activity_results
+Feature: The activity results block displays student scores
+  In order to be display student scores
+  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@asd.com | T1 |
+      | student1 | Student | 1 | student1@asd.com | S1 |
+      | student2 | Student | 2 | student2@asd.com | S2 |
+      | student3 | Student | 3 | student3@asd.com | S3 |
+      | student4 | Student | 4 | student4@asd.com | S4 |
+      | student5 | Student | 5 | student5@asd.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 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 |
+    And I follow "Course 1"
+    And I follow "Grades"
+    And I turn editing mode on
+    And I give the grade "90.00" to the user "Student 1" for the grade item "Test assignment"
+    And I give the grade "80.00" to the user "Student 2" for the grade item "Test assignment"
+    And I give the grade "70.00" to the user "Student 3" for the grade item "Test assignment"
+    And I give the grade "60.00" to the user "Student 4" for the grade item "Test assignment"
+    And I give the grade "50.00" 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 "50%" in the "Activity results" "block"
+
+  Scenario: Try to configure the block on the course page to show 1 low score as a fraction
+    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 | Fractions |
+      | 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 "50.00/100.00" in the "Activity results" "block"
+
+  Scenario: Try to configure the block on the course page to show 1 low score as a absolute number
+    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 | Absolute numbers |
+      | 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 "50.00" in the "Activity results" "block"
+
+  Scenario: Try to configure the block on the course page to show multiple low scores as percentages
+    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_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 "50%" in the "Activity results" "block"
+    And I should see "Student 4" in the "Activity results" "block"
+    And I should see "60%" in the "Activity results" "block"
+    And I should see "Student 3" in the "Activity results" "block"
+    And I should see "70%" in the "Activity results" "block"
+
+  Scenario: Try to configure the block on the course page to show multiple low scores as fractions
+    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_gradeformat | Fractions |
+      | 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 "50.00/100.00" in the "Activity results" "block"
+    And I should see "Student 4" in the "Activity results" "block"
+    And I should see "60.00/100.00" in the "Activity results" "block"
+    And I should see "Student 3" in the "Activity results" "block"
+    And I should see "70.00/100.00" in the "Activity results" "block"
+
+  Scenario: Try to configure the block on the course page to show multiple low scores as absolute 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_gradeformat | Absolute numbers |
+      | 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 "50.00" in the "Activity results" "block"
+    And I should see "Student 4" in the "Activity results" "block"
+    And I should see "60.00" in the "Activity results" "block"
+    And I should see "Student 3" in the "Activity results" "block"
+    And I should see "70.00" 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_gradeformat | Percentages |
+      | 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 "50.00%" in the "Activity results" "block"
+    And I should see "User S4" in the "Activity results" "block"
+    And I should see "60.00%" in the "Activity results" "block"
+    And I should see "User S3" in the "Activity results" "block"
+    And I should see "70.00%" 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_gradeformat | Percentages |
+      | id_config_nameformat | Anonymous results |
+    And I press "Save changes"
+    Then I should see "User" in the "Activity results" "block"
+    And I should see "50.00%" in the "Activity results" "block"
+    And I should see "60.00%" in the "Activity results" "block"
+    And I should see "70.00%" in the "Activity results" "block"
\ No newline at end of file
diff --git a/blocks/activity_results/tests/behat/lowscoreswithseperategroups.feature b/blocks/activity_results/tests/behat/lowscoreswithseperategroups.feature
new file mode 100644 (file)
index 0000000..876119b
--- /dev/null
@@ -0,0 +1,425 @@
+@block @block_activity_results
+Feature: The activity results block displays student scores
+  In order to be display student scores
+  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@asd.com | T1 |
+      | student1 | Student | 1 | student1@asd.com | S1 |
+      | student2 | Student | 2 | student2@asd.com | S2 |
+      | student3 | Student | 3 | student3@asd.com | S3 |
+      | student4 | Student | 4 | student4@asd.com | S4 |
+      | student5 | Student | 5 | student5@asd.com | S5 |
+      | student6 | Student | 6 | student6@asd.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 |
+
+  @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@asd.com)" user to "Group 1" group members
+    And I add "Student 2 (student2@asd.com)" user to "Group 1" group members
+    And I add "Student 3 (student3@asd.com)" user to "Group 2" group members
+    And I add "Student 4 (student4@asd.com)" user to "Group 2" group members
+    And I add "Student 5 (student5@asd.com)" user to "Group 3" group members
+    And I add "Student 6 (student6@asd.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 follow "Grades"
+    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
+    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 |
+      | id_config_usegroups | Yes |
+    And I press "Save changes"
+    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@asd.com)" user to "Group 1" group members
+    And I add "Student 2 (student2@asd.com)" user to "Group 1" group members
+    And I add "Student 3 (student3@asd.com)" user to "Group 2" group members
+    And I add "Student 4 (student4@asd.com)" user to "Group 2" group members
+    And I add "Student 5 (student5@asd.com)" user to "Group 3" group members
+    And I add "Student 6 (student6@asd.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 follow "Grades"
+    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
+    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 | Fractions |
+      | 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 "75.00/100.00" 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 "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@asd.com)" user to "Group 1" group members
+    And I add "Student 2 (student2@asd.com)" user to "Group 1" group members
+    And I add "Student 3 (student3@asd.com)" user to "Group 2" group members
+    And I add "Student 4 (student4@asd.com)" user to "Group 2" group members
+    And I add "Student 5 (student5@asd.com)" user to "Group 3" group members
+    And I add "Student 6 (student6@asd.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 follow "Grades"
+    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
+    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 | Absolute numbers |
+      | 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 "75.00" 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 "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@asd.com)" user to "Group 1" group members
+    And I add "Student 2 (student2@asd.com)" user to "Group 1" group members
+    And I add "Student 3 (student3@asd.com)" user to "Group 2" group members
+    And I add "Student 4 (student4@asd.com)" user to "Group 2" group members
+    And I add "Student 5 (student5@asd.com)" user to "Group 3" group members
+    And I add "Student 6 (student6@asd.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 follow "Grades"
+    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
+    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_gradeformat | Percentages |
+      | id_config_nameformat | Display full names |
+      | id_config_decimalpoints | 0 |
+      | id_config_usegroups | Yes |
+    And I press "Save changes"
+    Then I should see "Group 2" in the "Activity results" "block"
+    And I should see "85%" in the "Activity results" "block"
+    And I should see "Group 3" in the "Activity results" "block"
+    And I should see "75%" 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 "70%" in the "Activity results" "block"
+    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@asd.com)" user to "Group 1" group members
+    And I add "Student 2 (student2@asd.com)" user to "Group 1" group members
+    And I add "Student 3 (student3@asd.com)" user to "Group 2" group members
+    And I add "Student 4 (student4@asd.com)" user to "Group 2" group members
+    And I add "Student 5 (student5@asd.com)" user to "Group 3" group members
+    And I add "Student 6 (student6@asd.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 follow "Grades"
+    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
+    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_gradeformat | Fractions |
+      | 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 "85.00/100.00" in the "Activity results" "block"
+    And I should see "Group 3" in the "Activity results" "block"
+    And I should see "75.00/100.00" 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 "90.00/100.00" in the "Activity results" "block"
+    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@asd.com)" user to "Group 1" group members
+    And I add "Student 2 (student2@asd.com)" user to "Group 1" group members
+    And I add "Student 3 (student3@asd.com)" user to "Group 2" group members
+    And I add "Student 4 (student4@asd.com)" user to "Group 2" group members
+    And I add "Student 5 (student5@asd.com)" user to "Group 3" group members
+    And I add "Student 6 (student6@asd.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 follow "Grades"
+    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
+    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_gradeformat | Absolute numbers |
+      | 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 "85.00" in the "Activity results" "block"
+    And I should see "Group 3" in the "Activity results" "block"
+    And I should see "75.00" 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 5" in the "Activity results" "block"
+    And I should see "80.00" in the "Activity results" "block"
+    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@asd.com)" user to "Group 1" group members
+    And I add "Student 2 (student2@asd.com)" user to "Group 1" group members
+    And I add "Student 3 (student3@asd.com)" user to "Group 2" group members
+    And I add "Student 4 (student4@asd.com)" user to "Group 2" group members
+    And I add "Student 5 (student5@asd.com)" user to "Group 3" group members
+    And I add "Student 6 (student6@asd.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 follow "Grades"
+    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
+    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_gradeformat | Percentages |
+      | 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 "85.00%" in the "Activity results" "block"
+    And I should see "75.00%" 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 "100.00%" in the "Activity results" "block"
+    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@asd.com)" user to "Group 1" group members
+    And I add "Student 2 (student2@asd.com)" user to "Group 1" group members
+    And I add "Student 3 (student3@asd.com)" user to "Group 2" group members
+    And I add "Student 4 (student4@asd.com)" user to "Group 2" group members
+    And I add "Student 5 (student5@asd.com)" user to "Group 3" group members
+    And I add "Student 6 (student6@asd.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 follow "Grades"
+    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
+    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_gradeformat | Percentages |
+      | 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 "85.00%" in the "Activity results" "block"
+    And I should see "75.00%" 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 "100.00%" in the "Activity results" "block"
+    And I should see "90.00%" in the "Activity results" "block"
\ No newline at end of file
diff --git a/blocks/activity_results/tests/behat/lowscoreswithvisiblegroups.feature b/blocks/activity_results/tests/behat/lowscoreswithvisiblegroups.feature
new file mode 100644 (file)
index 0000000..4c629fa
--- /dev/null
@@ -0,0 +1,406 @@
+@block @block_activity_results
+Feature: The activity results block displays student scores
+  In order to be display student scores
+  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@asd.com | T1 |
+      | student1 | Student | 1 | student1@asd.com | S1 |
+      | student2 | Student | 2 | student2@asd.com | S2 |
+      | student3 | Student | 3 | student3@asd.com | S3 |
+      | student4 | Student | 4 | student4@asd.com | S4 |
+      | student5 | Student | 5 | student5@asd.com | S5 |
+      | student6 | Student | 6 | student6@asd.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 |
+
+  @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@asd.com)" user to "Group 1" group members
+    And I add "Student 2 (student2@asd.com)" user to "Group 1" group members
+    And I add "Student 3 (student3@asd.com)" user to "Group 2" group members
+    And I add "Student 4 (student4@asd.com)" user to "Group 2" group members
+    And I add "Student 5 (student5@asd.com)" user to "Group 3" group members
+    And I add "Student 6 (student6@asd.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 follow "Grades"
+    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
+    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 |
+      | id_config_usegroups | Yes |
+    And I press "Save changes"
+    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@asd.com)" user to "Group 1" group members
+    And I add "Student 2 (student2@asd.com)" user to "Group 1" group members
+    And I add "Student 3 (student3@asd.com)" user to "Group 2" group members
+    And I add "Student 4 (student4@asd.com)" user to "Group 2" group members
+    And I add "Student 5 (student5@asd.com)" user to "Group 3" group members
+    And I add "Student 6 (student6@asd.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 follow "Grades"
+    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
+    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 | Fractions |
+      | id_config_nameformat | Display full names |
+      | id_config_usegroups | Yes |
+    And I press "Save changes"
+    And I log out
+    Then I log in as "student1"
+    And I follow "Course 1"
+    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@asd.com)" user to "Group 1" group members
+    And I add "Student 2 (student2@asd.com)" user to "Group 1" group members
+    And I add "Student 3 (student3@asd.com)" user to "Group 2" group members
+    And I add "Student 4 (student4@asd.com)" user to "Group 2" group members
+    And I add "Student 5 (student5@asd.com)" user to "Group 3" group members
+    And I add "Student 6 (student6@asd.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 follow "Grades"
+    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
+    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 | Absolute numbers |
+      | id_config_nameformat | Display full names |
+      | id_config_usegroups | Yes |
+    And I press "Save changes"
+    And I log out
+    Then I log in as "student1"
+    And I follow "Course 1"
+    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@asd.com)" user to "Group 1" group members
+    And I add "Student 2 (student2@asd.com)" user to "Group 1" group members
+    And I add "Student 3 (student3@asd.com)" user to "Group 2" group members
+    And I add "Student 4 (student4@asd.com)" user to "Group 2" group members
+    And I add "Student 5 (student5@asd.com)" user to "Group 3" group members
+    And I add "Student 6 (student6@asd.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 follow "Grades"
+    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
+    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_gradeformat | Percentages |
+      | id_config_nameformat | Display full names |
+      | id_config_decimalpoints | 0 |
+      | id_config_usegroups | Yes |
+    And I press "Save changes"
+    Then I should see "Group 2" in the "Activity results" "block"
+    And I should see "85%" in the "Activity results" "block"
+    And I should see "Group 3" in the "Activity results" "block"
+    And I should see "75%" in the "Activity results" "block"
+    And I log out
+    And I log in as "student5"
+    And I follow "Course 1"
+    Then I should see "Group 2" in the "Activity results" "block"
+    And I should see "85%" in the "Activity results" "block"
+    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@asd.com)" user to "Group 1" group members
+    And I add "Student 2 (student2@asd.com)" user to "Group 1" group members
+    And I add "Student 3 (student3@asd.com)" user to "Group 2" group members
+    And I add "Student 4 (student4@asd.com)" user to "Group 2" group members
+    And I add "Student 5 (student5@asd.com)" user to "Group 3" group members
+    And I add "Student 6 (student6@asd.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 follow "Grades"
+    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
+    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_gradeformat | Fractions |
+      | id_config_nameformat | Display full names |
+      | id_config_usegroups | Yes |
+    And I press "Save changes"
+    And I log out
+    Then I log in as "student1"
+    And I follow "Course 1"
+    And I should see "Group 2" in the "Activity results" "block"
+    And I should see "85.00/100.00" in the "Activity results" "block"
+    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@asd.com)" user to "Group 1" group members
+    And I add "Student 2 (student2@asd.com)" user to "Group 1" group members
+    And I add "Student 3 (student3@asd.com)" user to "Group 2" group members
+    And I add "Student 4 (student4@asd.com)" user to "Group 2" group members
+    And I add "Student 5 (student5@asd.com)" user to "Group 3" group members
+    And I add "Student 6 (student6@asd.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 follow "Grades"
+    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
+    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_gradeformat | Absolute numbers |
+      | id_config_nameformat | Display full names |
+      | id_config_usegroups | Yes |
+    And I press "Save changes"
+    And I log out
+    Then I log in as "student1"
+    And I follow "Course 1"
+    And I should see "Group 2" in the "Activity results" "block"
+    And I should see "85.00" in the "Activity results" "block"
+    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@asd.com)" user to "Group 1" group members
+    And I add "Student 2 (student2@asd.com)" user to "Group 1" group members
+    And I add "Student 3 (student3@asd.com)" user to "Group 2" group members
+    And I add "Student 4 (student4@asd.com)" user to "Group 2" group members
+    And I add "Student 5 (student5@asd.com)" user to "Group 3" group members
+    And I add "Student 6 (student6@asd.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 follow "Grades"
+    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
+    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_gradeformat | Percentages |
+      | id_config_nameformat | Display only ID numbers |
+      | id_config_usegroups | Yes |
+    And I press "Save changes"
+    And I log out
+    Then I log in as "student1"
+    And I follow "Course 1"
+    And I should see "Group" in the "Activity results" "block"
+    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@asd.com)" user to "Group 1" group members
+    And I add "Student 2 (student2@asd.com)" user to "Group 1" group members
+    And I add "Student 3 (student3@asd.com)" user to "Group 2" group members
+    And I add "Student 4 (student4@asd.com)" user to "Group 2" group members
+    And I add "Student 5 (student5@asd.com)" user to "Group 3" group members
+    And I add "Student 6 (student6@asd.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 follow "Grades"
+    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
+    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_gradeformat | Percentages |
+      | id_config_nameformat | Anonymous results |
+      | id_config_usegroups | Yes |
+    And I press "Save changes"
+    And I log out
+    Then I log in as "student1"
+    And I follow "Course 1"
+    And I should see "Group" in the "Activity results" "block"
+    And I should see "85.00%" in the "Activity results" "block"
+    And I should see "75.00%" in the "Activity results" "block"
\ No newline at end of file
diff --git a/blocks/activity_results/version.php b/blocks/activity_results/version.php
new file mode 100644 (file)
index 0000000..96b0dc8
--- /dev/null
@@ -0,0 +1,29 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Version information for the block_quiz_results plugin.
+ *
+ * @package    block_activity_results
+ * @copyright  2015 Stephen Bourget
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+$plugin->version   = 2014111000;               // The current plugin version (Date: YYYYMMDDXX).
+$plugin->requires  = 2014110400;               // Requires this Moodle version.
+$plugin->component = 'block_activity_results'; // Full name of the plugin (used for diagnostics).
\ No newline at end of file
index 36c5407..548eea3 100644 (file)
@@ -57,18 +57,36 @@ class restore_quiz_results_block_task extends restore_block_task {
     public function after_restore() {
         global $DB;
 
-        // Get the blockid
+        // Get the blockid.
         $blockid = $this->get_blockid();
 
-        // Extract block configdata and update it to point to the new quiz
+        // Extract block configdata and update it to point to the new quiz.
         if ($configdata = $DB->get_field('block_instances', 'configdata', array('id' => $blockid))) {
             $config = unserialize(base64_decode($configdata));
             if (!empty($config->quizid)) {
-                // Get quiz mapping and replace it in config
+                // Get quiz mapping and replace it in config.
                 if ($quizmap = restore_dbops::get_backup_ids_record($this->get_restoreid(), 'quiz', $config->quizid)) {
-                    $config->quizid = $quizmap->newitemid;
-                    $configdata = base64_encode(serialize($config));
-                    $DB->set_field('block_instances', 'configdata', $configdata, array('id' => $blockid));
+                    $config->activityparent = 'quiz';
+                    $config->activityparentid = $quizmap->newitemid;
+
+                    // Set the decimal valuue as appropriate.
+                    if ($config->gradeformat == 1) {
+                        // This block is using percentages, do not display any decimal places.
+                        $config->decimalpoints = 0;
+                    } else {
+                        // Get the decimal value from the corresponding quiz.
+                        $config->decimalpoints = $DB->get_field('quiz', 'decimalpoints', array('id' => $config->activityparentid));
+                    }
+
+                    // Get the grade_items record to set the activitygradeitemid.
+                    $info = $DB->get_record('grade_items',
+                            array('iteminstance' => $config->activityparentid, 'itemmodule' => $config->activityparent));
+                    $config->activitygradeitemid = $info->id;
+                    unset($config->quizid);
+
+                    // Save the new configuration and update the record.
+                    $DB->set_field('block_instances', 'configdata', base64_encode(serialize($config)), array('id' => $blockid));
+                    $DB->set_field('block_instances', 'blockname', 'activity_results', array('id' => $blockid));
                 }
             }
         }
index 137a62b..3d7d649 100644 (file)
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
-
 defined('MOODLE_INTERNAL') || die();
 
 require_once($CFG->dirroot . '/mod/quiz/lib.php');
 
-
 /**
  * Block quiz_results class definition.
  *
@@ -38,441 +36,25 @@ require_once($CFG->dirroot . '/mod/quiz/lib.php');
  * @copyright  2009 Tim Hunt
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
-define('B_QUIZRESULTS_NAME_FORMAT_FULL', 1);
-define('B_QUIZRESULTS_NAME_FORMAT_ID',   2);
-define('B_QUIZRESULTS_NAME_FORMAT_ANON', 3);
-define('B_QUIZRESULTS_GRADE_FORMAT_PCT', 1);
-define('B_QUIZRESULTS_GRADE_FORMAT_FRA', 2);
-define('B_QUIZRESULTS_GRADE_FORMAT_ABS', 3);
-
 class block_quiz_results extends block_base {
     function init() {
         $this->title = get_string('pluginname', 'block_quiz_results');
     }
 
     function applicable_formats() {
-        return array('course' => true, 'mod-quiz' => true);
-    }
-
-    /**
-     * If this block belongs to a quiz context, then return that quiz's id.
-     * Otherwise, return 0.
-     * @return integer the quiz id.
-     */
-    public function get_owning_quiz() {
-        if (empty($this->instance->parentcontextid)) {
-            return 0;
-        }
-        $parentcontext = context::instance_by_id($this->instance->parentcontextid);
-        if ($parentcontext->contextlevel != CONTEXT_MODULE) {
-            return 0;
-        }
-        $cm = get_coursemodule_from_id('quiz', $parentcontext->instanceid);
-        if (!$cm) {
-            return 0;
-        }
-        return $cm->instance;
+        return array('mod-quiz' => true);
     }
 
     function instance_config_save($data, $nolongerused = false) {
-        if (empty($data->quizid)) {
-            $data->quizid = $this->get_owning_quiz();
-        }
         parent::instance_config_save($data);
     }
 
     function get_content() {
-        global $USER, $CFG, $DB;
-
-        if ($this->content !== NULL) {
-            return $this->content;
-        }
-
-        $this->content = new stdClass;
-        $this->content->text = '';
-        $this->content->footer = '';
-
-        if (empty($this->instance)) {
-            return $this->content;
-        }
-
-        if ($this->page->activityname == 'quiz' && $this->page->context->id == $this->instance->parentcontextid) {
-            $quiz = $this->page->activityrecord;
-            $quizid = $quiz->id;
-            $courseid = $this->page->course->id;
-            $inquiz = true;
-        } else if (!empty($this->config->quizid)) {
-            $quizid = $this->config->quizid;
-            $quiz = $DB->get_record('quiz', array('id' => $quizid));
-            if (empty($quiz)) {
-                $this->content->text = get_string('error_emptyquizrecord', 'block_quiz_results');
-                return $this->content;
-            }
-            $courseid = $quiz->course;
-            $inquiz = false;
-        } else {
-            $quizid = 0;
-        }
-
-        if (empty($quizid)) {
-            $this->content->text = get_string('error_emptyquizid', 'block_quiz_results');
-            return $this->content;
-        }
-
-        if (empty($this->config->showbest) && empty($this->config->showworst)) {
-            $this->content->text = get_string('configuredtoshownothing', 'block_quiz_results');
-            return $this->content;
-        }
-
-        // Get the grades for this quiz
-        $grades = $DB->get_records('quiz_grades', array('quiz' => $quizid), 'grade, timemodified DESC');
-
-        if (empty($grades)) {
-            // No grades, sorry
-            // The block will hide itself in this case
-            return $this->content;
-        }
-
-        $groupmode = NOGROUPS;
-        $best      = array();
-        $worst     = array();
-
-        if (!empty($this->config->nameformat)) {
-            $nameformat = $this->config->nameformat;
-        } else {
-            $nameformat = B_QUIZRESULTS_NAME_FORMAT_FULL;
-        }
-
-        if (!empty($this->config->usegroups)) {
-            if ($inquiz) {
-                $cm = $this->page->cm;
-                $context = $this->page->context;
-            } else {
-                $cm = get_coursemodule_from_instance('quiz', $quizid, $courseid);
-                $context = context_module::instance($cm->id);
-            }
-            $groupmode = groups_get_activity_groupmode($cm);
-
-            if ($groupmode == SEPARATEGROUPS && has_capability('moodle/site:accessallgroups', $context)) {
-                // We 'll make an exception in this case
-                $groupmode = VISIBLEGROUPS;
-            }
-        }
-
-        switch ($groupmode) {
-            case VISIBLEGROUPS:
-            // Display group-mode results
-            $groups = groups_get_all_groups($courseid);
-
-            if(empty($groups)) {
-                // No groups exist, sorry
-                $this->content->text = get_string('error_nogroupsexist', 'block_quiz_results');
-                return $this->content;
-            }
-
-            // Find out all the userids which have a submitted grade
-            $userids = array();
-            $gradeforuser = array();
-            foreach ($grades as $grade) {
-                $userids[] = $grade->userid;
-                $gradeforuser[$grade->userid] = (float)$grade->grade;
-            }
-
-            // Now find which groups these users belong in
-            list($usertest, $params) = $DB->get_in_or_equal($userids);
-            $params[] = $courseid;
-            $usergroups = $DB->get_records_sql('
-                    SELECT gm.id, gm.userid, gm.groupid, g.name
-                    FROM {groups} g
-                    LEFT JOIN {groups_members} gm ON g.id = gm.groupid
-                    WHERE gm.userid ' . $usertest . ' AND g.courseid = ?', $params);
-
-            // Now, iterate the grades again and sum them up for each group
-            $groupgrades = array();
-            foreach ($usergroups as $usergroup) {
-                if (!isset($groupgrades[$usergroup->groupid])) {
-                    $groupgrades[$usergroup->groupid] = array(
-                            'sum' => (float)$gradeforuser[$usergroup->userid],
-                            'number' => 1,
-                            'group' => $usergroup->name);
-                } else {
-                    $groupgrades[$usergroup->groupid]['sum'] += $gradeforuser[$usergroup->userid];
-                    $groupgrades[$usergroup->groupid]['number'] += 1;
-                }
-            }
-
-            foreach($groupgrades as $groupid => $groupgrade) {
-                $groupgrades[$groupid]['average'] = $groupgrades[$groupid]['sum'] / $groupgrades[$groupid]['number'];
-            }
-
-            // Sort groupgrades according to average grade, ascending
-            uasort($groupgrades, create_function('$a, $b', 'if($a["average"] == $b["average"]) return 0; return ($a["average"] > $b["average"] ? 1 : -1);'));
-
-            // How many groups do we have with graded member submissions to show?
-            $numbest  = empty($this->config->showbest) ? 0 : min($this->config->showbest, count($groupgrades));
-            $numworst = empty($this->config->showworst) ? 0 : min($this->config->showworst, count($groupgrades) - $numbest);
-
-            // Collect all the group results we are going to use in $best and $worst
-            $remaining = $numbest;
-            $groupgrade = end($groupgrades);
-            while ($remaining--) {
-                $best[key($groupgrades)] = $groupgrade['average'];
-                $groupgrade = prev($groupgrades);
-            }
-
-            $remaining = $numworst;
-            $groupgrade = reset($groupgrades);
-            while ($remaining--) {
-                $worst[key($groupgrades)] = $groupgrade['average'];
-                $groupgrade = next($groupgrades);
-            }
-
-            // Ready for output!
-            $gradeformat = intval(empty($this->config->gradeformat) ? B_QUIZRESULTS_GRADE_FORMAT_PCT : $this->config->gradeformat);
-
-            if (!$inquiz) {
-                // Don't show header and link to the quiz if we ARE at the quiz...
-                $this->content->text .= '<h1><a href="'.$CFG->wwwroot.'/mod/quiz/view.php?q='.$quizid.'">'.$quiz->name.'</a></h1>';
-            }
-
-            if ($nameformat = B_QUIZRESULTS_NAME_FORMAT_FULL) {
-                if (has_capability('moodle/course:managegroups', $context)) {
-                    $grouplink = $CFG->wwwroot.'/group/overview.php?id='.$courseid.'&amp;group=';
-                } else if (has_capability('moodle/course:viewparticipants', $context)) {
-                    $grouplink = $CFG->wwwroot.'/user/index.php?id='.$courseid.'&amp;group=';
-                } else {
-                    $grouplink = '';
-                }
-            }
-
-            $rank = 0;
-            if(!empty($best)) {
-                $this->content->text .= '<table class="grades"><caption>';
-                $this->content->text .= ($numbest == 1?get_string('bestgroupgrade', 'block_quiz_results'):get_string('bestgroupgrades', 'block_quiz_results', $numbest));
-                $this->content->text .= '</caption><colgroup class="number" /><colgroup class="name" /><colgroup class="grade" /><tbody>';
-                foreach($best as $groupid => $averagegrade) {
-                    switch($nameformat) {
-                        case B_QUIZRESULTS_NAME_FORMAT_ANON:
-                        case B_QUIZRESULTS_NAME_FORMAT_ID:
-                            $thisname = get_string('group');
-                        break;
-                        default:
-                        case B_QUIZRESULTS_NAME_FORMAT_FULL:
-                            if ($grouplink) {
-                                $thisname = '<a href="'.$grouplink.$groupid.'">'.$groupgrades[$groupid]['group'].'</a>';
-                            } else {
-                                $thisname = $groupgrades[$groupid]['group'];
-                            }
-                        break;
-                    }
-                    $this->content->text .= '<tr><td>'.(++$rank).'.</td><td>'.$thisname.'</td><td>';
-                    switch($gradeformat) {
-                        case B_QUIZRESULTS_GRADE_FORMAT_FRA:
-                            $this->content->text .= quiz_format_grade($quiz, $averagegrade).'/'.$quiz->grade;
-                        break;
-                        case B_QUIZRESULTS_GRADE_FORMAT_ABS:
-                            $this->content->text .= quiz_format_grade($quiz, $averagegrade);
-                        break;
-                        default:
-                        case B_QUIZRESULTS_GRADE_FORMAT_PCT:
-                            $this->content->text .= round((float)$averagegrade / (float)$quiz->grade * 100).'%';
-                        break;
-                    }
-                    $this->content->text .= '</td></tr>';
-                }
-                $this->content->text .= '</tbody></table>';
-            }
-
-            $rank = 0;
-            if(!empty($worst)) {
-                $worst = array_reverse($worst, true);
-                $this->content->text .= '<table class="grades"><caption>';
-                $this->content->text .= ($numworst == 1?get_string('worstgroupgrade', 'block_quiz_results'):get_string('worstgroupgrades', 'block_quiz_results', $numworst));
-                $this->content->text .= '</caption><colgroup class="number" /><colgroup class="name" /><colgroup class="grade" /><tbody>';
-                foreach($worst as $groupid => $averagegrade) {
-                    switch($nameformat) {
-                        case B_QUIZRESULTS_NAME_FORMAT_ANON:
-                        case B_QUIZRESULTS_NAME_FORMAT_ID:
-                            $thisname = get_string('group');
-                        break;
-                        default:
-                        case B_QUIZRESULTS_NAME_FORMAT_FULL:
-                            $thisname = '<a href="'.$CFG->wwwroot.'/course/group.php?group='.$groupid.'&amp;id='.$courseid.'">'.$groupgrades[$groupid]['group'].'</a>';
-                        break;
-                    }
-                    $this->content->text .= '<tr><td>'.(++$rank).'.</td><td>'.$thisname.'</td><td>';
-                    switch($gradeformat) {
-                        case B_QUIZRESULTS_GRADE_FORMAT_FRA:
-                            $this->content->text .= quiz_format_grade($quiz, $averagegrade).'/'.$quiz->grade;
-                        break;
-                        case B_QUIZRESULTS_GRADE_FORMAT_ABS:
-                            $this->content->text .= quiz_format_grade($quiz, $averagegrade);
-                        break;
-                        default:
-                        case B_QUIZRESULTS_GRADE_FORMAT_PCT:
-                            $this->content->text .= round((float)$averagegrade / (float)$quiz->grade * 100).'%';
-                        break;
-                    }
-                    $this->content->text .= '</td></tr>';
-                }
-                $this->content->text .= '</tbody></table>';
-            }
-            break;
-
-
-            case SEPARATEGROUPS:
-            // This is going to be just like no-groups mode, only we 'll filter
-            // out the grades from people not in our group.
-            if (!isloggedin()) {
-                // Not logged in, so show nothing
-                return $this->content;
-            }
-
-            $mygroups = groups_get_all_groups($courseid, $USER->id);
-            if(empty($mygroups)) {
-                // Not member of a group, show nothing
-                return $this->content;
-            }
-
-            // Get users from the same groups as me.
-            list($grouptest, $params) = $DB->get_in_or_equal(array_keys($mygroups));
-            $mygroupsusers = $DB->get_records_sql_menu(
-                    'SELECT DISTINCT userid, 1 FROM {groups_members} WHERE groupid ' . $grouptest,
-                    $params);
-
-            // Filter out the grades belonging to other users, and proceed as if there were no groups
-            foreach ($grades as $key => $grade) {
-                if (!isset($mygroupsusers[$grade->userid])) {
-                    unset($grades[$key]);
-                }
-            }
-
-            // No break, fall through to the default case now we have filtered the $grades array.
-            default:
-            case NOGROUPS:
-            // Single user mode
-            $numbest  = empty($this->config->showbest) ? 0 : min($this->config->showbest, count($grades));
-            $numworst = empty($this->config->showworst) ? 0 : min($this->config->showworst, count($grades) - $numbest);
-
-            // Collect all the usernames we are going to need
-            $remaining = $numbest;
-            $grade = end($grades);
-            while($remaining--) {
-                $best[$grade->userid] = $grade->id;
-                $grade = prev($grades);
-            }
-
-            $remaining = $numworst;
-            $grade = reset($grades);
-            while($remaining--) {
-                $worst[$grade->userid] = $grade->id;
-                $grade = next($grades);
-            }
-
-            if(empty($best) && empty($worst)) {
-                // Nothing to show, for some reason...
-                return $this->content;
-            }
-
-            // Now grab all the users from the database
-            $userids = array_merge(array_keys($best), array_keys($worst));
-            $fields = array_merge(array('id', 'idnumber'), get_all_user_name_fields());
-            $fields = implode(',', $fields);
-            $users = $DB->get_records_list('user', 'id', $userids, '', $fields);
-
-            // Ready for output!
-
-            $gradeformat = intval(empty($this->config->gradeformat) ? B_QUIZRESULTS_GRADE_FORMAT_PCT : $this->config->gradeformat);
-
-            if(!$inquiz) {
-                // Don't show header and link to the quiz if we ARE at the quiz...
-                $this->content->text .= '<h1><a href="'.$CFG->wwwroot.'/mod/quiz/view.php?q='.$quizid.'">'.$quiz->name.'</a></h1>';
-            }
-
-            $rank = 0;
-            if(!empty($best)) {
-                $this->content->text .= '<table class="grades"><caption>';
-                $this->content->text .= ($numbest == 1?get_string('bestgrade', 'block_quiz_results'):get_string('bestgrades', 'block_quiz_results', $numbest));
-                $this->content->text .= '</caption><colgroup class="number" /><colgroup class="name" /><colgroup class="grade" /><tbody>';
-                foreach($best as $userid => $gradeid) {
-                    switch($nameformat) {
-                        case B_QUIZRESULTS_NAME_FORMAT_ID:
-                            $thisname = get_string('user').' '.$users[$userid]->idnumber;
-                        break;
-                        case B_QUIZRESULTS_NAME_FORMAT_ANON:
-                            $thisname = get_string('user');
-                        break;
-                        default:
-                        case B_QUIZRESULTS_NAME_FORMAT_FULL:
-                            $thisname = '<a href="'.$CFG->wwwroot.'/user/view.php?id='.$userid.'&amp;course='.$courseid.'">'.fullname($users[$userid]).'</a>';
-                        break;
-                    }
-                    $this->content->text .= '<tr><td>'.(++$rank).'.</td><td>'.$thisname.'</td><td>';
-                    switch($gradeformat) {
-                        case B_QUIZRESULTS_GRADE_FORMAT_FRA:
-                            $this->content->text .=  quiz_format_grade($quiz, $grades[$gradeid]->grade).'/'.$quiz->grade;
-                        break;
-                        case B_QUIZRESULTS_GRADE_FORMAT_ABS:
-                            $this->content->text .= quiz_format_grade($quiz, $grades[$gradeid]->grade);
-                        break;
-                        default:
-                        case B_QUIZRESULTS_GRADE_FORMAT_PCT:
-                            if ($quiz->grade) {
-                                $this->content->text .= round((float)$grades[$gradeid]->grade / (float)$quiz->grade * 100).'%';
-                            } else {
-                                $this->content->text .= '--%';
-                            }
-                        break;
-                    }
-                    $this->content->text .= '</td></tr>';
-                }
-                $this->content->text .= '</tbody></table>';
-            }
-
-            $rank = 0;
-            if(!empty($worst)) {
-                $worst = array_reverse($worst, true);
-                $this->content->text .= '<table class="grades"><caption>';
-                $this->content->text .= ($numworst == 1?get_string('worstgrade', 'block_quiz_results'):get_string('worstgrades', 'block_quiz_results', $numworst));
-                $this->content->text .= '</caption><colgroup class="number" /><colgroup class="name" /><colgroup class="grade" /><tbody>';
-                foreach($worst as $userid => $gradeid) {
-                    switch($nameformat) {
-                        case B_QUIZRESULTS_NAME_FORMAT_ID:
-                            $thisname = get_string('user').' '.$users[$userid]->idnumber;
-                        break;
-                        case B_QUIZRESULTS_NAME_FORMAT_ANON:
-                            $thisname = get_string('user');
-                        break;
-                        default:
-                        case B_QUIZRESULTS_NAME_FORMAT_FULL:
-                            $thisname = '<a href="'.$CFG->wwwroot.'/user/view.php?id='.$userid.'&amp;course='.$courseid.'">'.fullname($users[$userid]).'</a>';
-                        break;
-                    }
-                    $this->content->text .= '<tr><td>'.(++$rank).'.</td><td>'.$thisname.'</td><td>';
-                    switch($gradeformat) {
-                        case B_QUIZRESULTS_GRADE_FORMAT_FRA:
-                            $this->content->text .= quiz_format_grade($quiz, $grades[$gradeid]->grade).'/'.$quiz->grade;
-                        break;
-                        case B_QUIZRESULTS_GRADE_FORMAT_ABS:
-                            $this->content->text .= quiz_format_grade($quiz, $grades[$gradeid]->grade);
-                        break;
-                        default:
-                        case B_QUIZRESULTS_GRADE_FORMAT_PCT:
-                            $this->content->text .= round((float)$grades[$gradeid]->grade / (float)$quiz->grade * 100).'%';
-                        break;
-                    }
-                    $this->content->text .= '</td></tr>';
-                }
-                $this->content->text .= '</tbody></table>';
-            }
-            break;
-        }
-
         return $this->content;
     }
 
     function instance_allow_multiple() {
-        return true;
+        return false;
     }
 }
 
diff --git a/blocks/quiz_results/db/install.php b/blocks/quiz_results/db/install.php
new file mode 100644 (file)
index 0000000..255cdba
--- /dev/null
@@ -0,0 +1,31 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Quiz results block installation.
+ *
+ * @package    block_quiz_results
+ * @copyright  2015 Dan Poltawski <dan@moodle.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+function xmldb_block_quiz_results_install() {
+    global $DB;
+
+    // Disable quiz_results on new installs (its now just a stub).
+    $DB->set_field('block', 'visible', 0, array('name' => 'quiz_results'));
+}
+
diff --git a/blocks/quiz_results/db/upgrade.php b/blocks/quiz_results/db/upgrade.php
new file mode 100644 (file)
index 0000000..85cceef
--- /dev/null
@@ -0,0 +1,93 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * This file keeps track of upgrades to the quiz_results block
+ *
+ * Sometimes, changes between versions involve alterations to database structures
+ * and other major things that may break installations.
+ *
+ * The upgrade function in this file will attempt to perform all the necessary
+ * actions to upgrade your older installation to the current version.
+ *
+ * If there's something it cannot do itself, it will tell you what you need to do.
+ *
+ * The commands in here will all be database-neutral, using the methods of
+ * database_manager class
+ *
+ * Please do not forget to use upgrade_set_timeout()
+ * before any action that may take longer time to finish.
+ *
+ * @since Moodle 2.9
+ * @package block_quiz_results
+ * @copyright 2015 Stephen Bourget
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+/**
+ * Upgrade the quiz_results block
+ * @param int $oldversion
+ * @param object $block
+ */
+function xmldb_block_quiz_results_upgrade($oldversion, $block) {
+    global $DB, $CFG;
+
+    if ($oldversion < 2015022200) {
+        // Only migrate if the block_activity_results is installed.
+        if (is_dir($CFG->dirroot . '/blocks/activity_results')) {
+
+            // Migrate all instances of block_quiz_results to block_activity_results.
+            $records = $DB->get_records('block_instances', array('blockname' => 'quiz_results'));
+            foreach ($records as $record) {
+                $config = unserialize(base64_decode($record->configdata));
+                $config->activityparent = 'quiz';
+                $config->activityparentid = $config->quizid;
+
+                // Set the decimal valuue as appropriate.
+                if ($config->gradeformat == 1) {
+                    // This block is using percentages, do not display any decimal places.
+                    $config->decimalpoints = 0;
+                } else {
+                    // Get the decimal value from the corresponding quiz.
+                    $config->decimalpoints = $DB->get_field('quiz', 'decimalpoints', array('id' => $config->activityparentid));
+                }
+
+                // Get the grade_items record to set the activitygradeitemid.
+                $info = $DB->get_record('grade_items',
+                        array('iteminstance' => $config->activityparentid, 'itemmodule' => $config->activityparent));
+                $config->activitygradeitemid = $info->id;
+                unset($config->quizid);
+
+                // Save the new configuration and update the record.
+                $record->configdata = base64_encode(serialize($config));
+                $record->blockname = 'activity_results';
+                $DB->update_record('block_instances', $record);
+            }
+
+            // Disable the Quiz_results block.
+            if ($block = $DB->get_record("block", array("name" => "quiz_results"))) {
+                $DB->set_field("block", "visible", "0", array("id" => $block->id));
+            }
+
+        }
+        upgrade_block_savepoint(true, 2015022200, 'quiz_results');
+    }
+
+    // Moodle v2.8.0 release upgrade line.
+    // Put any upgrade step following this.
+
+    return true;
+}
\ No newline at end of file
diff --git a/blocks/quiz_results/edit_form.php b/blocks/quiz_results/edit_form.php
deleted file mode 100644 (file)
index bddb705..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * Defines the form for editing Quiz results block instances.
- *
- * @package    block_quiz_results
- * @copyright 2009 Tim Hunt
- * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-defined('MOODLE_INTERNAL') || die();
-
-
-/**
- * Form for editing Quiz results block instances.
- *
- * @copyright 2009 Tim Hunt
- * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-class block_quiz_results_edit_form extends block_edit_form {
-    protected function specific_definition($mform) {
-        global $DB;
-
-        // Fields for editing HTML block title and contents.
-        $mform->addElement('header', 'configheader', get_string('blocksettings', 'block'));
-
-        if (!$this->block->get_owning_quiz()) {
-            $quizzes = $DB->get_records_menu('quiz', array('course' => $this->page->course->id), '', 'id, name');
-            if(empty($quizzes)) {
-                $mform->addElement('static', 'noquizzeswarning', get_string('config_select_quiz', 'block_quiz_results'),
-                        get_string('config_no_quizzes_in_course', 'block_quiz_results'));
-            } else {
-                foreach($quizzes as $id => $name) {
-                    $quizzes[$id] = strip_tags(format_string($name));
-                }
-                $mform->addElement('select', 'config_quizid', get_string('config_select_quiz', 'block_quiz_results'), $quizzes);
-            }
-        }
-
-        $mform->addElement('text', 'config_showbest', get_string('config_show_best', 'block_quiz_results'), array('size' => 3));
-        $mform->setDefault('config_showbest', 3);
-        $mform->setType('config_showbest', PARAM_INT);
-
-        $mform->addElement('text', 'config_showworst', get_string('config_show_worst', 'block_quiz_results'), array('size' => 3));
-        $mform->setDefault('config_showworst', 0);
-        $mform->setType('config_showworst', PARAM_INT);
-
-        $mform->addElement('selectyesno', 'config_usegroups', get_string('config_use_groups', 'block_quiz_results'));
-
-        $nameoptions = array(
-            B_QUIZRESULTS_NAME_FORMAT_FULL => get_string('config_names_full', 'block_quiz_results'),
-            B_QUIZRESULTS_NAME_FORMAT_ID => get_string('config_names_id', 'block_quiz_results'),
-            B_QUIZRESULTS_NAME_FORMAT_ANON => get_string('config_names_anon', 'block_quiz_results')
-        );
-        $mform->addElement('select', 'config_nameformat', get_string('config_name_format', 'block_quiz_results'), $nameoptions);
-        $mform->setDefault('config_nameformat', B_QUIZRESULTS_NAME_FORMAT_FULL);
-
-        $gradeeoptions = array(
-            B_QUIZRESULTS_GRADE_FORMAT_PCT => get_string('config_format_percentage', 'block_quiz_results'),
-            B_QUIZRESULTS_GRADE_FORMAT_FRA => get_string('config_format_fraction', 'block_quiz_results'),
-            B_QUIZRESULTS_GRADE_FORMAT_ABS => get_string('config_format_absolute', 'block_quiz_results')
-        );
-        $mform->addElement('select', 'config_gradeformat', get_string('config_grade_format', 'block_quiz_results'), $gradeeoptions);
-        $mform->setDefault('config_gradeformat', B_QUIZRESULTS_GRADE_FORMAT_PCT);
-    }
-}
\ No newline at end of file
index f6d758a..03bcd16 100644 (file)
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
+$string['pluginname'] = 'Quiz results (disabled)';
+$string['quiz_results:addinstance'] = 'Add a new quiz results block';
+
+// Deprecated since Moodle 2.9.
 $string['bestgrade'] = 'The highest grade:';
 $string['bestgrades'] = 'The {$a} highest grades:';
 $string['bestgroupgrade'] = 'The group with the highest average:';
@@ -43,8 +47,6 @@ $string['config_use_groups'] = 'Show groups instead of students (only if the qui
 $string['error_emptyquizid'] = 'There is an error right now with this block: you need to select which quiz it should display results from.';
 $string['error_emptyquizrecord'] = 'There is an error right now with this block: the selected quiz does not seem to exist in the database.';
 $string['error_nogroupsexist'] = 'There is an error right now with this block: it is set to display grades in group mode, but the course has no defined groups.';
-$string['pluginname'] = 'Quiz results';
-$string['quiz_results:addinstance'] = 'Add a new quiz results block';
 $string['worstgrade'] = 'The lowest grade:';
 $string['worstgrades'] = 'The {$a} lowest grades:';
 $string['worstgroupgrade'] = 'The group with the lowest average:';
diff --git a/blocks/quiz_results/lang/en/depreciated.txt b/blocks/quiz_results/lang/en/depreciated.txt
new file mode 100644 (file)
index 0000000..af64c64
--- /dev/null
@@ -0,0 +1,25 @@
+bestgrade,block_quiz_results
+bestgrades,block_quiz_results
+bestgroupgrade,block_quiz_results
+bestgroupgrades,block_quiz_results
+config_format_absolute,block_quiz_results
+config_format_fraction,block_quiz_results
+config_format_percentage,block_quiz_results
+config_grade_format,block_quiz_results
+config_name_format,block_quiz_results
+config_names_anon,block_quiz_results
+config_names_full,block_quiz_results
+config_names_id,block_quiz_results
+config_no_quizzes_in_course,block_quiz_results
+config_select_quiz,block_quiz_results
+config_show_best,block_quiz_results
+config_show_worst,block_quiz_results
+configuredtoshownothing,block_quiz_results
+config_use_groups,block_quiz_results
+error_emptyquizid,block_quiz_results
+error_emptyquizrecord,block_quiz_results
+error_nogroupsexist,block_quiz_results
+worstgrade,block_quiz_results
+worstgrades,block_quiz_results
+worstgroupgrade,block_quiz_results
+worstgroupgrades,block_quiz_results
\ No newline at end of file
diff --git a/blocks/quiz_results/styles.css b/blocks/quiz_results/styles.css
deleted file mode 100644 (file)
index 0f2dda9..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-.block_quiz_results {text-align: center;}
-.block_quiz_results h1 {margin: 4px;font-size: 1.1em;}
-.block_quiz_results table.grades {text-align: left;width: 100%;}
-.block_quiz_results table.grades .number,
-.block_quiz_results table.grades .grade {text-align: right;width: 10%;}
-.block_quiz_results table.grades caption {margin: 1em 0px 0px 0px;border-bottom-width: 1px;border-bottom-style: solid;font-weight: bold;}
index 88308e5..be5bfde 100644 (file)
@@ -24,7 +24,7 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2014111000;        // The current plugin version (Date: YYYYMMDDXX)
+$plugin->version   = 2015022200;        // The current plugin version (Date: YYYYMMDDXX)
 $plugin->requires  = 2014110400;        // Requires this Moodle version
 $plugin->component = 'block_quiz_results'; // Full name of the plugin (used for diagnostics)
 
index 572238a..605c328 100644 (file)
@@ -659,8 +659,14 @@ function calendar_add_event_metadata($event) {
         $event->courselink = calendar_get_courselink($event->courseid);
         $event->cssclass = 'calendar_event_course';
     } else if ($event->groupid) {                                    // Group event
-        $event->icon = '<img src="'.$OUTPUT->pix_url('i/groupevent') . '" alt="'.get_string('groupevent', 'calendar').'" class="icon" />';
-        $event->courselink = calendar_get_courselink($event->courseid);
+        if ($group = calendar_get_group_cached($event->groupid)) {
+            $groupname = format_string($group->name, true, context_course::instance($group->courseid));
+        } else {
+            $groupname = '';
+        }
+        $event->icon = html_writer::empty_tag('image', array('src' => $OUTPUT->pix_url('i/groupevent'),
+            'alt' => get_string('groupevent', 'calendar'), 'title' => $groupname, 'class' => 'icon'));
+        $event->courselink = calendar_get_courselink($event->courseid) . ', ' . $groupname;
         $event->cssclass = 'calendar_event_group';
     } else if($event->userid) {                                      // User event
         $event->icon = '<img src="'.$OUTPUT->pix_url('i/userevent') . '" alt="'.get_string('userevent', 'calendar').'" class="icon" />';
@@ -1415,6 +1421,20 @@ function calendar_get_course_cached(&$coursecache, $courseid) {
     return $coursecache[$courseid];
 }
 
+/**
+ * Get group from groupid for calendar display
+ *
+ * @param int $groupid
+ * @return stdClass group object with fields 'id', 'name' and 'courseid'
+ */
+function calendar_get_group_cached($groupid) {
+    static $groupscache = array();
+    if (!isset($groupscache[$groupid])) {
+        $groupscache[$groupid] = groups_get_group($groupid, 'id,name,courseid');
+    }
+    return $groupscache[$groupid];
+}
+
 /**
  * Returns the courses to load events for, the
  *
@@ -2947,7 +2967,7 @@ function calendar_add_icalendar_event($event, $courseid, $subscriptionid, $timez
     $name = $event->properties['SUMMARY'][0]->value;
     $name = str_replace('\n', '<br />', $name);
     $name = str_replace('\\', '', $name);
-    $name = preg_replace('/\s+/', ' ', $name);
+    $name = preg_replace('/\s+/u', ' ', $name);
 
     $eventrecord = new stdClass;
     $eventrecord->name = clean_param($name, PARAM_NOTAGS);
@@ -2959,7 +2979,7 @@ function calendar_add_icalendar_event($event, $courseid, $subscriptionid, $timez
         $description = clean_param($description, PARAM_NOTAGS);
         $description = str_replace('\n', '<br />', $description);
         $description = str_replace('\\', '', $description);
-        $description = preg_replace('/\s+/', ' ', $description);
+        $description = preg_replace('/\s+/u', ' ', $description);
     }
     $eventrecord->description = $description;
 
index 619590c..de0e752 100644 (file)
@@ -9,12 +9,20 @@ Feature: Perform basic calendar functionality
       | username | firstname | lastname | email |
       | student1 | Student | 1 | student1@asd.com |
       | student2 | Student | 2 | student2@asd.com |
+      | student3 | Student | 3 | student3@asd.com |
     And the following "courses" exist:
       | fullname | shortname | format |
       | Course 1 | C1 | topics |
     And the following "course enrolments" exist:
       | user | course | role |
       | student1 | C1 | student |
+      | student3 | C1 | student |
+    And the following "groups" exist:
+      | name | course | idnumber |
+      | Group 1 | C1 | G1 |
+    And the following "group members" exist:
+      | user | group |
+      | student1 | G1 |
     When I log in as "admin"
     And I follow "Course 1"
     And I turn editing mode on
@@ -50,6 +58,23 @@ Feature: Perform basic calendar functionality
     And I follow "This month"
     And I should not see "Really awesome event!"
 
+  Scenario: Create a group event
+    And I create a calendar event with form data:
+      | Type of event | group |
+      | Group | Group 1 |
+      | Event title | Really awesome event! |
+      | Description | Come join this awesome event |
+    And I log out
+    And I log in as "student1"
+    And I follow "Course 1"
+    And I follow "This month"
+    And I follow "Really awesome event!"
+    And "Group 1" "text" should exist in the ".eventlist" "css_element"
+    And I log out
+    And I log in as "student3"
+    And I follow "This month"
+    And I should not see "Really awesome event!"
+
   Scenario: Create a user event
     And I create a calendar event with form data:
       | Type of event | user |
diff --git a/completion/classes/external.php b/completion/classes/external.php
new file mode 100644 (file)
index 0000000..4d9c32e
--- /dev/null
@@ -0,0 +1,117 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Completion external API
+ *
+ * @package    core_completion
+ * @category   external
+ * @copyright  2015 Juan Leyva <juan@moodle.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @since      Moodle 2.9
+ */
+
+defined('MOODLE_INTERNAL') || die;
+
+require_once("$CFG->libdir/externallib.php");
+require_once("$CFG->libdir/completionlib.php");
+
+/**
+ * Completion external functions
+ *
+ * @package    core_completion
+ * @category   external
+ * @copyright  2015 Juan Leyva <juan@moodle.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @since      Moodle 2.9
+ */
+class core_completion_external extends external_api {
+
+    /**
+     * Describes the parameters for update_activity_completion_status_manually.
+     *
+     * @return external_external_function_parameters
+     * @since Moodle 2.9
+     */
+    public static function update_activity_completion_status_manually_parameters() {
+        return new external_function_parameters (
+            array(
+                'cmid' => new external_value(PARAM_INT, 'course module id'),
+                'completed' => new external_value(PARAM_BOOL, 'activity completed or not'),
+            )
+        );
+    }
+
+    /**
+     * Update completion status for the current user in an activity, only for activities with manual tracking.
+     * @param  int $cmid      Course module id
+     * @param  bool $completed Activity completed or not
+     * @return array            Result and possible warnings
+     * @since Moodle 2.9
+     * @throws moodle_exception
+     */
+    public static function update_activity_completion_status_manually($cmid,  $completed) {
+
+        // Validate and normalize parameters.
+        $params = self::validate_parameters(self::update_activity_completion_status_manually_parameters(),
+            array('cmid' => $cmid, 'completed' => $completed));
+        $cmid = $params['cmid'];
+        $completed = $params['completed'];
+
+        $warnings = array();
+
+        $context = context_module::instance($cmid);
+        self::validate_context($context);
+
+        list($course, $cm) = get_course_and_cm_from_cmid($cmid);
+
+        // Set up completion object and check it is enabled.
+        $completion = new completion_info($course);
+        if (!$completion->is_enabled()) {
+            throw new moodle_exception('completionnotenabled', 'completion');
+        }
+
+        // Check completion state is manual.
+        if ($cm->completion != COMPLETION_TRACKING_MANUAL) {
+            throw new moodle_exception('cannotmanualctrack', 'error');
+        }
+
+        $targetstate = ($completed) ? COMPLETION_COMPLETE : COMPLETION_INCOMPLETE;
+        $completion->update_state($cm, $targetstate);
+
+        $result = array();
+        $result['status'] = true;
+        $result['warnings'] = $warnings;
+        return $result;
+    }
+
+    /**
+     * Describes the update_activity_completion_status_manually return value.
+     *
+     * @return external_single_structure
+     * @since Moodle 2.9
+     */
+    public static function update_activity_completion_status_manually_returns() {
+
+        return new external_single_structure(
+            array(
+                'status'    => new external_value(PARAM_BOOL, 'status, true if success'),
+                'warnings'  => new external_warnings(),
+            )
+        );
+    }
+
+}
diff --git a/completion/tests/externallib_test.php b/completion/tests/externallib_test.php
new file mode 100644 (file)
index 0000000..24ee1a7
--- /dev/null
@@ -0,0 +1,90 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * External completion functions unit tests
+ *
+ * @package    core_completion
+ * @category   external
+ * @copyright  2015 Juan Leyva <juan@moodle.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @since      Moodle 2.9
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+global $CFG;
+
+require_once($CFG->dirroot . '/webservice/tests/helpers.php');
+
+/**
+ * External completion functions unit tests
+ *
+ * @package    core_completion
+ * @category   external
+ * @copyright  2015 Juan Leyva <juan@moodle.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @since      Moodle 2.9
+ */
+class core_completion_externallib_testcase extends externallib_advanced_testcase {
+
+    /**
+     * Test update_activity_completion_status_manually
+     */
+    public function test_update_activity_completion_status_manually() {
+        global $DB, $CFG;
+
+        $this->resetAfterTest(true);
+
+        $CFG->enablecompletion = true;
+        $user = $this->getDataGenerator()->create_user();
+        $course = $this->getDataGenerator()->create_course(array('enablecompletion' => 1));
+        $data = $this->getDataGenerator()->create_module('data', array('course' => $course->id),
+                                                             array('completion' => 1));
+        $cm = get_coursemodule_from_id('data', $data->cmid);
+
+        $studentrole = $DB->get_record('role', array('shortname' => 'student'));
+        $this->getDataGenerator()->enrol_user($user->id, $course->id, $studentrole->id);
+
+        $this->setUser($user);
+
+        $result = core_completion_external::update_activity_completion_status_manually($data->cmid, true);
+        // We need to execute the return values cleaning process to simulate the web service server.
+        $result = external_api::clean_returnvalue(
+            core_completion_external::update_activity_completion_status_manually_returns(), $result);
+
+        // Check in DB.
+        $this->assertEquals(1, $DB->get_field('course_modules_completion', 'completionstate',
+                            array('coursemoduleid' => $data->cmid)));
+
+        // Check using the API.
+        $completion = new completion_info($course);
+        $completiondata = $completion->get_data($cm);
+        $this->assertEquals(1, $completiondata->completionstate);
+        $this->assertTrue($result['status']);
+
+        $result = core_completion_external::update_activity_completion_status_manually($data->cmid, false);
+        // We need to execute the return values cleaning process to simulate the web service server.
+        $result = external_api::clean_returnvalue(
+            core_completion_external::update_activity_completion_status_manually_returns(), $result);
+
+        $this->assertEquals(0, $DB->get_field('course_modules_completion', 'completionstate',
+                            array('coursemoduleid' => $data->cmid)));
+        $completiondata = $completion->get_data($cm);
+        $this->assertEquals(0, $completiondata->completionstate);
+        $this->assertTrue($result['status']);
+    }
+}
index 60864a8..d1c1fff 100644 (file)
@@ -8,6 +8,6 @@
     "require-dev": {
         "phpunit/phpunit": "3.7.*",
         "phpunit/dbUnit": "1.2.*",
-        "moodlehq/behat-extension": "1.29.3"
+        "moodlehq/behat-extension": "1.29.4"
     }
 }
index 234e3ad..aaa87e9 100644 (file)
@@ -189,6 +189,10 @@ if (!empty($add)) {
                                              'iteminstance'=>$data->instance, 'courseid'=>$course->id))) {
         // add existing outcomes
         foreach ($items as $item) {
+            if (!empty($item->gradepass)) {
+                $decimalpoints = $item->get_decimals();
+                $data->gradepass = format_float($item->gradepass, $decimalpoints);
+            }
             if (!empty($item->outcomeid)) {
                 $data->{'outcome_'.$item->outcomeid} = 1;
             }
index 9a44714..ed653ce 100644 (file)
@@ -191,8 +191,16 @@ function edit_module_post_actions($moduleinfo, $course) {
     // Sync idnumber with grade_item.
     if ($hasgrades && $grade_item = grade_item::fetch(array('itemtype'=>'mod', 'itemmodule'=>$moduleinfo->modulename,
                  'iteminstance'=>$moduleinfo->instance, 'itemnumber'=>0, 'courseid'=>$course->id))) {
+        $gradeupdate = false;
         if ($grade_item->idnumber != $moduleinfo->cmidnumber) {
             $grade_item->idnumber = $moduleinfo->cmidnumber;
+            $gradeupdate = true;
+        }
+        if (isset($moduleinfo->gradepass) && $grade_item->gradepass != $moduleinfo->gradepass) {
+            $grade_item->gradepass = $moduleinfo->gradepass;
+            $gradeupdate = true;
+        }
+        if ($gradeupdate) {
             $grade_item->update();
         }
     }
index 6a3a845..3d485ae 100644 (file)
@@ -299,6 +299,22 @@ abstract class moodleform_mod extends moodleform {
             $errors['assessed'] = get_string('scaleselectionrequired', 'rating');
         }
 
+        // Grade to pass: ensure that the grade to pass is valid for points and scales.
+        // If we are working with a scale, convert into a positive number for validation.
+
+        if (isset($data['gradepass']) && (!empty($data['grade']) || !empty($data['scale']))) {
+            $scale = !empty($data['grade']) ? $data['grade'] : $data['scale'];
+            if ($scale < 0) {
+                $scalevalues = $DB->get_record('scale', array('id' => -$scale));
+                $grade = count(explode(',', $scalevalues->scale));
+            } else {
+                $grade = $scale;
+            }
+            if ($data['gradepass'] > $grade) {
+                $errors['gradepass'] = get_string('gradepassgreaterthangrade', 'grades', $grade);
+            }
+        }
+
         // Completion: Don't let them choose automatic completion without turning
         // on some conditions. Ignore this check when completion settings are
         // locked, as the options are then disabled.
@@ -624,6 +640,9 @@ abstract class moodleform_mod extends moodleform {
                     $mform->addElement('select', 'advancedgradingmethod_'.$areaname,
                         get_string('gradingmethod', 'core_grading'), $this->current->_advancedgradingdata['methods']);
                     $mform->addHelpButton('advancedgradingmethod_'.$areaname, 'gradingmethod', 'core_grading');
+                    if (!$this->_features->rating) {
+                        $mform->disabledIf('advancedgradingmethod_'.$areaname, 'grade[modgrade_type]', 'eq', 'none');
+                    }
 
                 } else {
                     // the module defines multiple gradable areas, display a selector
@@ -644,6 +663,19 @@ abstract class moodleform_mod extends moodleform {
                         get_string('gradecategoryonmodform', 'grades'),
                         grade_get_categories_menu($COURSE->id, $this->_outcomesused));
                 $mform->addHelpButton('gradecat', 'gradecategoryonmodform', 'grades');
+                if (!$this->_features->rating) {
+                    $mform->disabledIf('gradecat', 'grade[modgrade_type]', 'eq', 'none');
+                }
+            }
+
+            // Grade to pass.
+            $mform->addElement('text', 'gradepass', get_string('gradepass', 'grades'));
+            $mform->addHelpButton('gradepass', 'gradepass', 'grades');
+            $mform->setDefault('gradepass', '');
+            $mform->setType('gradepass', PARAM_FLOAT);
+            $mform->addRule('gradepass', null, 'numeric', null, 'client');
+            if (!$this->_features->rating) {
+                $mform->disabledIf('gradepass', 'grade[modgrade_type]', 'eq', 'none');
             }
         }
     }
index 17db276..08ce8ea 100644 (file)
Binary files a/course/yui/build/moodle-course-dragdrop/moodle-course-dragdrop-debug.js and b/course/yui/build/moodle-course-dragdrop/moodle-course-dragdrop-debug.js differ
index 8a8b5b6..0af8c1b 100644 (file)
Binary files a/course/yui/build/moodle-course-dragdrop/moodle-course-dragdrop-min.js and b/course/yui/build/moodle-course-dragdrop/moodle-course-dragdrop-min.js differ
index df6d54b..9da1d7d 100644 (file)
Binary files a/course/yui/build/moodle-course-dragdrop/moodle-course-dragdrop.js and b/course/yui/build/moodle-course-dragdrop/moodle-course-dragdrop.js differ
index 14f9129..db57c73 100644 (file)
@@ -93,6 +93,18 @@ Y.extend(DRAGRESOURCE, M.core.dragdrop, {
      */
     setup_for_resource: function(baseselector) {
         Y.Node.all(baseselector).each(function(resourcesnode) {
+            var draggroups = resourcesnode.getData('draggroups');
+            if (!draggroups) {
+                // This Drop Node has not been set up. Configure it now.
+                resourcesnode.setAttribute('data-draggroups', this.groups.join(' '));
+                // Define empty ul as droptarget, so that item could be moved to empty list
+                new Y.DD.Drop({
+                    node: resourcesnode,
+                    groups: this.groups,
+                    padding: '20 0 20 0'
+                });
+            }
+
             // Replace move icons
             var move = resourcesnode.one('a.' + CSS.EDITINGMOVE);
             if (move) {
index 6dfe3cc..845e2e4 100644 (file)
@@ -60,7 +60,21 @@ class enrol_paypal_plugin extends enrol_plugin {
      * @return array of pix_icon
      */
     public function get_info_icons(array $instances) {
-        return array(new pix_icon('icon', get_string('pluginname', 'enrol_paypal'), 'enrol_paypal'));
+        $found = false;
+        foreach ($instances as $instance) {
+            if ($instance->enrolstartdate != 0 && $instance->enrolstartdate > time()) {
+                continue;
+            }
+            if ($instance->enrolenddate != 0 && $instance->enrolenddate < time()) {
+                continue;
+            }
+            $found = true;
+            break;
+        }
+        if ($found) {
+            return array(new pix_icon('icon', get_string('pluginname', 'enrol_paypal'), 'enrol_paypal'));
+        }
+        return array();
     }
 
     public function roles_protected() {
index 3565ef6..4a896ea 100644 (file)
@@ -563,8 +563,8 @@ class gradingform_guide_controller extends gradingform_controller {
             return $this->get_instance($instance);
         }
         if ($itemid && $raterid) {
-            if ($rs = $DB->get_records('grading_instances', array('raterid' => $raterid, 'itemid' => $itemid),
-                'timemodified DESC', '*', 0, 1)) {
+            $params = array('definitionid' => $this->definition->id, 'raterid' => $raterid, 'itemid' => $itemid);
+            if ($rs = $DB->get_records('grading_instances', $params, 'timemodified DESC', '*', 0, 1)) {
                 $record = reset($rs);
                 $currentinstance = $this->get_current_instance($raterid, $itemid);
                 if ($record->status == gradingform_guide_instance::INSTANCE_STATUS_INCOMPLETE &&
diff --git a/grade/grading/form/guide/tests/guide_test.php b/grade/grading/form/guide/tests/guide_test.php
new file mode 100644 (file)
index 0000000..5bf953e
--- /dev/null
@@ -0,0 +1,99 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Unit tests for Marking Guide grading method.
+ *
+ * @package    gradingform_guide
+ * @category   test
+ * @copyright  2015 Nikita Kalinin <nixorv@gmail.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+global $CFG;
+require_once($CFG->dirroot . '/grade/grading/lib.php');
+require_once($CFG->dirroot . '/grade/grading/form/guide/lib.php');
+
+/**
+ * Test cases for the Marking Guide.
+ *
+ * @package    gradingform_guide
+ * @category   test
+ * @copyright  2015 Nikita Kalinin <nixorv@gmail.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class gradingform_guide_testcase extends advanced_testcase {
+    /**
+     * Unit test to get draft instance and create new instance.
+     */
+    public function test_get_or_create_instance() {
+        global $DB;
+
+        $this->resetAfterTest(true);
+
+        // Create fake areas.
+        $fakearea = (object)array(
+            'contextid'    => 1,
+            'component'    => 'mod_assign',
+            'areaname'     => 'submissions',
+            'activemethod' => 'guide'
+        );
+        $fakearea1id = $DB->insert_record('grading_areas', $fakearea);
+        $fakearea->contextid = 2;
+        $fakearea2id = $DB->insert_record('grading_areas', $fakearea);
+
+        // Create fake definitions.
+        $fakedefinition = (object)array(
+            'areaid'       => $fakearea1id,
+            'method'       => 'guide',
+            'name'         => 'fakedef',
+            'status'       => gradingform_controller::DEFINITION_STATUS_READY,
+            'timecreated'  => 0,
+            'usercreated'  => 1,
+            'timemodified' => 0,
+            'usermodified' => 1,
+        );
+        $fakedef1id = $DB->insert_record('grading_definitions', $fakedefinition);
+        $fakedefinition->areaid = $fakearea2id;
+        $fakedef2id = $DB->insert_record('grading_definitions', $fakedefinition);
+
+        // Create fake guide instance in first area.
+        $fakeinstance = (object)array(
+            'definitionid'   => $fakedef1id,
+            'raterid'        => 1,
+            'itemid'         => 1,
+            'rawgrade'       => null,
+            'status'         => 0,
+            'feedback'       => null,
+            'feedbackformat' => 0,
+            'timemodified'   => 0
+        );
+        $fakeinstanceid = $DB->insert_record('grading_instances', $fakeinstance);
+
+        $manager1 = get_grading_manager($fakearea1id);
+        $manager2 = get_grading_manager($fakearea2id);
+        $controller1 = $manager1->get_controller('guide');
+        $controller2 = $manager2->get_controller('guide');
+
+        $instance1 = $controller1->get_or_create_instance(0, 1, 1);
+        $instance2 = $controller2->get_or_create_instance(0, 1, 1);
+
+        // Definitions should not be the same.
+        $this->assertEquals(false, $instance1->get_data('definitionid') == $instance2->get_data('definitionid'));
+    }
+}
index 614ccca..7695995 100644 (file)
     min-width: 4.5em;
     vertical-align: top;
 }
+.dir-rtl.path-grade-report-user .user-grade td {
+    direction: ltr;
+}
+.dir-rtl.path-grade-report-user table.user-grade {
+    border-collapse: separate;
+}
 .path-grade-report-user .user-grade .b1l {
     padding: 0;
     width:24px;
@@ -59,4 +65,4 @@
 .dir-rtl.path-grade-report-user .user-grade .column-itemname.baggt,
 .dir-rtl.path-grade-report-user .user-grade .column-itemname.baggb {
     padding-right: 24px;
-}
\ No newline at end of file
+}
diff --git a/grade/tests/behat/grade_to_pass.feature b/grade/tests/behat/grade_to_pass.feature
new file mode 100644 (file)
index 0000000..8ac6e30
--- /dev/null
@@ -0,0 +1,251 @@
+@core @core_grades
+Feature: We can set the grade to pass value
+  In order to set the grade to pass value
+  As a teacher
+  I assign a grade to pass to an activity while editing the activity.
+  I need to ensure that the grade to pass is visible in the gradebook.
+
+  Background:
+    Given the following "users" exist:
+      | username | firstname | lastname | email |
+      | teacher1 | Teacher | 1 | teacher1@asd.com |
+    And the following "courses" exist:
+      | fullname | shortname | format | numsections |
+      | Course 1 | C1 | weeks | 5 |
+    And the following "course enrolments" exist:
+      | user | course | role |
+      | teacher1 | C1 | editingteacher |
+    And the following "scales" exist:
+      | name | scale |
+      | Test Scale 1 | Disappointing, Good, Very good, Excellent |
+    And I log in as "teacher1"
+    And I follow "Course 1"
+
+  @javascript
+  Scenario: Validate that switching the type of grading used correctly disables grade to pass
+    When I turn editing mode on
+    And I add a "Assignment" to section "1"
+    And I expand all fieldsets
+    And I set the field "grade[modgrade_type]" to "Point"
+    Then the "Grade to pass" "field" should be enabled
+    And I set the field "grade[modgrade_type]" to "None"
+    And the "Grade to pass" "field" should be disabled
+    And I press "Save and return to course"
+
+  @javascript
+  Scenario: Create an activity with a Grade to pass value greater than the maximum grade
+    When I turn editing mode on
+    And I add a "Assignment" to section "1" and I fill the form with:
+      | Assignment name | Test Assignment 1 |
+      | Description | Submit your online text |
+      | assignsubmission_onlinetext_enabled | 1 |
+      | grade[modgrade_type] | Point |
+      | grade[modgrade_point] | 50 |
+      | Grade to pass | 100 |
+    Then I should see "The grade to pass can not be greater than the maximum possible grade 50"
+    And I press "Cancel"
+
+  @javascript
+  Scenario: Set a valid grade to pass for an assignment activity using points
+    When I turn editing mode on
+    And I add a "Assignment" to section "1" and I fill the form with:
+      | Assignment name | Test Assignment 1 |
+      | Description | Submit your online text |
+      | assignsubmission_onlinetext_enabled | 1 |
+      | grade[modgrade_type] | Point |
+      | grade[modgrade_point] | 50 |
+      | Grade to pass | 25 |
+    And I follow "Grades"
+    And I turn editing mode on
+    And I click on "Edit  assign Test Assignment 1" "link"
+    Then the field "Grade to pass" matches value "25"
+    And I follow "Course 1"
+    And I follow "Test Assignment 1"
+    And I follow "Edit settings"
+    And I expand all fieldsets
+    And I set the field "Grade to pass" to "30"
+    And I press "Save and return to course"
+    And I follow "Grades"
+    And I click on "Edit  assign Test Assignment 1" "link"
+    And the field "Grade to pass" matches value "30"
+
+  @javascript
+  Scenario: Set a valid grade to pass for an assignment activity using scales
+    When I turn editing mode on
+    And I add a "Assignment" to section "1" and I fill the form with:
+      | Assignment name | Test Assignment 1 |
+      | Description | Submit your online text |
+      | grade[modgrade_type] | Scale |
+      | grade[modgrade_scale] | Test Scale 1 |
+      | Grade to pass | 3 |
+    And I follow "Grades"
+    And I turn editing mode on
+    And I click on "Edit  assign Test Assignment 1" "link"
+    And I follow "Show more..."
+    Then the field "Grade to pass" matches value "3"
+    And I set the field "Grade to pass" to "4"
+    And I press "Save changes"
+    And I follow "Course 1"
+    And I follow "Test Assignment 1"
+    And I follow "Edit settings"
+    And the field "Grade to pass" matches value "4"
+
+  @javascript
+  Scenario: Set a invalid grade to pass for an assignment activity using scales
+    When I turn editing mode on
+    And I add a "Assignment" to section "1" and I fill the form with:
+      | Assignment name | Test Assignment 1 |
+      | Description | Submit your online text |
+      | grade[modgrade_type] | Scale |
+      | grade[modgrade_scale] | Test Scale 1 |
+      | Grade to pass | 10 |
+    Then I should see "The grade to pass can not be greater than the maximum possible grade 4"
+
+  @javascript
+  Scenario: Set a valid grade to pass for workshop activity
+    When I turn editing mode on
+    And I add a "Workshop" to section "1" and I fill the form with:
+      | Workshop name | Test Workshop 1 |
+      | Description | Test workshop |
+      | grade | 80 |
+      | Submission grade to pass | 40 |
+      | gradinggrade | 20 |
+      | Assessment grade to pass | 10 |
+    And I follow "Grades"
+    And I turn editing mode on
+    And I click on "Edit  workshop Test Workshop 1 (submission)" "link"
+    And I follow "Show more..."
+    Then the field "Grade to pass" matches value "40"
+    And I set the field "Grade to pass" to "45"
+    And I press "Save changes"
+    And I click on "Edit  workshop Test Workshop 1 (assessment)" "link"
+    And I follow "Show more..."
+    And the field "Grade to pass" matches value "10"
+    And I set the field "Grade to pass" to "15"
+    And I press "Save changes"
+    And I follow "Course 1"
+    And I follow "Test Workshop 1"
+    And I follow "Edit settings"
+    And the field "Submission grade to pass" matches value "45"
+    And the field "Assessment grade to pass" matches value "15"
+
+  @javascript
+  Scenario: Set an invalid grade to pass for workshop activity
+    When I turn editing mode on
+    And I add a "Workshop" to section "1" and I fill the form with:
+      | Workshop name | Test Workshop 1 |
+      | Description | Test workshop |
+      | grade | 80 |
+      | Submission grade to pass | 90 |
+      | gradinggrade | 20 |
+      | Assessment grade to pass | 30 |
+    Then "The grade to pass can not be greater than the maximum possible grade 80" "text" should exist in the "#fitem_id_submissiongradepass .error" "css_element"
+    Then "The grade to pass can not be greater than the maximum possible grade 20" "text" should exist in the "#fitem_id_gradinggradepass .error" "css_element"
+
+  @javascript
+  Scenario: Set a valid grade to pass for quiz activity
+    When I turn editing mode on
+    And I add a "Quiz" to section "1" and I fill the form with:
+      | Name | Test Quiz 1 |
+      | Grade to pass | 9.5 |
+    And I follow "Grades"
+    And I turn editing mode on
+    And I click on "Edit  quiz Test Quiz 1" "link"
+    And I follow "Show more..."
+    Then the field "Grade to pass" matches value "9.5"
+    And I set the field "Grade to pass" to "8"
+    And I press "Save changes"
+    And I follow "Course 1"
+    And I follow "Test Quiz 1"
+    And I follow "Edit settings"
+    And the field "Grade to pass" matches value "8.00"
+
+  @javascript
+  Scenario: Set a valid grade to pass for lesson activity
+    When I turn editing mode on
+    And I add a "Lesson" to section "1" and I fill the form with:
+      | Name          | Test Lesson 1 |
+      | Description   | Test          |
+      | Grade to pass | 90            |
+    And I follow "Grades"
+    And I turn editing mode on
+    And I click on "Edit  lesson Test Lesson 1" "link"
+    And I follow "Show more..."
+    Then the field "Grade to pass" matches value "90"
+    And I set the field "Grade to pass" to "80"
+    And I press "Save changes"
+    And I follow "Course 1"
+    And I follow "Test Lesson 1"
+    And I follow "Edit settings"
+    And the field "Grade to pass" matches value "80"
+
+  @javascript
+  Scenario: Set a valid grade to pass for database activity
+    When I turn editing mode on
+    And I add a "Database" to section "1" and I fill the form with:
+      | Name           | Test Database 1    |
+      | Description    | Test               |
+      | Grade to pass  | 90                 |
+      | Aggregate type | Average of ratings |
+    And I follow "Grades"
+    And I turn editing mode on
+    And I click on "Edit  data Test Database 1" "link"
+    And I follow "Show more..."
+    Then the field "Grade to pass" matches value "90"
+    And I set the field "Grade to pass" to "80"
+    And I press "Save changes"
+    And I follow "Course 1"
+    And I follow "Test Database 1"
+    And I follow "Edit settings"
+    And the field "Grade to pass" matches value "80"
+
+  @javascript
+  Scenario: Set an invalid grade to pass for forum activity
+    When I turn editing mode on
+    And I add a "Forum" to section "1" and I fill the form with:
+      | Forum name     | Test Forum 1    |
+      | Description    | Test               |
+      | Grade to pass  | 90                 |
+      | Aggregate type | Average of ratings |
+      | scale[modgrade_point] | 60 |
+    Then I should see "The grade to pass can not be greater than the maximum possible grade 60"
+
+  @javascript
+  Scenario: Set a valid grade to pass for forum activity
+    When I turn editing mode on
+    And I add a "Forum" to section "1" and I fill the form with:
+      | Forum name     | Test Forum 1    |
+      | Description    | Test               |
+      | Grade to pass  | 90                 |
+      | Aggregate type | Average of ratings |
+    And I follow "Grades"
+    And I turn editing mode on
+    And I click on "Edit  forum Test Forum 1" "link"
+    And I follow "Show more..."
+    Then the field "Grade to pass" matches value "90"
+    And I set the field "Grade to pass" to "80"
+    And I press "Save changes"
+    And I follow "Course 1"
+    And I follow "Test Forum 1"
+    And I follow "Edit settings"
+    And the field "Grade to pass" matches value "80"
+
+  @javascript
+  Scenario: Set a valid grade to pass for glossary activity
+    When I turn editing mode on
+    And I add a "Glossary" to section "1" and I fill the form with:
+      | Name           | Test Glossary 1    |
+      | Description    | Test               |
+      | Grade to pass  | 90                 |
+      | Aggregate type | Average of ratings |
+    And I follow "Grades"
+    And I turn editing mode on
+    And I click on "Edit  glossary Test Glossary 1" "link"
+    And I follow "Show more..."
+    Then the field "Grade to pass" matches value "90"
+    And I set the field "Grade to pass" to "80"
+    And I press "Save changes"
+    And I follow "Course 1"
+    And I follow "Test Glossary 1"
+    And I follow "Edit settings"
+    And the field "Grade to pass" matches value "80"
diff --git a/install/lang/oc_lnc/install.php b/install/lang/oc_lnc/install.php
new file mode 100644 (file)
index 0000000..5c232b0
--- /dev/null
@@ -0,0 +1,37 @@
+<?php
+
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Automatically generated strings for Moodle installer
+ *
+ * Do not edit this file manually! It contains just a subset of strings
+ * needed during the very first steps of installation. This file was
+ * generated automatically by export-installer.php (which is part of AMOS
+ * {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
+ * list of strings defined in /install/stringnames.txt.
+ *
+ * @package   installer
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+$string['availablelangs'] = 'Paquetatges de lenga disponibles';
+$string['chooselanguagehead'] = 'Causissètz una lenga';
+$string['databasehost'] = 'Servidor de banca de donadas';
+$string['databasename'] = 'Nom de la banca de donadas';
+$string['databasetypehead'] = 'Seleccionar un pilòt de banca de donadas';
index ce03b75..7169f37 100644 (file)
@@ -218,6 +218,7 @@ $string['error:backpackproblem'] = 'There was a problem connecting to your backp
 $string['error:badjson'] = 'The connection attempt returned invalid data.';
 $string['error:cannotact'] = 'Cannot activate the badge. ';
 $string['error:cannotawardbadge'] = 'Cannot award badge to a user.';
+$string['error:cannotdeletecriterion'] = 'This criterion cannot be deleted. ';
 $string['error:connectionunknownreason'] = 'The connection was unsuccessful but no reason was given.';
 $string['error:clone'] = 'Cannot clone the badge.';
 $string['error:duplicatename'] = 'Badge with such name already exists in the system.';
index e80d92e..a15d522 100644 (file)
@@ -296,6 +296,7 @@ $string['gradeoutcomes'] = 'Outcomes';
 $string['gradeoutcomescourses'] = 'Course outcomes';
 $string['gradepass'] = 'Grade to pass';
 $string['gradepass_help'] = 'This setting determines the minimum grade required to pass. The value is used in activity and course completion, and in the gradebook, where pass grades are highlighted in green and fail grades in red.';
+$string['gradepassgreaterthangrade'] = 'The grade to pass can not be greater than the maximum possible grade {$a}';
 $string['gradepointdefault'] = 'Grade point default';
 $string['gradepointdefault_help'] = 'This setting determines the default value for the grade point value available in an activity.';
 $string['gradepointdefault_validateerror'] = 'This setting must be an integer between 1 and the grade point maximum.';
index 4b1272c..0590bd1 100644 (file)
@@ -1118,7 +1118,9 @@ $string['maxsizeandattachmentsandareasize'] = 'Maximum size for new files: {$a->
 $string['memberincourse'] = 'People in the course';
 $string['messagebody'] = 'Message body';
 $string['messagedselectedusers'] = 'Selected users have been messaged and the recipient list has been reset.';
+$string['messagedselecteduserfailed'] = 'The message was not sent to user {$a->fullname}.';
 $string['messagedselectedusersfailed'] = 'Something went wrong while messaging selected users.  Some may have received the email.';
+$string['messagedselectedcountusersfailed'] = 'A problem occurred and {$a} messages have not been sent.';
 $string['messageprovider:availableupdate'] = 'Available update notifications';
 $string['messageprovider:backup'] = 'Backup notifications';
 $string['messageprovider:badgecreatornotice'] = 'Badge creator notifications';
@@ -1330,7 +1332,7 @@ $string['notenrolled'] = '{$a} is not enrolled in this course.';
 $string['notenrolledprofile'] = 'This profile is not available because this user is not enrolled in this course.';
 $string['noteusercannotrolldatesoncontext'] = '<strong>Note:</strong> The ability to roll dates when restoring this backup has been disabled because you lack the required permissions.';
 $string['noteuserschangednonetocourse'] = '<strong>Note:</strong> Course users need to be restored when restoring user data (in activities, files or messages). This setting has been changed for you.';
-$string['nothingnew'] = 'Nothing new since your last login';
+$string['nothingnew'] = 'No recent activity';
 $string['nothingtodisplay'] = 'Nothing to display';
 $string['notice'] = 'Notice';
 $string['noticenewerbackup'] = 'This backup file has been created with Moodle {$a->backuprelease} ({$a->backupversion}) and it\'s newer than your currently installed Moodle {$a->serverrelease} ({$a->serverversion}). This could cause some inconsistencies because backwards compatibility of backup files cannot be guaranteed.';
index dde8b7e..8fd87a2 100644 (file)
@@ -967,8 +967,8 @@ class core_plugin_manager {
             ),
 
             'block' => array(
-                'activity_modules', 'admin_bookmarks', 'badges', 'blog_menu',
-                'blog_recent', 'blog_tags', 'calendar_month',
+                'activity_modules', 'activity_results', 'admin_bookmarks', 'badges',
+                'blog_menu', 'blog_recent', 'blog_tags', 'calendar_month',
                 'calendar_upcoming', 'comments', 'community',
                 'completionstatus', 'course_list', 'course_overview',
                 'course_summary', 'feedback', 'glossary_random', 'html',
index 487b137..861b24d 100644 (file)
@@ -67,4 +67,34 @@ class repository extends base {
     public static function get_manage_url() {
         return new moodle_url('/admin/repository.php');
     }
+
+    /**
+     * Defines if there should be a way to uninstall the plugin via the administration UI.
+     * @return boolean
+     */
+    public function is_uninstall_allowed() {
+        if ($this->name === 'upload' || $this->name === 'coursefiles' || $this->name === 'user' || $this->name === 'recent') {
+            return false;
+        } else {
+            return true;
+        }
+    }
+
+    /**
+     * Pre-uninstall hook.
+     * This is intended for disabling of plugin, some DB table purging, etc.
+     * Converts all linked files to standard files when repository is removed
+     * and cleans up all records in the DB for that repository.
+     */
+    public function uninstall_cleanup() {
+        global $CFG;
+        require_once($CFG->dirroot.'/repository/lib.php');
+
+        $repo = \repository::get_type_by_typename($this->name);
+        if ($repo) {
+            $repo->delete(true);
+        }
+
+        parent::uninstall_cleanup();
+    }
 }