MDL-60062 calendar: remove validate_event_timestart callback

This commit is contained in:
Ryan Wyllie 2017-10-30 08:15:10 +00:00
parent 9aac9f7074
commit 478b1d194f
12 changed files with 459 additions and 1062 deletions

View file

@ -213,14 +213,19 @@ class calendar_event_exporter extends event_exporter_base {
* @return array
*/
protected function get_module_timestamp_limits($event) {
global $DB;
$values = [];
$mapper = container::get_event_mapper();
$starttime = $event->get_times()->get_start_time();
$modname = $event->get_course_module()->get('modname');
$modid = $event->get_course_module()->get('instance');
$moduleinstance = $DB->get_record($modname, ['id' => $modid]);
list($min, $max) = component_callback(
'mod_' . $event->get_course_module()->get('modname'),
'mod_' . $modname,
'core_calendar_get_valid_event_timestart_range',
[$mapper->from_event_to_legacy_event($event)],
[$mapper->from_event_to_legacy_event($event), $moduleinstance],
[null, null]
);

View file

@ -231,9 +231,12 @@ class api {
event_interface $event,
\DateTimeInterface $startdate
) {
global $DB;
$mapper = container::get_event_mapper();
$legacyevent = $mapper->from_event_to_legacy_event($event);
$hascoursemodule = !empty($event->get_course_module());
$moduleinstance = null;
$starttime = $event->get_times()->get_start_time()->setDate(
$startdate->format('Y'),
$startdate->format('n'),
@ -241,15 +244,32 @@ class api {
);
if ($hascoursemodule) {
$legacyevent->timestart = $starttime->getTimestamp();
// If this event is from an activity then we need to call
// the activity callback to let it validate that the changes
// to the event are correct.
component_callback(
'mod_' . $event->get_course_module()->get('modname'),
'core_calendar_validate_event_timestart',
[$legacyevent]
$moduleinstance = $DB->get_record(
$event->get_course_module()->get('modname'),
['id' => $event->get_course_module()->get('instance')],
'*',
MUST_EXIST
);
$legacyevent->timestart = $starttime->getTimestamp();
// If there is a timestart range callback implemented then we can
// use the values returned from the valid timestart range to apply
// some default validation on the event's timestart value to ensure
// that it falls within the specified range.
list($min, $max) = component_callback(
'mod_' . $event->get_course_module()->get('modname'),
'core_calendar_get_valid_event_timestart_range',
[$legacyevent, $moduleinstance],
[null, null]
);
if ($min && $legacyevent->timestart < $min[0]) {
throw new \moodle_exception($min[1]);
}
if ($max && $legacyevent->timestart > $max[0]) {
throw new \moodle_exception($max[1]);
}
}
// This function does our capability checks.
@ -262,7 +282,7 @@ class api {
// We don't want to call the event update callback if the user isn't allowed
// to modify course modules because depending on the callback it can make
// some changes that would be considered security issues, such as updating the
// due date for and assignment.
// due date for an assignment.
if ($hascoursemodule && calendar_edit_event_allowed($legacyevent, true)) {
// If this event is from an activity then we need to call
// the activity callback to let it know that the event it
@ -270,7 +290,7 @@ class api {
component_callback(
'mod_' . $event->get_course_module()->get('modname'),
'core_calendar_event_timestart_updated',
[$legacyevent]
[$legacyevent, $moduleinstance]
);
}

View file

@ -44,6 +44,37 @@ class core_calendar_local_api_testcase extends advanced_testcase {
$this->resetAfterTest();
}
/**
* Create a feedback activity instance and a calendar event for
* that instance.
*
* @param array $feedbackproperties Properties to set on the feedback activity
* @param array $eventproperties Properties to set on the calendar event
* @return array The feedback activity and the calendar event
*/
protected function create_feedback_activity_and_event(array $feedbackproperties = [], array $eventproperties = []) {
$generator = $this->getDataGenerator();
$course = $generator->create_course();
$mapper = container::get_event_mapper();
$feedbackgenerator = $generator->get_plugin_generator('mod_feedback');
$feedback = $feedbackgenerator->create_instance(array_merge(
['course' => $course->id],
$feedbackproperties
));
$event = create_event(array_merge(
[
'courseid' => $course->id,
'modulename' => 'feedback',
'instance' => $feedback->id
],
$eventproperties
));
$event = $mapper->from_legacy_event_to_event($event);
return [$feedback, $event];
}
/**
* Requesting calendar events from a given time should return all events with a sort
* time at or after the requested time. All events prior to that time should not
@ -928,4 +959,284 @@ class core_calendar_local_api_testcase extends advanced_testcase {
$this->expectException('moodle_exception');
$newEvent = \core_calendar\local\api::update_event_start_day($event, $newstartdate);
}
/**
* Updating the start day of an event with no maximum cutoff should
* update the corresponding activity property.
*
* Note: This test uses the feedback activity because it requires
* module callbacks to be in place to test.
*/
public function test_update_event_start_day_activity_event_no_max() {
global $CFG, $DB;
require_once($CFG->dirroot . '/mod/feedback/lib.php');
$this->resetAfterTest(true);
$this->setAdminUser();
$timeopen = new DateTimeImmutable('2017-01-1T15:00:00+08:00');
$newstartdate = new DateTimeImmutable('2018-02-2T10:00:00+08:00');
$expected = new DateTimeImmutable('2018-02-2T15:00:00+08:00');
list($feedback, $event) = $this->create_feedback_activity_and_event(
[
'timeopen' => $timeopen->getTimestamp(),
'timeclose' => 0
],
[
'eventtype' => FEEDBACK_EVENT_TYPE_OPEN,
'timestart' => $timeopen->getTimestamp()
]
);
$newevent = \core_calendar\local\api::update_event_start_day($event, $newstartdate);
$actual = $newevent->get_times()->get_start_time();
$feedback = $DB->get_record('feedback', ['id' => $feedback->id]);
$this->assertEquals($expected->getTimestamp(), $actual->getTimestamp());
$this->assertEquals($expected->getTimestamp(), $feedback->timeopen);
}
/**
* Updating the start day of an event belonging to an activity to a value
* less than the maximum cutoff should update the corresponding activity
* property.
*
* Note: This test uses the feedback activity because it requires
* module callbacks to be in place to test.
*/
public function test_update_event_start_day_activity_event_less_than_max() {
global $CFG, $DB;
require_once($CFG->dirroot . '/mod/feedback/lib.php');
$this->resetAfterTest(true);
$this->setAdminUser();
$timeopen = new DateTimeImmutable('2017-01-1T15:00:00+08:00');
$timeclose = new DateTimeImmutable('2019-01-1T15:00:00+08:00');
$newstartdate = new DateTimeImmutable('2018-02-2T10:00:00+08:00');
$expected = new DateTimeImmutable('2018-02-2T15:00:00+08:00');
list($feedback, $event) = $this->create_feedback_activity_and_event(
[
'timeopen' => $timeopen->getTimestamp(),
'timeclose' => $timeclose->getTimestamp()
],
[
'eventtype' => FEEDBACK_EVENT_TYPE_OPEN,
'timestart' => $timeopen->getTimestamp()
]
);
$newevent = \core_calendar\local\api::update_event_start_day($event, $newstartdate);
$actual = $newevent->get_times()->get_start_time();
$feedback = $DB->get_record('feedback', ['id' => $feedback->id]);
$this->assertEquals($expected->getTimestamp(), $actual->getTimestamp());
$this->assertEquals($expected->getTimestamp(), $feedback->timeopen);
}
/**
* Updating the start day of an event belonging to an activity to a value
* equal to the maximum cutoff should update the corresponding activity
* property.
*
* Note: This test uses the feedback activity because it requires
* module callbacks to be in place to test.
*/
public function test_update_event_start_day_activity_event_equal_to_max() {
global $CFG, $DB;
require_once($CFG->dirroot . '/mod/feedback/lib.php');
$this->resetAfterTest(true);
$this->setAdminUser();
$timeopen = new DateTimeImmutable('2017-01-1T15:00:00+08:00');
$timeclose = new DateTimeImmutable('2018-02-2T15:00:00+08:00');
$newstartdate = new DateTimeImmutable('2018-02-2T10:00:00+08:00');
list($feedback, $event) = $this->create_feedback_activity_and_event(
[
'timeopen' => $timeopen->getTimestamp(),
'timeclose' => $timeclose->getTimestamp(),
],
[
'eventtype' => FEEDBACK_EVENT_TYPE_OPEN,
'timestart' => $timeopen->getTimestamp()
]
);
$newevent = \core_calendar\local\api::update_event_start_day($event, $newstartdate);
$actual = $newevent->get_times()->get_start_time();
$feedback = $DB->get_record('feedback', ['id' => $feedback->id]);
$this->assertEquals($timeclose->getTimestamp(), $actual->getTimestamp());
$this->assertEquals($timeclose->getTimestamp(), $feedback->timeopen);
}
/**
* Updating the start day of an event belonging to an activity to a value
* after the maximum cutoff should not update the corresponding activity
* property. Instead it should throw an exception.
*
* Note: This test uses the feedback activity because it requires
* module callbacks to be in place to test.
*/
public function test_update_event_start_day_activity_event_after_max() {
global $CFG, $DB;
require_once($CFG->dirroot . '/mod/feedback/lib.php');
$this->resetAfterTest(true);
$this->setAdminUser();
$timeopen = new DateTimeImmutable('2017-01-1T15:00:00+08:00');
$timeclose = new DateTimeImmutable('2017-02-2T15:00:00+08:00');
$newstartdate = new DateTimeImmutable('2018-02-2T10:00:00+08:00');
list($feedback, $event) = $this->create_feedback_activity_and_event(
[
'timeopen' => $timeopen->getTimestamp(),
'timeclose' => $timeclose->getTimestamp(),
],
[
'eventtype' => FEEDBACK_EVENT_TYPE_OPEN,
'timestart' => $timeopen->getTimestamp()
]
);
$this->expectException('moodle_exception');
$newevent = \core_calendar\local\api::update_event_start_day($event, $newstartdate);
}
/**
* Updating the start day of an event with no minimum cutoff should
* update the corresponding activity property.
*
* Note: This test uses the feedback activity because it requires
* module callbacks to be in place to test.
*/
public function test_update_event_start_day_activity_event_no_min() {
global $CFG, $DB;
require_once($CFG->dirroot . '/mod/feedback/lib.php');
$this->resetAfterTest(true);
$this->setAdminUser();
$timeclose = new DateTimeImmutable('2017-01-1T15:00:00+08:00');
$newstartdate = new DateTimeImmutable('2016-02-2T10:00:00+08:00');
$expected = new DateTimeImmutable('2016-02-2T15:00:00+08:00');
list($feedback, $event) = $this->create_feedback_activity_and_event(
[
'timeopen' => 0,
'timeclose' => $timeclose->getTimestamp()
],
[
'eventtype' => FEEDBACK_EVENT_TYPE_OPEN,
'timestart' => $timeclose->getTimestamp()
]
);
$newevent = \core_calendar\local\api::update_event_start_day($event, $newstartdate);
$actual = $newevent->get_times()->get_start_time();
$feedback = $DB->get_record('feedback', ['id' => $feedback->id]);
$this->assertEquals($expected->getTimestamp(), $actual->getTimestamp());
$this->assertEquals($expected->getTimestamp(), $feedback->timeopen);
}
/**
* Updating the start day of an event belonging to an activity to a value
* greater than the minimum cutoff should update the corresponding activity
* property.
*
* Note: This test uses the feedback activity because it requires
* module callbacks to be in place to test.
*/
public function test_update_event_start_day_activity_event_greater_than_min() {
global $CFG, $DB;
require_once($CFG->dirroot . '/mod/feedback/lib.php');
$this->resetAfterTest(true);
$this->setAdminUser();
$timeopen = new DateTimeImmutable('2016-01-1T15:00:00+08:00');
$timeclose = new DateTimeImmutable('2019-01-1T15:00:00+08:00');
$newstartdate = new DateTimeImmutable('2018-02-2T10:00:00+08:00');
$expected = new DateTimeImmutable('2018-02-2T15:00:00+08:00');
list($feedback, $event) = $this->create_feedback_activity_and_event(
[
'timeopen' => $timeopen->getTimestamp(),
'timeclose' => $timeclose->getTimestamp()
],
[
'eventtype' => FEEDBACK_EVENT_TYPE_CLOSE,
'timestart' => $timeclose->getTimestamp()
]
);
$newevent = \core_calendar\local\api::update_event_start_day($event, $newstartdate);
$actual = $newevent->get_times()->get_start_time();
$feedback = $DB->get_record('feedback', ['id' => $feedback->id]);
$this->assertEquals($expected->getTimestamp(), $actual->getTimestamp());
$this->assertEquals($expected->getTimestamp(), $feedback->timeclose);
}
/**
* Updating the start day of an event belonging to an activity to a value
* equal to the minimum cutoff should update the corresponding activity
* property.
*
* Note: This test uses the feedback activity because it requires
* module callbacks to be in place to test.
*/
public function test_update_event_start_day_activity_event_equal_to_min() {
global $CFG, $DB;
require_once($CFG->dirroot . '/mod/feedback/lib.php');
$this->resetAfterTest(true);
$this->setAdminUser();
$timeopen = new DateTimeImmutable('2017-01-1T15:00:00+08:00');
$timeclose = new DateTimeImmutable('2018-02-2T15:00:00+08:00');
$newstartdate = new DateTimeImmutable('2017-01-1T10:00:00+08:00');
$expected = new DateTimeImmutable('2017-01-1T15:00:00+08:00');
list($feedback, $event) = $this->create_feedback_activity_and_event(
[
'timeopen' => $timeopen->getTimestamp(),
'timeclose' => $timeclose->getTimestamp(),
],
[
'eventtype' => FEEDBACK_EVENT_TYPE_CLOSE,
'timestart' => $timeclose->getTimestamp()
]
);
$newevent = \core_calendar\local\api::update_event_start_day($event, $newstartdate);
$actual = $newevent->get_times()->get_start_time();
$feedback = $DB->get_record('feedback', ['id' => $feedback->id]);
$this->assertEquals($expected->getTimestamp(), $actual->getTimestamp());
$this->assertEquals($expected->getTimestamp(), $feedback->timeclose);
}
/**
* Updating the start day of an event belonging to an activity to a value
* before the minimum cutoff should not update the corresponding activity
* property. Instead it should throw an exception.
*
* Note: This test uses the feedback activity because it requires
* module callbacks to be in place to test.
*/
public function test_update_event_start_day_activity_event_before_min() {
global $CFG, $DB;
require_once($CFG->dirroot . '/mod/feedback/lib.php');
$this->resetAfterTest(true);
$this->setAdminUser();
$timeopen = new DateTimeImmutable('2017-01-1T15:00:00+08:00');
$timeclose = new DateTimeImmutable('2017-02-2T15:00:00+08:00');
$newstartdate = new DateTimeImmutable('2016-02-2T10:00:00+08:00');
list($feedback, $event) = $this->create_feedback_activity_and_event(
[
'timeopen' => $timeopen->getTimestamp(),
'timeclose' => $timeclose->getTimestamp(),
],
[
'eventtype' => FEEDBACK_EVENT_TYPE_CLOSE,
'timestart' => $timeclose->getTimestamp()
]
);
$this->expectException('moodle_exception');
$newevent = \core_calendar\local\api::update_event_start_day($event, $newstartdate);
}
}

View file

@ -4,7 +4,7 @@ information provided here is intended especially for developers.
=== 3.4 ===
* calendar_get_mini has been deprecated. Please update to use the new
exporters and renderers.
* added core_calendar_validate_event_timestart and core_calendar_event_timestart_updated callbacks for module events
* added core_calendar_get_valid_event_timestart_range and core_calendar_event_timestart_updated callbacks for module events
when the update_event_start_day function is used in the local api.
=== 3.3 ===