MDL-59252 mod_workshop: New WS mod_workshop_evaluate_assessment
authorJuan Leyva <juanleyvadelgado@gmail.com>
Thu, 29 Jun 2017 13:34:57 +0000 (14:34 +0100)
committerEloy Lafuente (stronk7) <stronk7@moodle.org>
Tue, 3 Oct 2017 17:16:43 +0000 (19:16 +0200)
mod/workshop/classes/external.php
mod/workshop/db/services.php
mod/workshop/locallib.php
mod/workshop/tests/external_test.php
mod/workshop/version.php

index 8ddb084..0d5404d 100644 (file)
@@ -1035,8 +1035,8 @@ class mod_workshop_external extends external_api {
             return null;
         }
 
-        // Remove the feedback for the reviewer if the feedback is not closed or if we don't have enough permissions to see it.
-        if (!$canoverridegrades && ($workshop->phase != workshop::PHASE_CLOSED || !$isreviewer)) {
+        // Remove the feedback for the reviewer if the feedback phase is not valid or if we don't have enough permissions to see it.
+        if ($workshop->phase < workshop::PHASE_EVALUATION || !($isreviewer || $canviewallassessments)) {
             // Remove all the feedback information (all the optional fields).
             foreach ($properties as $attribute => $settings) {
                 if (!empty($settings['optional'])) {
@@ -1632,4 +1632,119 @@ class mod_workshop_external extends external_api {
             )
         );
     }
+
+    /**
+     * Returns the description of the external function parameters.
+     *
+     * @return external_function_parameters
+     * @since Moodle 3.4
+     */
+    public static function evaluate_assessment_parameters() {
+        return new external_function_parameters(
+            array(
+                'assessmentid' => new external_value(PARAM_INT, 'Assessment id.'),
+                'feedbacktext' => new external_value(PARAM_RAW, 'The feedback for the reviewer.', VALUE_DEFAULT, ''),
+                'feedbackformat' => new external_value(PARAM_INT, 'The feedback format for text.', VALUE_DEFAULT, FORMAT_MOODLE),
+                'weight' => new external_value(PARAM_INT, 'The new weight for the assessment.', VALUE_DEFAULT, 1),
+                'gradinggradeover' => new external_value(PARAM_ALPHANUMEXT, 'The new grading grade.', VALUE_DEFAULT, ''),
+            )
+        );
+    }
+
+
+    /**
+     * Evaluates an assessment (used by teachers for provide feedback to the reviewer).
+     *
+     * @param int $assessmentid the assessment id
+     * @param str $feedbacktext the feedback for the reviewer
+     * @param int $feedbackformat the feedback format for the reviewer text
+     * @param int $weight the new weight for the assessment
+     * @param mixed $gradinggradeover the new grading grade (empty for no overriding the grade)
+     * @return array containing the status and warnings.
+     * @since Moodle 3.4
+     * @throws moodle_exception
+     */
+    public static function evaluate_assessment($assessmentid, $feedbacktext = '', $feedbackformat = FORMAT_MOODLE, $weight = 1,
+            $gradinggradeover = '') {
+        global $DB;
+
+        $params = self::validate_parameters(
+            self::evaluate_assessment_parameters(),
+            array(
+                'assessmentid' => $assessmentid,
+                'feedbacktext' => $feedbacktext,
+                'feedbackformat' => $feedbackformat,
+                'weight' => $weight,
+                'gradinggradeover' => $gradinggradeover,
+            )
+        );
+        $warnings = array();
+
+        // Get and validate the assessment, submission and workshop.
+        $assessment = $DB->get_record('workshop_assessments', array('id' => $params['assessmentid']), '*', MUST_EXIST);
+        $submission = $DB->get_record('workshop_submissions', array('id' => $assessment->submissionid), '*', MUST_EXIST);
+        list($workshop, $course, $cm, $context) = self::validate_workshop($submission->workshopid);
+
+        // Check we can evaluate the assessment.
+        $workshop->check_view_assessment($assessment, $submission);
+        $cansetassessmentweight = has_capability('mod/workshop:allocate', $context);
+        $canoverridegrades      = has_capability('mod/workshop:overridegrades', $context);
+        if (!$canoverridegrades && !$cansetassessmentweight) {
+            throw new moodle_exception('nopermissions', 'error', '', 'evaluate assessments');
+        }
+
+        // Process data.
+        $data = new stdClass;
+        $data->asid = $assessment->id;
+        $data->feedbackreviewer_editor = array(
+            'text' => $params['feedbacktext'],
+            'format' => $params['feedbackformat'],
+        );
+        $data->weight = $params['weight'];
+        $data->gradinggradeover = $params['gradinggradeover'];
+
+        $options = array(
+            'editable' => true,
+            'editableweight' => $cansetassessmentweight,
+            'overridablegradinggrade' => $canoverridegrades
+        );
+        $feedbackform = $workshop->get_feedbackreviewer_form(null, $assessment, $options);
+
+        $errors = $feedbackform->validation((array) $data, array());
+        // We can get several errors, return them in warnings.
+        if (!empty($errors)) {
+            $status = false;
+            foreach ($errors as $itemname => $message) {
+                $warnings[] = array(
+                    'item' => $itemname,
+                    'itemid' => 0,
+                    'warningcode' => 'fielderror',
+                    'message' => s($message)
+                );
+            }
+        } else {
+            $workshop->evaluate_assessment($assessment, $data, $cansetassessmentweight, $canoverridegrades);
+            $status = true;
+        }
+
+        return array(
+            'status' => $status,
+            'warnings' => $warnings,
+        );
+    }
+
+    /**
+     * Returns description of method result value
+     *
+     * @return external_description
+     * @since Moodle 3.4
+     */
+    public static function evaluate_assessment_returns() {
+        return new external_single_structure(
+            array(
+                'status' => new external_value(PARAM_BOOL, 'status: true if the assessment was evaluated, false otherwise.'),
+                'warnings' => new external_warnings()
+            )
+        );
+    }
 }
index 06aabc6..0e76683 100644 (file)
@@ -141,4 +141,11 @@ $functions = array(
         'type'          => 'read',
         'services'      => array(MOODLE_OFFICIAL_MOBILE_SERVICE)
     ),
+    'mod_workshop_evaluate_assessment' => array(
+        'classname'     => 'mod_workshop_external',
+        'methodname'    => 'evaluate_assessment',
+        'description'   => 'Evaluates an assessment (used by teachers for provide feedback to the reviewer).',
+        'type'          => 'write',
+        'services'      => array(MOODLE_OFFICIAL_MOBILE_SERVICE)
+    ),
 );
