/**
 * Check if the user or group has correctly answered the question and complete the required activity.
 * If the group identifier provided is not 0, the group is checked, else the user is checked.
 * 
 * @param int $selectedanswerid The identifier of the answer selected by the user.
 * @param int $userid The identifier of user.
 * @param int $groupid The identifier of the group to which the user belongs.
 * @param int $roadid The identifier of the road of user.
 * @param bool $updateroad If the road has been updated or not.
 * @param stdClass $context The context object.
 * @param stdClass $treasurehunt The treasurehunt instance.
 * @param int $nostages The total number of stages in the road.
 * @param bool $qoaremoved If the question or activity to end has been removed or not.
 * @return stdClass The control parameters.
 */
function treasurehunt_check_question_and_activity_solved($selectedanswerid, $userid, $groupid, $roadid, $updateroad, $context, $treasurehunt, $nostages, $qoaremoved)
{
    global $DB;
    $return = new stdClass();
    $return->msg = '';
    $return->updates = array();
    $return->newattempt = false;
    $return->attemptsolved = false;
    $return->roadfinished = false;
    $return->qoaremoved = false;
    $return->success = false;
    $lastattempt = treasurehunt_get_last_successful_attempt($userid, $groupid, $roadid);
    // If the last attempt has resolved geometry but the stage is not exceeded.
    if (!$lastattempt->success && $lastattempt->geometrysolved) {
        $lastattempt->userid = $userid;
        $lastattempt->groupid = $groupid;
        $activitysolved = false;
        // If the last attempt is not completed activity to overcome.
        if (!$lastattempt->activitysolved) {
            // If there is an activity to overcome.
            if (treasurehunt_check_activity_completion($lastattempt->activitytoend)) {
                if ($usercompletion = treasurehunt_check_completion_activity($lastattempt->activitytoend, $userid, $groupid, $context)) {
                    $return->newattempt = true;
                    $return->attemptsolved = true;
                    $return->updates[] = get_string('activitytoendovercome', 'treasurehunt', treasurehunt_get_activity_to_end_link($lastattempt->activitytoend));
                    // If there is no question and still has not been resolved.
                    if (!$lastattempt->questionsolved && $lastattempt->questiontext === '') {
                        $lastattempt->questionsolved = 1;
                        $return->updates[] = get_string('removedquestion', 'treasurehunt');
                    }
                    $lastattempt->userid = $usercompletion;
                    $lastattempt->type = 'activity';
                    $lastattempt->timecreated = time();
                    $lastattempt->activitysolved = 1;
                    $lastattempt->penalty = 0;
                    // If the question is already resolved is set to overcome.
                    if ($lastattempt->questionsolved) {
                        $lastattempt->success = 1;
                    } else {
                        $lastattempt->success = 0;
                    }
                    treasurehunt_insert_attempt($lastattempt, $context);
                    $activitysolved = true;
                    // If the stage is overcome, attempt is created.
                    if ($lastattempt->success == 1) {
                        $lastattempt->type = 'location';
                        $lastattempt->timecreated += 1;
                        treasurehunt_insert_attempt($lastattempt, $context);
                    }
                }
            } else {
                // If there is no activity to overcome is that has been deleted.
                $return->qoaremoved = true;
                if (!$qoaremoved) {
                    $return->updates[] = get_string('removedactivitytoend', 'treasurehunt');
                    $return->attemptsolved = true;
                }
                $lastattempt->activitysolved = 1;
                // If there is no question.
                if ($lastattempt->questiontext === '') {
                    $lastattempt->questionsolved = 1;
                    $return->updates[] = get_string('removedquestion', 'treasurehunt');
                }
                // If the question is overcome.
                if ($lastattempt->questionsolved) {
                    $lastattempt->success = 1;
                    $lastattempt->type = 'location';
                    $lastattempt->penalty = 0;
                    $lastattempt->timecreated = time();
                    treasurehunt_insert_attempt($lastattempt, $context);
                    $return->newattempt = true;
                    $return->attemptsolved = true;
                }
            }
        }
        // If the question is not overcome.
        if (!$lastattempt->questionsolved) {
            // If there is no question.
            if ($lastattempt->questiontext === '') {
                $return->qoaremoved = true;
                if (!$qoaremoved) {
                    $return->updates[] = get_string('removedquestion', 'treasurehunt');
                    $return->attemptsolved = true;
                }
                // If the activity to end is overcome, succesful attempt is created.
                if ($lastattempt->activitysolved) {
                    $lastattempt->success = 1;
                    $lastattempt->type = 'location';
                    $lastattempt->questionsolved = 1;
                    $lastattempt->penalty = 0;
                    $lastattempt->timecreated = time();
                    treasurehunt_insert_attempt($lastattempt, $context);
                    $return->newattempt = true;
                    $return->attemptsolved = true;
                }
            } else {
                // If there is an answer and the road has not been updated.
                if ($selectedanswerid > 0 && !$updateroad) {
                    $answer = $DB->get_record('treasurehunt_answers', array('id' => $selectedanswerid), 'correct,stageid', MUST_EXIST);
                    if ($answer->stageid != $lastattempt->stageid) {
                        $return->msg = get_string('warmatchanswer', 'treasurehunt');
                    } else {
                        $return->newattempt = true;
                        $lastattempt->type = 'question';
                        // To follow a chronological order.
                        $lastattempt->timecreated = time() + 1;
                        if ($answer->correct) {
                            $return->attemptsolved = true;
                            $return->msg = get_string('correctanswer', 'treasurehunt');
                            $lastattempt->questionsolved = 1;
                            $lastattempt->penalty = 0;
                            if ($lastattempt->activitysolved) {
                                $lastattempt->success = 1;
                            } else {
                                $lastattempt->success = 0;
                            }
                            treasurehunt_insert_attempt($lastattempt, $context);
                            if ($lastattempt->activitysolved) {
                                $lastattempt->type = 'location';
                                $lastattempt->timecreated += 1;
                                treasurehunt_insert_attempt($lastattempt, $context);
                            }
                        } else {
                            $return->msg = get_string('incorrectanswer', 'treasurehunt');
                            $lastattempt->questionsolved = 0;
                            $lastattempt->penalty = 1;
                            treasurehunt_insert_attempt($lastattempt, $context);
                        }
                    }
                }
            }
        }
        if ($return->newattempt == true) {
            if ($lastattempt->success) {
                $return->success = true;
            }
            if ($lastattempt->success && $lastattempt->position == $nostages) {
                if ($treasurehunt->grademethod != TREASUREHUNT_GRADEFROMSTAGES) {
                    treasurehunt_update_grades($treasurehunt);
                } else {
                    treasurehunt_set_grade($treasurehunt, $groupid, $userid);
                }
                $return->roadfinished = true;
            } else {
                treasurehunt_set_grade($treasurehunt, $groupid, $userid);
            }
        }
        $return->attempttimestamp = $lastattempt->timecreated;
    }
    return $return;
}
Esempio n. 2
0
/**
 * Updates an instance of the treasurehunt in the database
 *
 * Given an object containing all the necessary data,
 * (defined by the form in mod_form.php) this function
 * will update an existing instance with new data.
 *
 * @param stdClass $treasurehunt An object from the form in mod_form.php
 * @param mod_treasurehunt_mod_form $mform The form instance itself (if needed)
 * @return boolean Success/Fail
 */
function treasurehunt_update_instance(stdClass $treasurehunt, mod_treasurehunt_mod_form $mform = null)
{
    global $DB;
    // Get the current value, so we can see what changed.
    $oldtreasurehunt = $DB->get_record('treasurehunt', array('id' => $treasurehunt->instance));
    // Update the database.
    $treasurehunt->timemodified = time();
    $treasurehunt->id = $treasurehunt->instance;
    $result = $DB->update_record('treasurehunt', $treasurehunt);
    if ($oldtreasurehunt->grade != $treasurehunt->grade && $treasurehunt->grade > 0 || $oldtreasurehunt->grademethod != $treasurehunt->grademethod || $oldtreasurehunt->gradepenlocation != $treasurehunt->gradepenlocation || $oldtreasurehunt->gradepenanswer != $treasurehunt->gradepenanswer || $oldtreasurehunt->groupmode != $treasurehunt->groupmode) {
        treasurehunt_update_grades($treasurehunt);
    }
    treasurehunt_grade_item_update($treasurehunt);
    treasurehunt_update_events($treasurehunt);
    return $result;
}