예제 #1
0
/**
 * 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;
    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);
        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.
    if (!($choice->limitanswers && $choicesexceeded)) {
        $answersnapshots = array();
        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));
                    $answersnapshots[] = $c;
                } else {
                    $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;
                }
            }
            // Initialised as true, meaning we updated the answer.
            $answerupdated = true;
        } 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);
            }
            // Initalised as false, meaning we submitted a new answer.
            $answerupdated = false;
        }
    } 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();
    }
    // Now record completed event.
    if (isset($answerupdated)) {
        $eventdata = array();
        $eventdata['context'] = $context;
        $eventdata['objectid'] = $choice->id;
        $eventdata['userid'] = $userid;
        $eventdata['courseid'] = $course->id;
        $eventdata['other'] = array();
        $eventdata['other']['choiceid'] = $choice->id;
        if ($answerupdated) {
            $eventdata['other']['optionid'] = $formanswer;
            $event = \mod_choice\event\answer_updated::create($eventdata);
        } else {
            $eventdata['other']['optionid'] = $formanswers;
            $event = \mod_choice\event\answer_submitted::create($eventdata);
        }
        $event->add_record_snapshot('course', $course);
        $event->add_record_snapshot('course_modules', $cm);
        $event->add_record_snapshot('choice', $choice);
        foreach ($answersnapshots as $record) {
            $event->add_record_snapshot('choice_answers', $record);
        }
        $event->trigger();
    }
}
예제 #2
0
 /**
  * Test custom validations
  * for answer_updated event.
  */
 public function test_answer_updated_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.
     $this->setExpectedException('coding_exception');
     $event = \mod_choice\event\answer_updated::create($eventdata);
     $event->trigger();
     $this->assertEventContextNotUsed($event);
 }
예제 #3
0
/**
 * @global object
 * @param int $formanswer
 * @param object $choice
 * @param int $userid
 * @param object $course Course object
 * @param object $cm
 */
