MDL-52786 mod_quiz: New WS mod_quiz_get_combined_review_options
This commit is contained in:
@@ -1311,6 +1311,7 @@ $services = array(
|
||||
'mod_imscp_view_imscp',
|
||||
'mod_imscp_get_imscps_by_courses',
|
||||
'mod_quiz_get_quizzes_by_courses',
|
||||
'mod_quiz_get_combined_review_options',
|
||||
'mod_quiz_get_user_attempts',
|
||||
'mod_quiz_view_quiz',
|
||||
'mod_quiz_get_user_best_grade',
|
||||
|
||||
@@ -530,4 +530,110 @@ class mod_quiz_external extends external_api {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Describes the parameters for get_combined_review_options.
|
||||
*
|
||||
* @return external_external_function_parameters
|
||||
* @since Moodle 3.1
|
||||
*/
|
||||
public static function get_combined_review_options_parameters() {
|
||||
return new external_function_parameters (
|
||||
array(
|
||||
'quizid' => new external_value(PARAM_INT, 'quiz instance id'),
|
||||
'userid' => new external_value(PARAM_INT, 'user id (empty for current user)', VALUE_DEFAULT, 0),
|
||||
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Combines the review options from a number of different quiz attempts.
|
||||
*
|
||||
* @param int $quizid quiz instance id
|
||||
* @param int $userid user id (empty for current user)
|
||||
* @return array of warnings and the review options
|
||||
* @since Moodle 3.1
|
||||
*/
|
||||
public static function get_combined_review_options($quizid, $userid = 0) {
|
||||
global $DB, $USER;
|
||||
|
||||
$warnings = array();
|
||||
|
||||
$params = array(
|
||||
'quizid' => $quizid,
|
||||
'userid' => $userid,
|
||||
);
|
||||
$params = self::validate_parameters(self::get_combined_review_options_parameters(), $params);
|
||||
|
||||
// Request and permission validation.
|
||||
$quiz = $DB->get_record('quiz', array('id' => $params['quizid']), '*', MUST_EXIST);
|
||||
list($course, $cm) = get_course_and_cm_from_instance($quiz, 'quiz');
|
||||
|
||||
$context = context_module::instance($cm->id);
|
||||
self::validate_context($context);
|
||||
|
||||
// Default value for userid.
|
||||
if (empty($params['userid'])) {
|
||||
$params['userid'] = $USER->id;
|
||||
}
|
||||
|
||||
$user = core_user::get_user($params['userid'], '*', MUST_EXIST);
|
||||
core_user::require_active_user($user);
|
||||
|
||||
// Extra checks so only users with permissions can view other users attempts.
|
||||
if ($USER->id != $user->id) {
|
||||
require_capability('mod/quiz:viewreports', $context);
|
||||
}
|
||||
|
||||
$attempts = quiz_get_user_attempts($quiz->id, $user->id, 'all', true);
|
||||
|
||||
$result = array();
|
||||
$result['someoptions'] = [];
|
||||
$result['alloptions'] = [];
|
||||
|
||||
list($someoptions, $alloptions) = quiz_get_combined_reviewoptions($quiz, $attempts);
|
||||
|
||||
foreach (array('someoptions', 'alloptions') as $typeofoption) {
|
||||
foreach ($$typeofoption as $key => $value) {
|
||||
$result[$typeofoption][] = array(
|
||||
"name" => $key,
|
||||
"value" => (!empty($value)) ? $value : 0
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$result['warnings'] = $warnings;
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Describes the get_combined_review_options return value.
|
||||
*
|
||||
* @return external_single_structure
|
||||
* @since Moodle 3.1
|
||||
*/
|
||||
public static function get_combined_review_options_returns() {
|
||||
return new external_single_structure(
|
||||
array(
|
||||
'someoptions' => new external_multiple_structure(
|
||||
new external_single_structure(
|
||||
array(
|
||||
'name' => new external_value(PARAM_ALPHANUMEXT, 'option name'),
|
||||
'value' => new external_value(PARAM_INT, 'option value'),
|
||||
)
|
||||
)
|
||||
),
|
||||
'alloptions' => new external_multiple_structure(
|
||||
new external_single_structure(
|
||||
array(
|
||||
'name' => new external_value(PARAM_ALPHANUMEXT, 'option name'),
|
||||
'value' => new external_value(PARAM_INT, 'option value'),
|
||||
)
|
||||
)
|
||||
),
|
||||
'warnings' => new external_warnings(),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -60,4 +60,12 @@ $functions = array(
|
||||
'type' => 'read',
|
||||
'capabilities' => 'mod/quiz:view'
|
||||
),
|
||||
|
||||
'mod_quiz_get_combined_review_options' => array(
|
||||
'classname' => 'mod_quiz_external',
|
||||
'methodname' => 'get_combined_review_options',
|
||||
'description' => 'Combines the review options from a number of different quiz attempts.',
|
||||
'type' => 'read',
|
||||
'capabilities' => 'mod/quiz:view'
|
||||
),
|
||||
);
|
||||
|
||||
@@ -448,4 +448,141 @@ class mod_quiz_external_testcase extends externallib_advanced_testcase {
|
||||
$DB->delete_records('quiz_grades', array('id' => $grade->id));
|
||||
|
||||
}
|
||||
/**
|
||||
* Test get_combined_review_options.
|
||||
* This is a basic test, this is already tested in mod_quiz_display_options_testcase.
|
||||
*/
|
||||
public function test_get_combined_review_options() {
|
||||
global $DB;
|
||||
|
||||
// Create a new quiz with attempts.
|
||||
$quizgenerator = $this->getDataGenerator()->get_plugin_generator('mod_quiz');
|
||||
$data = array('course' => $this->course->id,
|
||||
'sumgrades' => 1);
|
||||
$quiz = $quizgenerator->create_instance($data);
|
||||
|
||||
// Create a couple of questions.
|
||||
$questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question');
|
||||
|
||||
$cat = $questiongenerator->create_question_category();
|
||||
$question = $questiongenerator->create_question('numerical', null, array('category' => $cat->id));
|
||||
quiz_add_quiz_question($question->id, $quiz);
|
||||
|
||||
$quizobj = quiz::create($quiz->id, $this->student->id);
|
||||
|
||||
// Set grade to pass.
|
||||
$item = grade_item::fetch(array('courseid' => $this->course->id, 'itemtype' => 'mod',
|
||||
'itemmodule' => 'quiz', 'iteminstance' => $quiz->id, 'outcomeid' => null));
|
||||
$item->gradepass = 80;
|
||||
$item->update();
|
||||
|
||||
// Start the passing attempt.
|
||||
$quba = question_engine::make_questions_usage_by_activity('mod_quiz', $quizobj->get_context());
|
||||
$quba->set_preferred_behaviour($quizobj->get_quiz()->preferredbehaviour);
|
||||
|
||||
$timenow = time();
|
||||
$attempt = quiz_create_attempt($quizobj, 1, false, $timenow, false, $this->student->id);
|
||||
quiz_start_new_attempt($quizobj, $quba, $attempt, 1, $timenow);
|
||||
quiz_attempt_save_started($quizobj, $quba, $attempt);
|
||||
|
||||
$this->setUser($this->student);
|
||||
|
||||
$result = mod_quiz_external::get_combined_review_options($quiz->id);
|
||||
$result = external_api::clean_returnvalue(mod_quiz_external::get_combined_review_options_returns(), $result);
|
||||
|
||||
// Expected values.
|
||||
$expected = array(
|
||||
"someoptions" => array(
|
||||
array("name" => "feedback", "value" => 1),
|
||||
array("name" => "generalfeedback", "value" => 1),
|
||||
array("name" => "rightanswer", "value" => 1),
|
||||
array("name" => "overallfeedback", "value" => 0),
|
||||
array("name" => "marks", "value" => 2),
|
||||
),
|
||||
"alloptions" => array(
|
||||
array("name" => "feedback", "value" => 1),
|
||||
array("name" => "generalfeedback", "value" => 1),
|
||||
array("name" => "rightanswer", "value" => 1),
|
||||
array("name" => "overallfeedback", "value" => 0),
|
||||
array("name" => "marks", "value" => 2),
|
||||
),
|
||||
"warnings" => [],
|
||||
);
|
||||
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
// Now, finish the attempt.
|
||||
$attemptobj = quiz_attempt::create($attempt->id);
|
||||
$attemptobj->process_finish($timenow, false);
|
||||
|
||||
$expected = array(
|
||||
"someoptions" => array(
|
||||
array("name" => "feedback", "value" => 1),
|
||||
array("name" => "generalfeedback", "value" => 1),
|
||||
array("name" => "rightanswer", "value" => 1),
|
||||
array("name" => "overallfeedback", "value" => 1),
|
||||
array("name" => "marks", "value" => 2),
|
||||
),
|
||||
"alloptions" => array(
|
||||
array("name" => "feedback", "value" => 1),
|
||||
array("name" => "generalfeedback", "value" => 1),
|
||||
array("name" => "rightanswer", "value" => 1),
|
||||
array("name" => "overallfeedback", "value" => 1),
|
||||
array("name" => "marks", "value" => 2),
|
||||
),
|
||||
"warnings" => [],
|
||||
);
|
||||
|
||||
// We should see now the overall feedback.
|
||||
$result = mod_quiz_external::get_combined_review_options($quiz->id);
|
||||
$result = external_api::clean_returnvalue(mod_quiz_external::get_combined_review_options_returns(), $result);
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
// Start a new attempt, but not finish it.
|
||||
$timenow = time();
|
||||
$attempt = quiz_create_attempt($quizobj, 2, false, $timenow, false, $this->student->id);
|
||||
$quba = question_engine::make_questions_usage_by_activity('mod_quiz', $quizobj->get_context());
|
||||
$quba->set_preferred_behaviour($quizobj->get_quiz()->preferredbehaviour);
|
||||
quiz_start_new_attempt($quizobj, $quba, $attempt, 1, $timenow);
|
||||
quiz_attempt_save_started($quizobj, $quba, $attempt);
|
||||
|
||||
$expected = array(
|
||||
"someoptions" => array(
|
||||
array("name" => "feedback", "value" => 1),
|
||||
array("name" => "generalfeedback", "value" => 1),
|
||||
array("name" => "rightanswer", "value" => 1),
|
||||
array("name" => "overallfeedback", "value" => 1),
|
||||
array("name" => "marks", "value" => 2),
|
||||
),
|
||||
"alloptions" => array(
|
||||
array("name" => "feedback", "value" => 1),
|
||||
array("name" => "generalfeedback", "value" => 1),
|
||||
array("name" => "rightanswer", "value" => 1),
|
||||
array("name" => "overallfeedback", "value" => 0),
|
||||
array("name" => "marks", "value" => 2),
|
||||
),
|
||||
"warnings" => [],
|
||||
);
|
||||
|
||||
$result = mod_quiz_external::get_combined_review_options($quiz->id);
|
||||
$result = external_api::clean_returnvalue(mod_quiz_external::get_combined_review_options_returns(), $result);
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
// Teacher, for see student options.
|
||||
$this->setUser($this->teacher);
|
||||
|
||||
$result = mod_quiz_external::get_combined_review_options($quiz->id, $this->student->id);
|
||||
$result = external_api::clean_returnvalue(mod_quiz_external::get_combined_review_options_returns(), $result);
|
||||
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
// Invalid user.
|
||||
try {
|
||||
mod_quiz_external::get_combined_review_options($quiz->id, -1);
|
||||
$this->fail('Exception expected due to missing capability.');
|
||||
} catch (dml_missing_record_exception $e) {
|
||||
$this->assertEquals('invaliduser', $e->errorcode);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2015111604;
|
||||
$plugin->version = 2015111606;
|
||||
$plugin->requires = 2015111000;
|
||||
$plugin->component = 'mod_quiz';
|
||||
$plugin->cron = 60;
|
||||
|
||||
Reference in New Issue
Block a user