/** * 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); } } if (!$choice->allowupdate && choice_get_my_response($choice)) { $available = false; $warnings['choicesaved'] = ''; } // Choice is available. return array($available, $warnings); }
groups_get_activity_group($cm, true); groups_print_activity_menu($cm, $CFG->wwwroot . '/mod/choice/view.php?id=' . $id); } // Check if we want to include responses from inactive users. $onlyactive = $choice->includeinactive ? false : true; $allresponses = choice_get_response_data($choice, $cm, $groupmode, $onlyactive); // Big function, approx 6 SQL calls per user. if (has_capability('mod/choice:readresponses', $context)) { choice_show_reportlink($allresponses, $cm); } echo '<div class="clearer"></div>'; if ($choice->intro) { echo $OUTPUT->box(format_module_intro('choice', $choice, $cm->id), 'generalbox', 'intro'); } $timenow = time(); $current = choice_get_my_response($choice); //if user has already made a selection, and they are not allowed to update it or if choice is not open, show their selected answer. if (isloggedin() && !empty($current) && (empty($choice->allowupdate) || $timenow > $choice->timeclose)) { $choicetexts = array(); foreach ($current as $c) { $choicetexts[] = format_string(choice_get_option_text($choice, $c->optionid)); } echo $OUTPUT->box(get_string("yourselection", "choice", userdate($choice->timeopen)) . ": " . implode('; ', $choicetexts), 'generalbox', 'yourselection'); } /// Print the form $choiceopen = true; if ($choice->timeclose != 0) { if ($choice->timeopen > $timenow) { if ($choice->showpreview) { echo $OUTPUT->box(get_string('previewonly', 'choice', userdate($choice->timeopen)), 'generalbox alert'); } else {
/** * Test delete_choice_responses */ public function test_delete_choice_responses() { global $DB; $this->resetAfterTest(true); $course = self::getDataGenerator()->create_course(); $params = new stdClass(); $params->course = $course->id; $params->option = array('fried rice', 'spring rolls', 'sweet and sour pork', 'satay beef', 'gyouza'); $params->name = 'First Choice Activity'; $params->showresults = CHOICE_SHOWRESULTS_ALWAYS; $params->allowmultiple = 1; $params->showunanswered = 1; $choice = self::getDataGenerator()->create_module('choice', $params); $cm = get_coursemodule_from_id('choice', $choice->cmid); $choiceinstance = choice_get_choice($cm->instance); $options = array_keys($choiceinstance->option); $student = $this->getDataGenerator()->create_user(); $studentrole = $DB->get_record('role', array('shortname' => 'student')); // Enroll student in Course1. self::getDataGenerator()->enrol_user($student->id, $course->id, $studentrole->id); $this->setUser($student); $results = mod_choice_external::submit_choice_response($choice->id, array($options[1], $options[2])); $results = external_api::clean_returnvalue(mod_choice_external::submit_choice_response_returns(), $results); $myresponses = array_keys(choice_get_my_response($choice)); // Try to delete responses when allow update is false. try { mod_choice_external::delete_choice_responses($choice->id, array($myresponses[0], $myresponses[0])); $this->fail('Exception expected due to missing permissions.'); } catch (required_capability_exception $e) { $this->assertEquals('nopermissions', $e->errorcode); } // Set allow update to true, and a passed time close. $DB->set_field('choice', 'allowupdate', 1, array('id' => $choice->id)); $DB->set_field('choice', 'timeclose', time() - DAYSECS, array('id' => $choice->id)); try { mod_choice_external::delete_choice_responses($choice->id, array($myresponses[0], $myresponses[1])); $this->fail('Exception expected due to expired choice.'); } catch (moodle_exception $e) { $this->assertEquals('expired', $e->errorcode); } // Reset time close. We should be able now to delete all the responses. $DB->set_field('choice', 'timeclose', 0, array('id' => $choice->id)); $results = mod_choice_external::delete_choice_responses($choice->id, array($myresponses[0], $myresponses[1])); $results = external_api::clean_returnvalue(mod_choice_external::delete_choice_responses_returns(), $results); $this->assertTrue($results['status']); $this->assertCount(0, $results['warnings']); // Now, in the DB 0 responses. $this->assertCount(0, choice_get_my_response($choice)); // Submit again the responses. $results = mod_choice_external::submit_choice_response($choice->id, array($options[1], $options[2])); $results = external_api::clean_returnvalue(mod_choice_external::submit_choice_response_returns(), $results); $myresponses = array_keys(choice_get_my_response($choice)); // Delete only one response. $results = mod_choice_external::delete_choice_responses($choice->id, array($myresponses[0])); $results = external_api::clean_returnvalue(mod_choice_external::delete_choice_responses_returns(), $results); $this->assertTrue($results['status']); $this->assertCount(0, $results['warnings']); // Now, in the DB 1 response still. $this->assertCount(1, choice_get_my_response($choice)); // Delete the remaining response, passing 2 invalid responses ids. $results = mod_choice_external::delete_choice_responses($choice->id, array($myresponses[1], $myresponses[0] + 2, $myresponses[0] + 3)); $results = external_api::clean_returnvalue(mod_choice_external::delete_choice_responses_returns(), $results); $this->assertTrue($results['status']); // 2 warnings, 2 invalid responses. $this->assertCount(2, $results['warnings']); // Now, in the DB 0 responses. $this->assertCount(0, choice_get_my_response($choice)); // Now, as an admin we must be able to delete all the responses under any condition. // Submit again the responses. $results = mod_choice_external::submit_choice_response($choice->id, array($options[1], $options[2])); $results = external_api::clean_returnvalue(mod_choice_external::submit_choice_response_returns(), $results); $studentresponses = array_keys(choice_get_my_response($choice)); $this->setAdminUser(); $DB->set_field('choice', 'allowupdate', 0, array('id' => $choice->id)); $DB->set_field('choice', 'timeclose', time() - DAYSECS, array('id' => $choice->id)); $results = mod_choice_external::delete_choice_responses($choice->id, array($studentresponses[0], $studentresponses[1])); $results = external_api::clean_returnvalue(mod_choice_external::delete_choice_responses_returns(), $results); $this->assertTrue($results['status']); $this->assertCount(0, $results['warnings']); // Submit again the responses. $DB->set_field('choice', 'timeclose', 0, array('id' => $choice->id)); $results = mod_choice_external::submit_choice_response($choice->id, array($options[1], $options[2])); $results = external_api::clean_returnvalue(mod_choice_external::submit_choice_response_returns(), $results); // With other user account too, so we can test all the responses are deleted. choice_user_submit_response(array($options[1], $options[2]), $choice, $student->id, $course, $cm); // Test deleting all (not passing the answers ids), event not only mine. $results = mod_choice_external::delete_choice_responses($choice->id); $results = external_api::clean_returnvalue(mod_choice_external::delete_choice_responses_returns(), $results); $this->assertTrue($results['status']); $this->assertCount(0, $results['warnings']); $this->assertCount(0, choice_get_all_responses($choice)); // Now, in the DB 0 responses. $this->setUser($student); // Submit again respones. $DB->set_field('choice', 'allowupdate', 1, array('id' => $choice->id)); $DB->set_field('choice', 'timeclose', 0, array('id' => $choice->id)); $results = mod_choice_external::submit_choice_response($choice->id, array($options[1], $options[2])); $results = external_api::clean_returnvalue(mod_choice_external::submit_choice_response_returns(), $results); // Delete all responses. $results = mod_choice_external::delete_choice_responses($choice->id); $results = external_api::clean_returnvalue(mod_choice_external::delete_choice_responses_returns(), $results); $this->assertTrue($results['status']); $this->assertCount(0, $results['warnings']); $this->assertCount(0, choice_get_my_response($choice)); }
/** * Return true if we are allowd to view the choice results. * * @param stdClass $choice Choice record * @param rows|null $current my choice responses * @param bool|null $choiceopen if the choice is open * @return bool true if we can view the results, false otherwise. * @since Moodle 3.0 */ function choice_can_view_results($choice, $current = null, $choiceopen = null) { if (is_null($choiceopen)) { $timenow = time(); if ($choice->timeclose != 0 && $timenow > $choice->timeclose) { $choiceopen = false; } else { $choiceopen = true; } } if (empty($current)) { $current = choice_get_my_response($choice); } if ($choice->showresults == CHOICE_SHOWRESULTS_ALWAYS or ($choice->showresults == CHOICE_SHOWRESULTS_AFTER_ANSWER and !empty($current)) or ($choice->showresults == CHOICE_SHOWRESULTS_AFTER_CLOSE and !$choiceopen)) { return true; } return false; }
/** * Delete the given submitted responses in a choice * * @param int $choiceid the choice instance id * @param array $responses the response ids, empty for deleting all the user responses * @return array status information and warnings * @throws moodle_exception * @since Moodle 3.0 */ public static function delete_choice_responses($choiceid, $responses = array()) { $status = false; $warnings = array(); $params = self::validate_parameters(self::delete_choice_responses_parameters(), array('choiceid' => $choiceid, 'responses' => $responses)); if (!($choice = choice_get_choice($params['choiceid']))) { throw new moodle_exception("invalidcoursemodule", "error"); } list($course, $cm) = get_course_and_cm_from_instance($choice, 'choice'); $context = context_module::instance($cm->id); self::validate_context($context); require_capability('mod/choice:choose', $context); // If we have the capability, delete all the passed responses. if (has_capability('mod/choice:deleteresponses', $context)) { if (empty($params['responses'])) { // Get all the responses for the choice. $params['responses'] = array_keys(choice_get_all_responses($choice)); } $status = choice_delete_responses($params['responses'], $choice, $cm, $course); } else { if ($choice->allowupdate) { // Check if we can delate our own responses. $timenow = time(); if ($choice->timeclose != 0) { if ($timenow > $choice->timeclose) { throw new moodle_exception("expired", "choice", '', userdate($choice->timeclose)); } } // Delete only our responses. $myresponses = array_keys(choice_get_my_response($choice)); if (empty($params['responses'])) { $todelete = $myresponses; } else { $todelete = array(); foreach ($params['responses'] as $response) { if (!in_array($response, $myresponses)) { $warnings[] = array('item' => 'response', 'itemid' => $response, 'warningcode' => 'nopermissions', 'message' => 'No permission to delete this response'); } else { $todelete[] = $response; } } } $status = choice_delete_responses($todelete, $choice, $cm, $course); } else { // The user requires the capability to delete responses. throw new required_capability_exception($context, 'mod/choice:deleteresponses', 'nopermissions', ''); } } return array('status' => $status, 'warnings' => $warnings); }
/** * Test choice_get_my_response * @return void */ public function test_choice_get_my_response() { global $USER; $this->resetAfterTest(); $this->setAdminUser(); // Setup test data. $course = $this->getDataGenerator()->create_course(); $choice = $this->getDataGenerator()->create_module('choice', array('course' => $course->id)); $context = context_module::instance($choice->cmid); $cm = get_coursemodule_from_instance('choice', $choice->id); $choicewithoptions = choice_get_choice($choice->id); $optionids = array_keys($choicewithoptions->option); choice_user_submit_response($optionids[0], $choice, $USER->id, $course, $cm); $responses = choice_get_my_response($choice, $course, $cm, $context); $this->assertCount(1, $responses); $response = array_shift($responses); $this->assertEquals($optionids[0], $response->optionid); // Multiple responses. $choice = $this->getDataGenerator()->create_module('choice', array('course' => $course->id, 'allowmultiple' => 1)); $context = context_module::instance($choice->cmid); $cm = get_coursemodule_from_instance('choice', $choice->id); $choicewithoptions = choice_get_choice($choice->id); $optionids = array_keys($choicewithoptions->option); choice_user_submit_response($optionids, $choice, $USER->id, $course, $cm); $responses = choice_get_my_response($choice, $course, $cm, $context); $this->assertCount(count($optionids), $responses); foreach ($responses as $resp) { $this->assertContains($resp->optionid, $optionids); } }
/** * Submit choice responses * * @param int $choiceid the choice instance id * @param array $responses the response ids * @return array ansers informatinon and warnings * @since Moodle 3.0 */ public static function submit_choice_response($choiceid, $responses) { global $USER; $warnings = array(); $params = self::validate_parameters(self::submit_choice_response_parameters(), array( 'choiceid' => $choiceid, 'responses' => $responses )); if (!$choice = choice_get_choice($params['choiceid'])) { throw new moodle_exception("invalidcoursemodule", "error"); } list($course, $cm) = get_course_and_cm_from_instance($choice, 'choice'); $context = context_module::instance($cm->id); self::validate_context($context); require_capability('mod/choice:choose', $context); $timenow = time(); if ($choice->timeclose != 0) { if ($choice->timeopen > $timenow) { throw new moodle_exception("notopenyet", "choice", '', userdate($choice->timeopen)); } else if ($timenow > $choice->timeclose) { throw new moodle_exception("expired", "choice", '', userdate($choice->timeclose)); } } if (!choice_get_my_response($choice) or $choice->allowupdate) { // When a single response is given, we convert the array to a simple variable // in order to avoid choice_user_submit_response to check with allowmultiple even // for a single response. if (count($params['responses']) == 1) { $params['responses'] = reset($params['responses']); } choice_user_submit_response($params['responses'], $choice, $USER->id, $course, $cm); } else { throw new moodle_exception('missingrequiredcapability', 'webservice', '', 'allowupdate'); } $answers = choice_get_my_response($choice); return array( 'answers' => $answers, 'warnings' => $warnings ); }