From 3dd0ac559f852993422156a1c9e574c3b6c8991d Mon Sep 17 00:00:00 2001 From: Juan Leyva Date: Sat, 24 Oct 2015 17:03:35 +0200 Subject: [PATCH] MDL-51569 mod_choice: Check choice availability prior to do any action --- mod/choice/lib.php | 26 ++++++++++++++++++++++ mod/choice/tests/lib_test.php | 42 +++++++++++++++++++++++++++++++++++ mod/choice/view.php | 10 ++++++++- 3 files changed, 77 insertions(+), 1 deletion(-) diff --git a/mod/choice/lib.php b/mod/choice/lib.php index 43c3db6f419..7a62bc3d126 100644 --- a/mod/choice/lib.php +++ b/mod/choice/lib.php @@ -1007,3 +1007,29 @@ function choice_view($choice, $course, $cm, $context) { $completion = new completion_info($course); $completion->set_module_viewed($cm); } + +/** + * Check if a choice is available for the current user. + * + * @param stdClass $choice choice record + * @return array status (available or not and possible warnings) + */ +function choice_get_availability_status($choice) { + $available = true; + $warnings = array(); + + if ($choice->timeclose != 0) { + $timenow = time(); + + if ($choice->timeopen > $timenow) { + $available = false; + $warnings['notopenyet'] = userdate($choice->timeopen); + } else if ($timenow > $choice->timeclose) { + $available = false; + $warnings['expired'] = userdate($choice->timeclose); + } + } + + // Choice is available. + return array($available, $warnings); +} diff --git a/mod/choice/tests/lib_test.php b/mod/choice/tests/lib_test.php index 0f581170313..341886ea6b7 100644 --- a/mod/choice/tests/lib_test.php +++ b/mod/choice/tests/lib_test.php @@ -172,4 +172,46 @@ class mod_choice_lib_testcase extends externallib_advanced_testcase { } } + /** + * Test choice_get_availability_status + * @return void + */ + public function choice_get_availability_status() { + $this->resetAfterTest(); + + $this->setAdminUser(); + // Setup test data. + $course = $this->getDataGenerator()->create_course(); + $choice = $this->getDataGenerator()->create_module('choice', array('course' => $course->id)); + + // No time restrictions. + list($status, $warnings) = choice_get_availability_status($choice, false); + $this->assertEquals(true, $status); + $this->assertCount(0, $warnings); + + // With time restrictions, still open. + $choice->timeopen = time() - DAYSECS; + $choice->timeclose = time() + DAYSECS; + list($status, $warnings) = choice_get_availability_status($choice, false); + $this->assertEquals(true, $status); + $this->assertCount(0, $warnings); + + // Choice not open yet. + $choice->timeopen = time() + DAYSECS; + $choice->timeclose = $choice->timeopen + DAYSECS; + list($status, $warnings) = choice_get_availability_status($choice, false); + $this->assertEquals(false, $status); + $this->assertCount(1, $warnings); + $this->assertEquals('notopenyet', $warnings[0]); + + // Choice closed. + $choice->timeopen = time() - DAYSECS; + $choice->timeclose = time() - 1; + list($status, $warnings) = choice_get_availability_status($choice, false); + $this->assertEquals(false, $status); + $this->assertCount(1, $warnings); + $this->assertEquals('expired', $warnings[0]); + + } + } diff --git a/mod/choice/view.php b/mod/choice/view.php index d40bebaea96..98d4840559f 100644 --- a/mod/choice/view.php +++ b/mod/choice/view.php @@ -34,7 +34,10 @@ $strchoices = get_string('modulenameplural', 'choice'); $context = context_module::instance($cm->id); -if ($action == 'delchoice' and confirm_sesskey() and is_enrolled($context, NULL, 'mod/choice:choose') and $choice->allowupdate) { +list($choiceavailable, $warnings) = choice_get_availability_status($choice); + +if ($action == 'delchoice' and confirm_sesskey() and is_enrolled($context, NULL, 'mod/choice:choose') and $choice->allowupdate + and $choiceavailable) { $answercount = $DB->count_records('choice_answers', array('choiceid' => $choice->id, 'userid' => $USER->id)); if ($answercount > 0) { $DB->delete_records('choice_answers', array('choiceid' => $choice->id, 'userid' => $USER->id)); @@ -67,6 +70,11 @@ if (data_submitted() && is_enrolled($context, NULL, 'mod/choice:choose') && conf $answer = optional_param('answer', '', PARAM_INT); } + if (!$choiceavailable) { + $reason = current(array_keys($warnings)); + throw new moodle_exception($reason, 'choice', '', $warnings[$reason]); + } + if ($answer) { choice_user_submit_response($answer, $choice, $USER->id, $course, $cm); redirect(new moodle_url('/mod/choice/view.php', -- 2.43.0