Permalink
Browse files

MDL-60062 quiz: add support for drag drop of calendar events

  • Loading branch information...
ryanwyllie committed Oct 5, 2017
1 parent 159b4e5 commit 9aac9f70748c016419cc037d5213d643a1e8d2e2
@@ -565,6 +565,7 @@
$string['onlyteachersimport'] = 'Only teachers with editing rights can import questions';
$string['onthispage'] = 'This page';
$string['open'] = 'Not answered';
$string['openafterclose'] = 'Could not update the quiz. You have specified an open date after the close date.';
$string['openclosedatesupdated'] = 'Quiz open and close dates updated';
$string['optional'] = 'optional';
$string['orderandpaging'] = 'Order and paging';
View
@@ -2253,3 +2253,175 @@ function mod_quiz_get_completion_active_rule_descriptions($cm) {
}
return $descriptions;
}
/**
* Returns the min and max values for the timestart property of a quiz
* activity event.
*
* The min and max values will be the timeopen and timeclose properties
* of the quiz, respectively, if they are set.
*
* If either value isn't set then null will be returned instead to
* indicate that there is no cutoff for that value.
*
* A minimum and maximum cutoff return value will look like:
* [
* [1505704373, 'The date must be after this date'],
* [1506741172, 'The date must be before this date']
* ]
*
* @param \calendar_event $event The calendar event to get the time range for
* @param stdClass|null $quiz The module instance to get the range from
* @return array
*/
function mod_quiz_core_calendar_get_valid_event_timestart_range(\calendar_event $event, \stdClass $quiz = null) {
global $CFG, $DB;
require_once($CFG->dirroot . '/mod/quiz/locallib.php');
// No restrictions on override events.
if (quiz_is_overriden_calendar_event($event)) {
return [null, null];
}
if (!$quiz) {
$quiz = $DB->get_record('quiz', ['id' => $event->instance]);
}
$mindate = null;
$maxdate = null;
if ($event->eventtype == QUIZ_EVENT_TYPE_OPEN) {
if (!empty($quiz->timeclose)) {
$maxdate = [
$quiz->timeclose,
get_string('openafterclose', 'quiz')
];
}
} else if ($event->eventtype == QUIZ_EVENT_TYPE_CLOSE) {
if (!empty($quiz->timeopen)) {
$mindate = [
$quiz->timeopen,
get_string('closebeforeopen', 'quiz')
];
}
}
return [$mindate, $maxdate];
}
/**
* This function will check that the given event is valid for it's
* corresponding quiz module.
*
* An exception is thrown if the event fails validation.
*
* @throws \moodle_exception
* @param \calendar_event $event
* @return bool
*/
function mod_quiz_core_calendar_validate_event_timestart(\calendar_event $event) {
global $DB;
if (!isset($event->instance)) {
return;
}
// Something weird going on. The event is for a different module so
// we should ignore it.
if ($event->modulename != 'quiz') {
return;
}
// We need to read from the DB directly because course module may
// currently be getting created so it won't be in mod info yet.
$quiz = $DB->get_record('quiz', ['id' => $event->instance], '*', MUST_EXIST);
$timestart = $event->timestart;
list($min, $max) = mod_quiz_core_calendar_get_valid_event_timestart_range($event, $quiz);
if ($min && $timestart < $min[0]) {
throw new \moodle_exception($min[1]);
}
if ($max && $timestart > $max[0]) {
throw new \moodle_exception($max[1]);
}
}
/**
* This function will update the quiz module according to the
* event that has been modified.
*
* It will set the timeopen or timeclose value of the quiz instance
* according to the type of event provided.
*
* @throws \moodle_exception
* @param \calendar_event $event
*/
function mod_quiz_core_calendar_event_timestart_updated(\calendar_event $event) {
global $CFG, $DB;
require_once($CFG->dirroot . '/mod/quiz/locallib.php');
// We don't update the activity if it's an override event that has
// been modified.
if (quiz_is_overriden_calendar_event($event)) {
return;
}
$courseid = $event->courseid;
$modulename = $event->modulename;
$instanceid = $event->instance;
$modified = false;
$closedatechanged = false;
// Something weird going on. The event is for a different module so
// we should ignore it.
if ($modulename != 'quiz') {
return;
}
$coursemodule = get_fast_modinfo($courseid)->instances[$modulename][$instanceid];
$context = context_module::instance($coursemodule->id);
// The user does not have the capability to modify this activity.
if (!has_capability('moodle/course:manageactivities', $context)) {
return;
}
if ($event->eventtype == QUIZ_EVENT_TYPE_OPEN) {
// If the event is for the quiz activity opening then we should
// set the start time of the quiz activity to be the new start
// time of the event.
$quiz = $DB->get_record('quiz', ['id' => $instanceid], '*', MUST_EXIST);
if ($quiz->timeopen != $event->timestart) {
$quiz->timeopen = $event->timestart;
$modified = true;
}
} else if ($event->eventtype == QUIZ_EVENT_TYPE_CLOSE) {
// If the event is for the quiz activity closing then we should
// set the end time of the quiz activity to be the new start
// time of the event.
$quiz = $DB->get_record('quiz', ['id' => $instanceid], '*', MUST_EXIST);
if ($quiz->timeclose != $event->timestart) {
$quiz->timeclose = $event->timestart;
$modified = true;
$closedatechanged = true;
}
}
if ($modified) {
$quiz->timemodified = time();
$DB->update_record('quiz', $quiz);
if ($closedatechanged) {
quiz_update_open_attempts(array('quizid' => $quiz->id));
}
// Delete any previous preview attempts.
quiz_delete_previews($quiz);
quiz_update_events($quiz);
$event = \core\event\course_module_updated::create_from_cm($coursemodule, $context);
$event->trigger();
}
}
View
@@ -2316,3 +2316,42 @@ function quiz_prepare_and_start_new_attempt(quiz $quizobj, $attemptnumber, $last
return $attempt;
}
/**
* Check if the given calendar_event is either a user or group override
* event for quiz.
*
* @param calendar_event $event The calendar event to check
* @return bool
*/
function quiz_is_overriden_calendar_event(\calendar_event $event) {
global $DB;
if (!isset($event->modulename)) {
return false;
}
if ($event->modulename != 'quiz') {
return false;
}
if (!isset($event->instance)) {
return false;
}
if (!isset($event->userid) && !isset($event->groupid)) {
return false;
}
$overrideparams = [
'quiz' => $event->instance
];
if (isset($event->groupid)) {
$overrideparams['groupid'] = $event->groupid;
} else if (isset($event->userid)) {
$overrideparams['userid'] = $event->userid;
}
return $DB->record_exists('quiz_overrides', $overrideparams);
}
Oops, something went wrong.

0 comments on commit 9aac9f7

Please sign in to comment.