Esempio n. 1
0
 /**
  * Test custom validations.
  *
  * @expectedException coding_exception
  */
 public function test_answer_created_other_exception()
 {
     // Generate user data.
     $user = $this->getDataGenerator()->create_user();
     $eventdata = array();
     $eventdata['context'] = $this->context;
     $eventdata['objectid'] = 2;
     $eventdata['userid'] = $user->id;
     $eventdata['courseid'] = $this->course->id;
     $eventdata['other'] = array();
     // Make sure content identifier is always set.
     $event = \mod_choice\event\answer_created::create($eventdata);
     $event->trigger();
     $this->assertEventContextNotUsed($event);
 }
Esempio n. 2
0
File: lib.php Progetto: dg711/moodle
/**
 * Process user submitted answers for a choice,
 * and either updating them or saving new answers.
 *
 * @param int $formanswer users submitted answers.
 * @param object $choice the selected choice.
 * @param int $userid user identifier.
 * @param object $course current course.
 * @param object $cm course context.
 * @return void
 */
function choice_user_submit_response($formanswer, $choice, $userid, $course, $cm)
{
    global $DB, $CFG, $USER;
    require_once $CFG->libdir . '/completionlib.php';
    $continueurl = new moodle_url('/mod/choice/view.php', array('id' => $cm->id));
    if (empty($formanswer)) {
        print_error('atleastoneoption', 'choice', $continueurl);
    }
    if (is_array($formanswer)) {
        if (!$choice->allowmultiple) {
            print_error('multiplenotallowederror', 'choice', $continueurl);
        }
        $formanswers = $formanswer;
    } else {
        $formanswers = array($formanswer);
    }
    $options = $DB->get_records('choice_options', array('choiceid' => $choice->id), '', 'id');
    foreach ($formanswers as $key => $val) {
        if (!isset($options[$val])) {
            print_error('cannotsubmit', 'choice', $continueurl);
        }
    }
    // Start lock to prevent synchronous access to the same data
    // before it's updated, if using limits.
    if ($choice->limitanswers) {
        $timeout = 10;
        $locktype = 'mod_choice_choice_user_submit_response';
        // Limiting access to this choice.
        $resouce = 'choiceid:' . $choice->id;
        $lockfactory = \core\lock\lock_config::get_lock_factory($locktype);
        // Opening the lock.
        $choicelock = $lockfactory->get_lock($resouce, $timeout, MINSECS);
        if (!$choicelock) {
            print_error('cannotsubmit', 'choice', $continueurl);
        }
    }
    $current = $DB->get_records('choice_answers', array('choiceid' => $choice->id, 'userid' => $userid));
    $context = context_module::instance($cm->id);
    $choicesexceeded = false;
    $countanswers = array();
    foreach ($formanswers as $val) {
        $countanswers[$val] = 0;
    }
    if ($choice->limitanswers) {
        // Find out whether groups are being used and enabled
        if (groups_get_activity_groupmode($cm) > 0) {
            $currentgroup = groups_get_activity_group($cm);
        } else {
            $currentgroup = 0;
        }
        list($insql, $params) = $DB->get_in_or_equal($formanswers, SQL_PARAMS_NAMED);
        if ($currentgroup) {
            // If groups are being used, retrieve responses only for users in
            // current group
            global $CFG;
            $params['groupid'] = $currentgroup;
            $sql = "SELECT ca.*\n                      FROM {choice_answers} ca\n                INNER JOIN {groups_members} gm ON ca.userid=gm.userid\n                     WHERE optionid {$insql}\n                       AND gm.groupid= :groupid";
        } else {
            // Groups are not used, retrieve all answers for this option ID
            $sql = "SELECT ca.*\n                      FROM {choice_answers} ca\n                     WHERE optionid {$insql}";
        }
        $answers = $DB->get_records_sql($sql, $params);
        if ($answers) {
            foreach ($answers as $a) {
                //only return enrolled users.
                if (is_enrolled($context, $a->userid, 'mod/choice:choose')) {
                    $countanswers[$a->optionid]++;
                }
            }
        }
        foreach ($countanswers as $opt => $count) {
            if ($count >= $choice->maxanswers[$opt]) {
                $choicesexceeded = true;
                break;
            }
        }
    }
    // Check the user hasn't exceeded the maximum selections for the choice(s) they have selected.
    $answersnapshots = array();
    $deletedanswersnapshots = array();
    if (!($choice->limitanswers && $choicesexceeded)) {
        if ($current) {
            // Update an existing answer.
            $existingchoices = array();
            foreach ($current as $c) {
                if (in_array($c->optionid, $formanswers)) {
                    $existingchoices[] = $c->optionid;
                    $DB->set_field('choice_answers', 'timemodified', time(), array('id' => $c->id));
                } else {
                    $deletedanswersnapshots[] = $c;
                    $DB->delete_records('choice_answers', array('id' => $c->id));
                }
            }
            // Add new ones.
            foreach ($formanswers as $f) {
                if (!in_array($f, $existingchoices)) {
                    $newanswer = new stdClass();
                    $newanswer->optionid = $f;
                    $newanswer->choiceid = $choice->id;
                    $newanswer->userid = $userid;
                    $newanswer->timemodified = time();
                    $newanswer->id = $DB->insert_record("choice_answers", $newanswer);
                    $answersnapshots[] = $newanswer;
                }
            }
        } else {
            // Add new answer.
            foreach ($formanswers as $answer) {
                $newanswer = new stdClass();
                $newanswer->choiceid = $choice->id;
                $newanswer->userid = $userid;
                $newanswer->optionid = $answer;
                $newanswer->timemodified = time();
                $newanswer->id = $DB->insert_record("choice_answers", $newanswer);
                $answersnapshots[] = $newanswer;
            }
            // Update completion state
            $completion = new completion_info($course);
            if ($completion->is_enabled($cm) && $choice->completionsubmit) {
                $completion->update_state($cm, COMPLETION_COMPLETE);
            }
        }
    } else {
        // Check to see if current choice already selected - if not display error.
        $currentids = array_keys($current);
        if (array_diff($currentids, $formanswers) || array_diff($formanswers, $currentids)) {
            // Release lock before error.
            $choicelock->release();
            print_error('choicefull', 'choice', $continueurl);
        }
    }
    // Release lock.
    if (isset($choicelock)) {
        $choicelock->release();
    }
    // Trigger events.
    foreach ($deletedanswersnapshots as $answer) {
        \mod_choice\event\answer_deleted::create_from_object($answer, $choice, $cm, $course)->trigger();
    }
    foreach ($answersnapshots as $answer) {
        \mod_choice\event\answer_created::create_from_object($answer, $choice, $cm, $course)->trigger();
    }
}