Merge branch 'MDL-62960-35' of git://github.com/rezaies/moodle into MOODLE_35_STABLE

This commit is contained in:
Damyon Wiese
2018-10-16 11:43:53 +08:00
6 changed files with 196 additions and 30 deletions
+74 -7
View File
@@ -176,6 +176,9 @@ class calendar_event_exporter extends event_exporter_base {
if ($event->get_course_module()) {
$values = array_merge($values, $this->get_module_timestamp_limits($event));
} else if ($hascourse && $course->id != SITEID && empty($event->get_group())) {
// This is a course event.
$values = array_merge($values, $this->get_course_timestamp_limits($event));
}
return $values;
@@ -210,6 +213,44 @@ class calendar_event_exporter extends event_exporter_base {
return $this->event->get_type();
}
/**
* Return the set of minimum and maximum date timestamp values
* for the given event.
*
* @param event_interface $event
* @return array
*/
protected function get_course_timestamp_limits($event) {
$values = [];
$mapper = container::get_event_mapper();
$starttime = $event->get_times()->get_start_time();
list($min, $max) = component_callback(
'core_course',
'core_calendar_get_valid_event_timestart_range',
[$mapper->from_event_to_legacy_event($event), $event->get_course()->get_proxied_instance()],
[false, false]
);
// The callback will return false for either of the
// min or max cutoffs to indicate that there are no
// valid timestart values. In which case the event is
// not draggable.
if ($min === false || $max === false) {
return ['draggable' => false];
}
if ($min) {
$values = array_merge($values, $this->get_timestamp_min_limit($starttime, $min));
}
if ($max) {
$values = array_merge($values, $this->get_timestamp_max_limit($starttime, $max));
}
return $values;
}
/**
* Return the set of minimum and maximum date timestamp values
* for the given event.
@@ -240,11 +281,11 @@ class calendar_event_exporter extends event_exporter_base {
}
if ($min) {
$values = array_merge($values, $this->get_module_timestamp_min_limit($starttime, $min));
$values = array_merge($values, $this->get_timestamp_min_limit($starttime, $min));
}
if ($max) {
$values = array_merge($values, $this->get_module_timestamp_max_limit($starttime, $max));
$values = array_merge($values, $this->get_timestamp_max_limit($starttime, $max));
}
return $values;
@@ -252,12 +293,13 @@ class calendar_event_exporter extends event_exporter_base {
/**
* Get the correct minimum midnight day limit based on the event start time
* and the module's minimum timestamp limit.
* and the minimum timestamp limit of what the event belongs to.
*
* @param DateTimeInterface $starttime The event start time
* @param array $min The module's minimum limit for the event
* @return array Returns an array with mindaytimestamp and mindayerror keys.
*/
protected function get_module_timestamp_min_limit(\DateTimeInterface $starttime, $min) {
protected function get_timestamp_min_limit(\DateTimeInterface $starttime, $min) {
// We need to check that the minimum valid time is earlier in the
// day than the current event time so that if the user drags and drops
// the event to this day (which changes the date but not the time) it
@@ -295,15 +337,16 @@ class calendar_event_exporter extends event_exporter_base {
/**
* Get the correct maximum midnight day limit based on the event start time
* and the module's maximum timestamp limit.
* and the maximum timestamp limit of what the event belongs to.
*
* @param DateTimeInterface $starttime The event start time
* @param array $max The module's maximum limit for the event
* @return array Returns an array with maxdaytimestamp and maxdayerror keys.
*/
protected function get_module_timestamp_max_limit(\DateTimeInterface $starttime, $max) {
protected function get_timestamp_max_limit(\DateTimeInterface $starttime, $max) {
// We're doing a similar calculation here as we are for the minimum
// day timestamp. See the explanation above.
$values;
$values = [];
$timestamp = $max[0];
$errorstring = $max[1];
$maxdate = (new \DateTimeImmutable())->setTimestamp($timestamp);
@@ -326,4 +369,28 @@ class calendar_event_exporter extends event_exporter_base {
$values['maxdayerror'] = $errorstring;
return $values;
}
/**
* Get the correct minimum midnight day limit based on the event start time
* and the module's minimum timestamp limit.
*
* @param DateTimeInterface $starttime The event start time
* @param array $min The module's minimum limit for the event
* @return array Returns an array with mindaytimestamp and mindayerror keys.
*/
protected function get_module_timestamp_min_limit(\DateTimeInterface $starttime, $min) {
return $this->get_timestamp_min_limit($starttime, $min);
}
/**
* Get the correct maximum midnight day limit based on the event start time
* and the module's maximum timestamp limit.
*
* @param DateTimeInterface $starttime The event start time
* @param array $max The module's maximum limit for the event
* @return array Returns an array with maxdaytimestamp and maxdayerror keys.
*/
protected function get_module_timestamp_max_limit(\DateTimeInterface $starttime, $max) {
return $this->get_timestamp_max_limit($starttime, $max);
}
}
+22 -12
View File
@@ -242,6 +242,7 @@ class api {
$startdate->format('n'),
$startdate->format('j')
);
$starttimestamp = $starttime->getTimestamp();
if ($hascoursemodule) {
$moduleinstance = $DB->get_record(
@@ -250,7 +251,6 @@ class api {
'*',
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
@@ -262,20 +262,30 @@ class api {
[$legacyevent, $moduleinstance],
[false, false]
);
} else if ($legacyevent->courseid != 0 && $legacyevent->courseid != SITEID && $legacyevent->groupid == 0) {
// This is a course event.
list($min, $max) = component_callback(
'core_course',
'core_calendar_get_valid_event_timestart_range',
[$legacyevent, $event->get_course()->get_proxied_instance()],
[0, 0]
);
} else {
$min = $max = 0;
}
// If the callback returns false for either value it means that
// there is no valid time start range.
if ($min === false || $max === false) {
throw new \moodle_exception('The start day of this event can not be modified');
}
// If the callback returns false for either value it means that
// there is no valid time start range.
if ($min === false || $max === false) {
throw new \moodle_exception('The start day of this event can not be modified');
}
if ($min && $legacyevent->timestart < $min[0]) {
throw new \moodle_exception($min[1]);
}
if ($min && $starttimestamp < $min[0]) {
throw new \moodle_exception($min[1]);
}
if ($max && $legacyevent->timestart > $max[0]) {
throw new \moodle_exception($max[1]);
}
if ($max && $starttimestamp > $max[0]) {
throw new \moodle_exception($max[1]);
}
// This function does our capability checks.
+11 -11
View File
@@ -38,10 +38,10 @@ require_once(__DIR__ . '/helpers.php');
*/
class core_calendar_event_exporter_testcase extends advanced_testcase {
/**
* Data provider for the module timestamp min limit test case to confirm
* Data provider for the timestamp min limit test case to confirm
* that the minimum time limit is set correctly on the boundary cases.
*/
public function get_module_timestamp_min_limit_test_cases() {
public function get_timestamp_min_limit_test_cases() {
$now = time();
$todaymidnight = usergetmidnight($now);
$tomorrowmidnight = $todaymidnight + DAYSECS;
@@ -77,16 +77,16 @@ class core_calendar_event_exporter_testcase extends advanced_testcase {
}
/**
* @dataProvider get_module_timestamp_min_limit_test_cases()
* @dataProvider get_timestamp_min_limit_test_cases()
*/
public function test_get_module_timestamp_min_limit($starttime, $min, $expected) {
public function test_get_timestamp_min_limit($starttime, $min, $expected) {
$class = \core_calendar\external\calendar_event_exporter::class;
$mock = $this->getMockBuilder($class)
->disableOriginalConstructor()
->setMethods(null)
->getMock();
$reflector = new ReflectionClass($class);
$method = $reflector->getMethod('get_module_timestamp_min_limit');
$method = $reflector->getMethod('get_timestamp_min_limit');
$method->setAccessible(true);
$result = $method->invoke($mock, $starttime, $min);
@@ -95,10 +95,10 @@ class core_calendar_event_exporter_testcase extends advanced_testcase {
}
/**
* Data provider for the module timestamp min limit test case to confirm
* that the minimum time limit is set correctly on the boundary cases.
* Data provider for the timestamp max limit test case to confirm
* that the maximum time limit is set correctly on the boundary cases.
*/
public function get_module_timestamp_max_limit_test_cases() {
public function get_timestamp_max_limit_test_cases() {
$now = time();
$todaymidnight = usergetmidnight($now);
$yesterdaymidnight = $todaymidnight - DAYSECS;
@@ -134,16 +134,16 @@ class core_calendar_event_exporter_testcase extends advanced_testcase {
}
/**
* @dataProvider get_module_timestamp_max_limit_test_cases()
* @dataProvider get_timestamp_max_limit_test_cases()
*/
public function test_get_module_timestamp_max_limit($starttime, $max, $expected) {
public function test_get_timestamp_max_limit($starttime, $max, $expected) {
$class = \core_calendar\external\calendar_event_exporter::class;
$mock = $this->getMockBuilder($class)
->disableOriginalConstructor()
->setMethods(null)
->getMock();
$reflector = new ReflectionClass($class);
$method = $reflector->getMethod('get_module_timestamp_max_limit');
$method = $reflector->getMethod('get_timestamp_max_limit');
$method->setAccessible(true);
$result = $method->invoke($mock, $starttime, $max);
+4
View File
@@ -1,6 +1,10 @@
This files describes API changes in /calendar/* ,
information provided here is intended especially for developers.
=== 3.5.3 ===
* added core_calendar_get_valid_event_timestart_range callback for course events when the update_event_start_day function is used
in the local api.
=== 3.5.2 ===
* calendar_get_default_courses() function now has optional $userid parameter.
* calendar_set_filters() function now has optional $user parameter.
+35
View File
@@ -3756,6 +3756,41 @@ function core_course_inplace_editable($itemtype, $itemid, $newvalue) {
}
}
/**
* This function calculates the minimum and maximum cutoff values for the timestart of
* the given event.
*
* It will return an array with two values, the first being the minimum cutoff value and
* the second being the maximum cutoff value. Either or both values can be null, which
* indicates there is no minimum or maximum, respectively.
*
* If a cutoff is required then the function must return an array containing the cutoff
* timestamp and error string to display to the user if the cutoff value is violated.
*
* 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 $course The course object to get the range from
* @return array Returns an array with min and max date.
*/
function core_course_core_calendar_get_valid_event_timestart_range(\calendar_event $event, $course) {
$mindate = null;
$maxdate = null;
if ($course->startdate) {
$mindate = [
$course->startdate,
get_string('errorbeforecoursestart', 'calendar')
];
}
return [$mindate, $maxdate];
}
/**
* Returns course modules tagged with a specified tag ready for output on tag/index.php page
*
+50
View File
@@ -4182,4 +4182,54 @@ class core_course_courselib_testcase extends advanced_testcase {
assign_capability('moodle/backup:downloadfile', CAP_ALLOW, $teacherrole->id, $context);
$this->assertFalse(can_download_from_backup_filearea('testing', $context, $user));
}
/**
* Testing core_course_core_calendar_get_valid_event_timestart_range when the course has no end date.
*/
public function test_core_course_core_calendar_get_valid_event_timestart_range_no_enddate() {
global $CFG;
require_once($CFG->dirroot . "/calendar/lib.php");
$this->resetAfterTest(true);
$this->setAdminUser();
$generator = $this->getDataGenerator();
$now = time();
$course = $generator->create_course(['startdate' => $now - 86400]);
// Create a course event.
$event = new \calendar_event([
'name' => 'Test course event',
'eventtype' => 'course',
'courseid' => $course->id,
]);
list ($min, $max) = core_course_core_calendar_get_valid_event_timestart_range($event, $course);
$this->assertEquals($course->startdate, $min[0]);
$this->assertNull($max);
}
/**
* Testing core_course_core_calendar_get_valid_event_timestart_range when the course has end date.
*/
public function test_core_course_core_calendar_get_valid_event_timestart_range_with_enddate() {
global $CFG;
require_once($CFG->dirroot . "/calendar/lib.php");
$this->resetAfterTest(true);
$this->setAdminUser();
$generator = $this->getDataGenerator();
$now = time();
$course = $generator->create_course(['startdate' => $now - 86400, 'enddate' => $now + 86400]);
// Create a course event.
$event = new \calendar_event([
'name' => 'Test course event',
'eventtype' => 'course',
'courseid' => $course->id,
]);
list ($min, $max) = core_course_core_calendar_get_valid_event_timestart_range($event, $course);
$this->assertEquals($course->startdate, $min[0]);
$this->assertNull($max);
}
}