index 6d85286..966e268 100644 (file)
@@ -2455,12 +2455,12 @@ class workshop {
     /**
      * Returns the mform the teachers use to put a feedback for the reviewer
      *
-     * @param moodle_url $actionurl
+     * @param mixed moodle_url|null $actionurl
      * @param stdClass $assessment
      * @param array $options editable, editableweight, overridablegradinggrade
      * @return workshop_feedbackreviewer_form
      */
-    public function get_feedbackreviewer_form(moodle_url $actionurl, stdclass $assessment, $options=array()) {
+    public function get_feedbackreviewer_form($actionurl, stdclass $assessment, $options=array()) {
         global $CFG;
         require_once(__DIR__ . '/feedbackreviewer_form.php');
 
index 870c737..dbe229c 100644 (file)
@@ -1590,4 +1590,82 @@ class mod_workshop_external_testcase extends externallib_advanced_testcase {
         $this->expectException('moodle_exception');
         mod_workshop_external::get_grades($this->workshop->id, $this->student->id);
     }
+
+    /**
+     * Test evaluate_assessment.
+     */
+    public function test_evaluate_assessment() {
+        global $DB;
+
+        $workshopgenerator = $this->getDataGenerator()->get_plugin_generator('mod_workshop');
+        $submissionid = $workshopgenerator->create_submission($this->workshop->id, $this->student->id);
+        $assessmentid = $workshopgenerator->create_assessment($submissionid, $this->anotherstudentg1->id, array(
+            'weight' => 3,
+            'grade' => 95,
+        ));
+
+        $this->setUser($this->teacher);
+        $feedbacktext = 'The feedback';
+        $feedbackformat = FORMAT_MOODLE;
+        $weight = 25;
+        $gradinggradeover = 10;
+        $result = mod_workshop_external::evaluate_assessment($assessmentid, $feedbacktext, $feedbackformat, $weight,
+            $gradinggradeover);
+        $result = external_api::clean_returnvalue(mod_workshop_external::evaluate_assessment_returns(), $result);
+        $this->assertTrue($result['status']);
+
+        $assessment = $DB->get_record('workshop_assessments', array('id' => $assessmentid));
+        $this->assertEquals('The feedback', $assessment->feedbackreviewer);
+        $this->assertEquals(25, $assessment->weight);
+    }
+
+    /**
+     * Test evaluate_assessment_ignore_parameters.
+     */
+    public function test_evaluate_assessment_ignore_parameters() {
+        $workshopgenerator = $this->getDataGenerator()->get_plugin_generator('mod_workshop');
+        $submissionid = $workshopgenerator->create_submission($this->workshop->id, $this->student->id);
+        $assessmentid = $workshopgenerator->create_assessment($submissionid, $this->anotherstudentg1->id, array(
+            'weight' => 3,
+            'grade' => 95,
+        ));
+
+        assign_capability('mod/workshop:allocate', CAP_PROHIBIT, $this->teacherrole->id, $this->context->id);
+        // Empty all the caches that may be affected  by this change.
+        accesslib_clear_all_caches_for_unit_testing();
+
+        $this->setUser($this->teacher);
+        $feedbacktext = 'The feedback';
+        $feedbackformat = FORMAT_MOODLE;
+        $weight = 25;
+        $gradinggradeover = 1000;
+        $result = mod_workshop_external::evaluate_assessment($assessmentid, $feedbacktext, $feedbackformat, $weight,
+            $gradinggradeover);
+        $result = external_api::clean_returnvalue(mod_workshop_external::evaluate_assessment_returns(), $result);
+        $this->assertTrue($result['status']);
+
+        $result = mod_workshop_external::get_assessment($assessmentid);
+        $result = external_api::clean_returnvalue(mod_workshop_external::get_assessment_returns(), $result);
+        $this->assertNotEquals(25, $result['assessment']['weight']);
+    }
+
+    /**
+     * Test evaluate_assessment_no_permissions.
+     */
+    public function test_evaluate_assessment_no_permissions() {
+        $workshopgenerator = $this->getDataGenerator()->get_plugin_generator('mod_workshop');
+        $submissionid = $workshopgenerator->create_submission($this->workshop->id, $this->student->id);
+        $assessmentid = $workshopgenerator->create_assessment($submissionid, $this->anotherstudentg1->id, array(
+            'weight' => 3,
+            'grade' => 95,
+        ));
+
+        $this->setUser($this->student);
+        $feedbacktext = 'The feedback';
+        $feedbackformat = FORMAT_MOODLE;
+        $weight = 25;
+        $gradinggradeover = 50;
+        $this->expectException('moodle_exception');
+        mod_workshop_external::evaluate_assessment($assessmentid, $feedbacktext, $feedbackformat, $weight, $gradinggradeover);
+    }
 }
index 94d9d6c..001cf8a 100644 (file)
@@ -24,7 +24,7 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2017051515;        // The current module version (YYYYMMDDXX)
+$plugin->version   = 2017051516;        // The current module version (YYYYMMDDXX)
 $plugin->requires  = 2017050500;        // Requires this Moodle version.
 $plugin->component = 'mod_workshop';
 $plugin->cron      = 60;                // Give as a chance every minute.