function choice_user_submit_response($formanswer, $choice, $userid, $course, $cm)
{
    global $DB, $CFG;
    require_once $CFG->libdir . '/completionlib.php';
    $current = $DB->get_record('choice_answers', array('choiceid' => $choice->id, 'userid' => $userid));
    $context = context_module::instance($cm->id);
    $countanswers = 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;
        }
        if ($currentgroup) {
            // If groups are being used, retrieve responses only for users in
            // current group
            global $CFG;
            $answers = $DB->get_records_sql("\nSELECT\n    ca.*\nFROM\n    {choice_answers} ca\n    INNER JOIN {groups_members} gm ON ca.userid=gm.userid\nWHERE\n    optionid=?\n    AND gm.groupid=?", array($formanswer, $currentgroup));
        } else {
            // Groups are not used, retrieve all answers for this option ID
            $answers = $DB->get_records("choice_answers", array("optionid" => $formanswer));
        }
        if ($answers) {
            foreach ($answers as $a) {
                //only return enrolled users.
                if (is_enrolled($context, $a->userid, 'mod/choice:choose')) {
                    $countanswers++;
                }
            }
        }
        $maxans = $choice->maxanswers[$formanswer];
    }
    if (!($choice->limitanswers && $countanswers >= $maxans)) {
        if ($current) {
            $newanswer = $current;
            $newanswer->optionid = $formanswer;
            $newanswer->timemodified = time();
            $DB->update_record("choice_answers", $newanswer);
            $eventdata = array();
            $eventdata['context'] = $context;
            $eventdata['objectid'] = $newanswer->id;
            $eventdata['userid'] = $userid;
            $eventdata['courseid'] = $course->id;
            $eventdata['other'] = array();
            $eventdata['other']['choiceid'] = $choice->id;
            $eventdata['other']['optionid'] = $formanswer;
            $event = \mod_choice\event\answer_updated::create($eventdata);
            $event->add_record_snapshot('choice_answers', $newanswer);
            $event->add_record_snapshot('course', $course);
            $event->add_record_snapshot('course_modules', $cm);
            $event->trigger();
        } else {
            $newanswer = new stdClass();
            $newanswer->choiceid = $choice->id;
            $newanswer->userid = $userid;
            $newanswer->optionid = $formanswer;
            $newanswer->timemodified = time();
            $newanswer->id = $DB->insert_record("choice_answers", $newanswer);
            // Update completion state
            $completion = new completion_info($course);
            if ($completion->is_enabled($cm) && $choice->completionsubmit) {
                $completion->update_state($cm, COMPLETION_COMPLETE);
            }
            $eventdata = array();
            $eventdata['context'] = $context;
            $eventdata['objectid'] = $newanswer->id;
            $eventdata['userid'] = $userid;
            $eventdata['courseid'] = $course->id;
            $eventdata['other'] = array();
            $eventdata['other']['choiceid'] = $choice->id;
            $eventdata['other']['optionid'] = $formanswer;
            $event = \mod_choice\event\answer_submitted::create($eventdata);
            $event->add_record_snapshot('choice_answers', $newanswer);
            $event->add_record_snapshot('course', $course);
            $event->add_record_snapshot('course_modules', $cm);
            $event->trigger();
        }
    } else {
        if (!($current->optionid == $formanswer)) {
            //check to see if current choice already selected - if not display error
            print_error('choicefull', 'choice');
        }
    }
}
예제 #4
0
파일: lib.php 프로젝트: educacionbe/cursos
/**
 * 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;
    require_once $CFG->libdir . '/completionlib.php';
    $continueurl = new moodle_url('/mod/choice/view.php', array('id' => $cm->id));
    // 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);
        if (!$choicelock) {
            print_error('cannotsubmit', 'choice', $continueurl);
        }
    }
    $current = $DB->get_record('choice_answers', array('choiceid' => $choice->id, 'userid' => $userid));
    $context = context_module::instance($cm->id);
    $countanswers = 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;
        }
        if ($currentgroup) {
            // If groups are being used, retrieve responses only for users in
            // current group
            global $CFG;
            $answers = $DB->get_records_sql("\nSELECT\n    ca.*\nFROM\n    {choice_answers} ca\n    INNER JOIN {groups_members} gm ON ca.userid=gm.userid\nWHERE\n    optionid=?\n    AND gm.groupid=?", array($formanswer, $currentgroup));
        } else {
            // Groups are not used, retrieve all answers for this option ID
            $answers = $DB->get_records("choice_answers", array("optionid" => $formanswer));
        }
        if ($answers) {
            foreach ($answers as $a) {
                //only return enrolled users.
                if (is_enrolled($context, $a->userid, 'mod/choice:choose')) {
                    $countanswers++;
                }
            }
        }
        $maxans = $choice->maxanswers[$formanswer];
    }
    // Check the user hasn't exceeded the maximum selections for the choice(s) they have selected.
    if (!($choice->limitanswers && $countanswers >= $maxans)) {
        if ($current) {
            // Update an existing answer.
            $newanswer = $current;
            $newanswer->optionid = $formanswer;
            $newanswer->timemodified = time();
            $DB->update_record("choice_answers", $newanswer);
            // Initialised as true, meaning we updated the answer.
            $answerupdated = true;
        } else {
            // Add new answer.
            $newanswer = new stdClass();
            $newanswer->choiceid = $choice->id;
            $newanswer->userid = $userid;
            $newanswer->optionid = $formanswer;
            $newanswer->timemodified = time();
            $newanswer->id = $DB->insert_record("choice_answers", $newanswer);
            // Update completion state
            $completion = new completion_info($course);
            if ($completion->is_enabled($cm) && $choice->completionsubmit) {
                $completion->update_state($cm, COMPLETION_COMPLETE);
            }
            // Initalised as false, meaning we submitted a new answer.
            $answerupdated = false;
        }
    } else {
        if (!($current->optionid == $formanswer)) {
            // Check to see if current choice already selected - if not display error.
            // Release lock before error.
            $choicelock->release();
            print_error('choicefull', 'choice', $continueurl);
        }
    }
    // Release lock.
    if (isset($choicelock)) {
        $choicelock->release();
    }
    // Now record completed event.
    if (isset($answerupdated)) {
        $eventdata = array();
        $eventdata['context'] = $context;
        $eventdata['objectid'] = $newanswer->id;
        $eventdata['userid'] = $userid;
        $eventdata['courseid'] = $course->id;
        $eventdata['other'] = array();
        $eventdata['other']['choiceid'] = $choice->id;
        $eventdata['other']['optionid'] = $formanswer;
        if ($answerupdated) {
            $event = \mod_choice\event\answer_updated::create($eventdata);
        } else {
            $event = \mod_choice\event\answer_submitted::create($eventdata);
        }
        $event->add_record_snapshot('choice_answers', $newanswer);
        $event->add_record_snapshot('course', $course);
        $event->add_record_snapshot('course_modules', $cm);
        $event->trigger();
    }
}