Example #1
0
$attemptids = optional_param_array('attemptid', array(), PARAM_INT);
// array of attempt ids for delete action
$notify = optional_param('notify', '', PARAM_ALPHA);
$url = new moodle_url('/mod/choice/view.php', array('id' => $id));
if ($action !== '') {
    $url->param('action', $action);
}
$PAGE->set_url($url);
if (!($cm = get_coursemodule_from_id('choice', $id))) {
    print_error('invalidcoursemodule');
}
if (!($course = $DB->get_record("course", array("id" => $cm->course)))) {
    print_error('coursemisconf');
}
require_course_login($course, false, $cm);
if (!($choice = choice_get_choice($cm->instance))) {
    print_error('invalidcoursemodule');
}
$strchoice = get_string('modulename', 'choice');
$strchoices = get_string('modulenameplural', 'choice');
$context = context_module::instance($cm->id);
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));
        // Update completion state
        $completion = new completion_info($course);
        if ($completion->is_enabled($cm) && $choice->completionsubmit) {
            $completion->update_state($cm, COMPLETION_INCOMPLETE);
        }
Example #2
0
 /**
  * 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));
 }
Example #3
0
/**
 * Adds module specific settings to the settings block
 *
 * @param settings_navigation $settings The settings navigation object
 * @param navigation_node $choicenode The node to add module settings to
 */
function choice_extend_settings_navigation(settings_navigation $settings, navigation_node $choicenode)
{
    global $PAGE;
    if (has_capability('mod/choice:readresponses', $PAGE->cm->context)) {
        $groupmode = groups_get_activity_groupmode($PAGE->cm);
        if ($groupmode) {
            groups_get_activity_group($PAGE->cm, true);
        }
        $choice = choice_get_choice($PAGE->cm->instance);
        // Check if we want to include responses from inactive users.
        $onlyactive = $choice->includeinactive ? false : true;
        // Big function, approx 6 SQL calls per user.
        $allresponses = choice_get_response_data($choice, $PAGE->cm, $groupmode, $onlyactive);
        $responsecount = 0;
        foreach ($allresponses as $optionid => $userlist) {
            if ($optionid) {
                $responsecount += count($userlist);
            }
        }
        $choicenode->add(get_string("viewallresponses", "choice", $responsecount), new moodle_url('/mod/choice/report.php', array('id' => $PAGE->cm->id)));
    }
}
Example #4
0
 /**
  * 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);
 }
Example #5
0
    /**
     * Test submit_choice_response
     */
    public function test_submit_choice_response() {
        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);
        $student1 = $this->getDataGenerator()->create_user();
        $studentrole = $DB->get_record('role', array('shortname' => 'student'));

        // Enroll Students in Course1.
        self::getDataGenerator()->enrol_user($student1->id,  $course->id, $studentrole->id);

        $this->setUser($student1);
        $myresponse = $options[2];
        $results = mod_choice_external::submit_choice_response($choice->id, array($myresponse));
        // We need to execute the return values cleaning process to simulate the web service server.
        $results = external_api::clean_returnvalue(mod_choice_external::submit_choice_response_returns(), $results);
        $myanswers = $DB->get_records('choice_answers', array('choiceid' => $choice->id, 'userid' => $student1->id));
        $myanswer = reset($myanswers);
        $this->assertEquals($results['answers'][0]['id'], $myanswer->id);
        $this->assertEquals($results['answers'][0]['choiceid'], $myanswer->choiceid);
        $this->assertEquals($results['answers'][0]['userid'], $myanswer->userid);
        $this->assertEquals($results['answers'][0]['timemodified'], $myanswer->timemodified);
    }
Example #6
0
 /**
  * Test choice_get_availability_status
  * @return void
  */
 public function test_choice_get_availability_status()
 {
     global $USER;
     $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 and updates allowed.
     list($status, $warnings) = choice_get_availability_status($choice, false);
     $this->assertEquals(true, $status);
     $this->assertCount(0, $warnings);
     // No updates allowed, but haven't answered yet.
     $choice->allowupdate = false;
     list($status, $warnings) = choice_get_availability_status($choice, false);
     $this->assertEquals(true, $status);
     $this->assertCount(0, $warnings);
     // No updates allowed and have answered.
     $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);
     list($status, $warnings) = choice_get_availability_status($choice, false);
     $this->assertEquals(false, $status);
     $this->assertCount(1, $warnings);
     $this->assertEquals('choicesaved', array_keys($warnings)[0]);
     $choice->allowupdate = true;
     // 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', array_keys($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', array_keys($warnings)[0]);
 }
Example #7
0
    /**
     * 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);
        }
    }
Example #8
0
    /**
     * Trigger the course module viewed event and update the module completion status.
     *
     * @param int $choiceid the choice instance id
     * @return array of warnings and status result
     * @since Moodle 3.0
     * @throws moodle_exception
     */
    public static function view_choice($choiceid) {
        global $CFG;

        $params = self::validate_parameters(self::view_choice_parameters(),
                                            array(
                                                'choiceid' => $choiceid
                                            ));
        $warnings = array();

        // Request and permission validation.
        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);

        // Trigger course_module_viewed event and completion.
        choice_view($choice, $course, $cm, $context);

        $result = array();
        $result['status'] = true;
        $result['warnings'] = $warnings;
        return $result;
    }