From 38fefb5cdf96bd32ccfa0951c01d88635ec02815 Mon Sep 17 00:00:00 2001 From: Marina Glancy Date: Wed, 25 Oct 2017 13:41:32 +0800 Subject: [PATCH] MDL-60578 mod_feedback: pass courseid to WS --- mod/feedback/classes/external.php | 37 ++++++++----- mod/feedback/tests/external_test.php | 79 ++++++++++++++++++++++++++++ 2 files changed, 104 insertions(+), 12 deletions(-) diff --git a/mod/feedback/classes/external.php b/mod/feedback/classes/external.php index 2d89f597a78..e9bc096a35a 100644 --- a/mod/feedback/classes/external.php +++ b/mod/feedback/classes/external.php @@ -150,7 +150,7 @@ class mod_feedback_external extends external_api { * @return array array containing the feedback persistent, course, context and course module objects * @since Moodle 3.3 */ - protected static function validate_feedback($feedbackid) { + protected static function validate_feedback($feedbackid, $courseid = 0) { global $DB, $USER; // Request and permission validation. @@ -160,6 +160,11 @@ class mod_feedback_external extends external_api { $context = context_module::instance($cm->id); self::validate_context($context); + if ($course->id == SITEID && $courseid) { + $course = get_course($courseid); + self::validate_context(context_course::instance($courseid)); + } + return array($feedback, $course, $cm, $context); } @@ -167,15 +172,19 @@ class mod_feedback_external extends external_api { * Utility function for validating access to feedback. * * @param stdClass $feedback feedback object - * @param stdClass $course course object + * @param int $courseid course where user completes the feedback (for frontpage feedbacks only) * @param stdClass $cm course module * @param stdClass $context context object * @throws moodle_exception - * @return feedback_completion feedback completion instance + * @return mod_feedback_completion feedback completion instance * @since Moodle 3.3 */ - protected static function validate_feedback_access($feedback, $course, $cm, $context, $checksubmit = false) { - $feedbackcompletion = new mod_feedback_completion($feedback, $cm, $course->id); + protected static function validate_feedback_access($feedback, $courseid, $cm, $context, $checksubmit = false) { + $feedbackcompletion = new mod_feedback_completion($feedback, $cm, $courseid); + + if (!$feedbackcompletion->check_course_is_mapped()) { + throw new moodle_exception('cannotaccess', 'mod_feedback'); + } if (!$feedbackcompletion->can_complete()) { throw new required_capability_exception($context, 'mod/feedback:complete', 'nopermission', ''); @@ -478,19 +487,20 @@ class mod_feedback_external extends external_api { * Starts or continues a feedback submission * * @param array $feedbackid feedback instance id + * @param int $courseid course where user completes a feedback (for site feedbacks only). * @return array of warnings and launch information * @since Moodle 3.3 */ - public static function launch_feedback($feedbackid) { + public static function launch_feedback($feedbackid, $courseid = 0) { global $PAGE; $params = array('feedbackid' => $feedbackid); $params = self::validate_parameters(self::launch_feedback_parameters(), $params); $warnings = array(); - list($feedback, $course, $cm, $context) = self::validate_feedback($params['feedbackid']); + list($feedback, $course, $cm, $context) = self::validate_feedback($params['feedbackid'], $courseid); // Check we can do a new submission (or continue an existing). - $feedbackcompletion = self::validate_feedback_access($feedback, $course, $cm, $context, true); + $feedbackcompletion = self::validate_feedback_access($feedback, $courseid, $cm, $context, true); $gopage = $feedbackcompletion->get_resume_page(); if ($gopage === null) { @@ -615,6 +625,8 @@ class mod_feedback_external extends external_api { ), 'The data to be processed.', VALUE_DEFAULT, array() ), 'goprevious' => new external_value(PARAM_BOOL, 'Whether we want to jump to previous page.', VALUE_DEFAULT, false), + 'courseid' => new external_value(PARAM_INT, 'Id of the course where feedback is being completed (for frontpage feedbacks only)', + VALUE_DEFAULT, 0), ) ); } @@ -629,17 +641,18 @@ class mod_feedback_external extends external_api { * @return array of warnings and launch information * @since Moodle 3.3 */ - public static function process_page($feedbackid, $page, $responses = [], $goprevious = false) { + public static function process_page($feedbackid, $page, $responses = [], $goprevious = false, $courseid = 0) { global $USER, $SESSION; - $params = array('feedbackid' => $feedbackid, 'page' => $page, 'responses' => $responses, 'goprevious' => $goprevious); + $params = array('feedbackid' => $feedbackid, 'page' => $page, 'responses' => $responses, 'goprevious' => $goprevious, + 'courseid' => $courseid); $params = self::validate_parameters(self::process_page_parameters(), $params); $warnings = array(); $siteaftersubmit = $completionpagecontents = ''; list($feedback, $course, $cm, $context) = self::validate_feedback($params['feedbackid']); // Check we can do a new submission (or continue an existing). - $feedbackcompletion = self::validate_feedback_access($feedback, $course, $cm, $context, true); + $feedbackcompletion = self::validate_feedback_access($feedback, $courseid, $cm, $context, true); // Create the $_POST object required by the feedback question engine. $_POST = array(); @@ -653,7 +666,7 @@ class mod_feedback_external extends external_api { } // Force fields. $_POST['id'] = $cm->id; - $_POST['courseid'] = $course->id; + $_POST['courseid'] = $courseid; $_POST['gopage'] = $params['page']; $_POST['_qf__mod_feedback_complete_form'] = 1; diff --git a/mod/feedback/tests/external_test.php b/mod/feedback/tests/external_test.php index 813810765a8..e51c5511f10 100644 --- a/mod/feedback/tests/external_test.php +++ b/mod/feedback/tests/external_test.php @@ -531,6 +531,85 @@ class mod_feedback_external_testcase extends externallib_advanced_testcase { $itemid = $itemscreated[4]->id; $itemsaved = $DB->get_field('feedback_value', 'value', array('item' => $itemid)); $this->assertEquals('b', $itemsaved); + + // Check that the answers are saved for course 0. + foreach ($items as $item) { + $this->assertEquals(0, $item->course_id); + } + $completed = $DB->get_record('feedback_completed', []); + $this->assertEquals(0, $completed->courseid); + } + + public function test_process_page_site_feedback() { + global $DB; + $pagecontents = 'You finished it!'; + $this->feedback = $this->getDataGenerator()->create_module('feedback', + array('course' => SITEID, 'page_after_submit' => $pagecontents)); + + // Test user with full capabilities. + $this->setUser($this->student); + + // Add questions to the feedback, we are adding 2 pages of questions. + $itemscreated = self::populate_feedback($this->feedback, 2); + + $data = []; + foreach ($itemscreated as $item) { + + if (empty($item->hasvalue)) { + continue; + } + + switch ($item->typ) { + case 'textarea': + case 'textfield': + $value = 'Lorem ipsum'; + break; + case 'numeric': + $value = 5; + break; + case 'multichoice': + $value = '1'; + break; + case 'multichoicerated': + $value = '1'; + break; + case 'info': + $value = format_string($this->course->shortname, true, array('context' => $this->context)); + break; + default: + $value = ''; + } + $data[] = ['name' => $item->typ . '_' . $item->id, 'value' => $value]; + } + + // Process first page. + $firstpagedata = [$data[0], $data[1]]; + $result = mod_feedback_external::process_page($this->feedback->id, 0, $firstpagedata, false, $this->course->id); + $result = external_api::clean_returnvalue(mod_feedback_external::process_page_returns(), $result); + $this->assertEquals(1, $result['jumpto']); + $this->assertFalse($result['completed']); + + // Process second page. + $data[2]['value'] = 'b'; + $secondpagedata = [$data[2], $data[3], $data[4], $data[5], $data[6]]; + $result = mod_feedback_external::process_page($this->feedback->id, 1, $secondpagedata, false, $this->course->id); + $result = external_api::clean_returnvalue(mod_feedback_external::process_page_returns(), $result); + $this->assertTrue($result['completed']); + $this->assertTrue(strpos($result['completionpagecontents'], $pagecontents) !== false); + // Check all the items were saved. + $items = $DB->get_records('feedback_value'); + $this->assertCount(7, $items); + // Check if the one we modified was correctly saved. + $itemid = $itemscreated[4]->id; + $itemsaved = $DB->get_field('feedback_value', 'value', array('item' => $itemid)); + $this->assertEquals('b', $itemsaved); + + // Check that the answers are saved for the correct course. + foreach ($items as $item) { + $this->assertEquals($this->course->id, $item->course_id); + } + $completed = $DB->get_record('feedback_completed', []); + $this->assertEquals($this->course->id, $completed->courseid); } /**