MDL-60144 mod_workshop: New WS mod_workshop_evaluate_submission
authorJuan Leyva <juanleyvadelgado@gmail.com>
Fri, 15 Sep 2017 14:01:50 +0000 (16:01 +0200)
committerEloy Lafuente (stronk7) <stronk7@moodle.org>
Tue, 3 Oct 2017 17:28:56 +0000 (19:28 +0200)
mod/workshop/classes/external.php
mod/workshop/db/services.php
mod/workshop/tests/external_test.php
mod/workshop/version.php

index 70063c4..e79bef4 100644 (file)
@@ -1976,4 +1976,120 @@ 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_submission_parameters() {
+        return new external_function_parameters(
+            array(
+                'submissionid' => new external_value(PARAM_INT, 'submission id.'),
+                'feedbacktext' => new external_value(PARAM_RAW, 'The feedback for the author.', VALUE_DEFAULT, ''),
+                'feedbackformat' => new external_value(PARAM_INT, 'The feedback format for text.', VALUE_DEFAULT, FORMAT_MOODLE),
+                'published' => new external_value(PARAM_BOOL, 'Publish the submission for others?.', VALUE_DEFAULT, false),
+                'gradeover' => new external_value(PARAM_ALPHANUMEXT, 'The new submission grade.', VALUE_DEFAULT, ''),
+            )
+        );
+    }
+
+
+    /**
+     * Evaluates a submission (used by teachers for provide feedback or override the submission grade).
+     *
+     * @param int $submissionid the submission id
+     * @param str $feedbacktext the feedback for the author
+     * @param int $feedbackformat the feedback format for the reviewer text
+     * @param bool $published whether to publish the submission for other users
+     * @param mixed $gradeover the new submission 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_submission($submissionid, $feedbacktext = '', $feedbackformat = FORMAT_MOODLE, $published = 1,
+            $gradeover = '') {
+        global $DB;
+
+        $params = self::validate_parameters(
+            self::evaluate_submission_parameters(),
+            array(
+                'submissionid' => $submissionid,
+                'feedbacktext' => $feedbacktext,
+                'feedbackformat' => $feedbackformat,
+                'published' => $published,
+                'gradeover' => $gradeover,
+            )
+        );
+        $warnings = array();
+
+        // Get and validate the submission, submission and workshop.
+        $submission = $DB->get_record('workshop_submissions', array('id' => $params['submissionid']), '*', MUST_EXIST);
+        list($workshop, $course, $cm, $context) = self::validate_workshop($submission->workshopid);
+
+        // Check we can evaluate the submission.
+        self::validate_submission($submission, $workshop);
+        $canpublish  = has_capability('mod/workshop:publishsubmissions', $context);
+        $canoverride = ($workshop->phase == workshop::PHASE_EVALUATION &&
+            has_capability('mod/workshop:overridegrades', $context));
+
+        if (!$canpublish && !$canoverride) {
+            throw new moodle_exception('nopermissions', 'error', '', 'evaluate submission');
+        }
+
+        // Process data.
+        $data = new stdClass;
+        $data->id = $submission->id;
+        $data->feedbackauthor_editor = array(
+            'text' => $params['feedbacktext'],
+            'format' => $params['feedbackformat'],
+        );
+        $data->published = $params['published'];
+        $data->gradeover = $params['gradeover'];
+
+        $options = array(
+            'editable' => true,
+            'editablepublished' => $canpublish,
+            'overridablegrade' => $canoverride
+        );
+        $feedbackform = $workshop->get_feedbackauthor_form(null, $submission, $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_submission($submission, $data, $canpublish, $canoverride);
+            $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_submission_returns() {
+        return new external_single_structure(
+            array(
+                'status' => new external_value(PARAM_BOOL, 'status: true if the submission was evaluated, false otherwise.'),
+                'warnings' => new external_warnings()
+            )
+        );
+    }
 }
index d25ce62..bbe4a90 100644 (file)
@@ -163,4 +163,11 @@ $functions = array(
         'capabilities'  => 'mod/workshop:view',
         'services'      => array(MOODLE_OFFICIAL_MOBILE_SERVICE)
     ),
+    'mod_workshop_evaluate_submission' => array(
+        'classname'     => 'mod_workshop_external',
+        'methodname'    => 'evaluate_submission',
+        'description'   => 'Evaluates a submission (used by teachers for provide feedback or override the submission grade).',
+        'type'          => 'write',
+        'services'      => array(MOODLE_OFFICIAL_MOBILE_SERVICE)
+    ),
 );
index 2ccc99e..fa43ebc 100644 (file)
@@ -1768,4 +1768,76 @@ class mod_workshop_external_testcase extends externallib_advanced_testcase {
         $this->assertNotEmpty($event->get_name());
 
     }
+
+    /**
+     * Test evaluate_submission.
+     */
+    public function test_evaluate_submission() {
+        global $DB;
+
+        $workshopgenerator = $this->getDataGenerator()->get_plugin_generator('mod_workshop');
+        $submissionid = $workshopgenerator->create_submission($this->workshop->id, $this->student->id);
+
+        $DB->set_field('workshop', 'phase', workshop::PHASE_EVALUATION, array('id' => $this->workshop->id));
+
+        $this->setUser($this->teacher);
+        $feedbacktext = 'The feedback';
+        $feedbackformat = FORMAT_MOODLE;
+        $published = 1;
+        $gradeover = 10;
+        $result = mod_workshop_external::evaluate_submission($submissionid, $feedbacktext, $feedbackformat, $published,
+            $gradeover);
+        $result = external_api::clean_returnvalue(mod_workshop_external::evaluate_submission_returns(), $result);
+        $this->assertTrue($result['status']);
+
+        $workshop = new workshop($this->workshop, $this->cm, $this->course);
+        $submission = $DB->get_record('workshop_submissions', array('id' => $submissionid));
+        $this->assertEquals($feedbacktext, $submission->feedbackauthor);
+        $this->assertEquals($workshop->raw_grade_value($gradeover, $workshop->grade), $submission->gradeover);  // Expected grade.
+        $this->assertEquals(1, $submission->published); // Submission published.
+    }
+
+    /**
+     * Test evaluate_submission_invalid_phase_for_override.
+     */
+    public function test_evaluate_submission_invalid_phase_for_override() {
+        global $DB;
+
+        $workshopgenerator = $this->getDataGenerator()->get_plugin_generator('mod_workshop');
+        $submissionid = $workshopgenerator->create_submission($this->workshop->id, $this->student->id);
+
+        $this->setUser($this->teacher);
+        $feedbacktext = 'The feedback';
+        $feedbackformat = FORMAT_MOODLE;
+        $published = 1;
+        $gradeover = 10;
+        $result = mod_workshop_external::evaluate_submission($submissionid, $feedbacktext, $feedbackformat, $published,
+            $gradeover);
+        $result = external_api::clean_returnvalue(mod_workshop_external::evaluate_submission_returns(), $result);
+        $this->assertTrue($result['status']);
+
+        $submission = $DB->get_record('workshop_submissions', array('id' => $submissionid));
+        $this->assertEquals('', $submission->feedbackauthor);   // Feedback and grade not updated.
+        $this->assertEquals(0, $submission->gradeover);
+        $this->assertEquals(1, $submission->published); // Publishing status correctly updated.
+    }
+
+    /**
+     * Test evaluate_submission_no_permissions.
+     */
+    public function test_evaluate_submission_no_permissions() {
+        global $DB;
+
+        $workshopgenerator = $this->getDataGenerator()->get_plugin_generator('mod_workshop');
+        $submissionid = $workshopgenerator->create_submission($this->workshop->id, $this->student->id);
+        $DB->set_field('workshop', 'phase', workshop::PHASE_EVALUATION, array('id' => $this->workshop->id));
+
+        $this->setUser($this->student);
+        $feedbacktext = 'The feedback';
+        $feedbackformat = FORMAT_MOODLE;
+        $published = 1;
+        $gradeover = 50;
+        $this->expectException('moodle_exception');
+        mod_workshop_external::evaluate_submission($submissionid, $feedbacktext, $feedbackformat, $published, $gradeover);
+    }
 }
index d3cb91c..617de0a 100644 (file)
@@ -24,7 +24,7 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2017051518;        // The current module version (YYYYMMDDXX)
+$plugin->version   = 2017051519;        // 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.