예제 #1
0
 /**
  * Test recurrence rules for yearly frequency.
  */
 public function test_yearly_events()
 {
     global $DB;
     $rrule = 'FREQ=YEARLY;COUNT=3;BYMONTH=12';
     // This should generate 3 events in total.
     $mang = new \core_calendar\rrule_manager($rrule);
     $mang->parse_rrule();
     $mang->create_events($this->event);
     $count = $DB->count_records('event', array('repeatid' => $this->event->id));
     $this->assertEquals(3, $count);
     for ($i = 0, $time = $this->event->timestart; $i < 3; $i++, $time = strtotime("+{$i} years", $this->event->timestart)) {
         $result = $DB->record_exists('event', array('repeatid' => $this->event->id, 'timestart' => $time));
         $this->assertTrue($result);
     }
     // Create an event every december, until the time limit is hit.
     $until = strtotime('+20 day +10 years', $this->event->timestart);
     $until = date('YmdTHis', $until);
     $rrule = "FREQ=YEARLY;BYMONTH=12;UNTIL={$until}";
     // Forever event.
     $mang = new \core_calendar\rrule_manager($rrule);
     $until = time() + YEARSECS * $mang::TIME_UNLIMITED_YEARS;
     $mang->parse_rrule();
     $mang->create_events($this->event);
     $count = $DB->count_records('event', array('repeatid' => $this->event->id));
     $this->assertEquals(11, $count);
     for ($i = 0, $time = $this->event->timestart; $time < $until; $i++, $yoffset = $i * 2, $time = strtotime("+{$yoffset} years", $this->event->timestart)) {
         $result = $DB->record_exists('event', array('repeatid' => $this->event->id, 'timestart' => $time));
         $this->assertTrue($result);
     }
     // This should generate 5 events in total, every second year in the month of december.
     $rrule = 'FREQ=YEARLY;BYMONTH=12;INTERVAL=2;COUNT=5';
     $mang = new \core_calendar\rrule_manager($rrule);
     $mang->parse_rrule();
     $mang->create_events($this->event);
     $count = $DB->count_records('event', array('repeatid' => $this->event->id));
     $this->assertEquals(5, $count);
     for ($i = 0, $time = $this->event->timestart; $i < 5; $i++, $yoffset = $i * 2, $time = strtotime("+{$yoffset} years", $this->event->timestart)) {
         $result = $DB->record_exists('event', array('repeatid' => $this->event->id, 'timestart' => $time));
         $this->assertTrue($result);
     }
     $rrule = 'FREQ=YEARLY;BYMONTH=12;INTERVAL=2';
     // Forever event.
     $mang = new \core_calendar\rrule_manager($rrule);
     $until = time() + YEARSECS * $mang::TIME_UNLIMITED_YEARS;
     $mang->parse_rrule();
     $mang->create_events($this->event);
     $count = $DB->count_records('event', array('repeatid' => $this->event->id));
     $this->assertEquals(6, $count);
     for ($i = 0, $time = $this->event->timestart; $time < $until; $i++, $yoffset = $i * 2, $time = strtotime("+{$yoffset} years", $this->event->timestart)) {
         $result = $DB->record_exists('event', array('repeatid' => $this->event->id, 'timestart' => $time));
         $this->assertTrue($result);
     }
     // This much seconds after the start of the day.
     $offset = $this->event->timestart - mktime(0, 0, 0, date("n", $this->event->timestart), date("j", $this->event->timestart), date("Y", $this->event->timestart));
     $yearstart = mktime(0, 0, 0, 1, 1, date("Y", $this->event->timestart));
     $rrule = 'FREQ=YEARLY;COUNT=3;BYMONTH=12;BYDAY=1MO';
     // This should generate 3 events in total.
     $mang = new \core_calendar\rrule_manager($rrule);
     $mang->parse_rrule();
     $mang->create_events($this->event);
     $count = $DB->count_records('event', array('repeatid' => $this->event->id));
     $this->assertEquals(3, $count);
     for ($i = 0; $i < 3; $i++) {
         $time = strtotime("+11 months +{$i} years", $yearstart);
         $time = strtotime("+1 Monday", $time) + $offset;
         $result = $DB->record_exists('event', array('repeatid' => $this->event->id, 'timestart' => $time));
         $this->assertTrue($result);
     }
     // Create an event every december, until the time limit is hit.
     $until = strtotime('+20 day +10 years', $this->event->timestart);
     $until = date('YmdTHis', $until);
     $rrule = "FREQ=YEARLY;BYMONTH=12;UNTIL={$until};BYDAY=1MO";
     $mang = new \core_calendar\rrule_manager($rrule);
     $until = time() + YEARSECS * $mang::TIME_UNLIMITED_YEARS;
     $mang->parse_rrule();
     $mang->create_events($this->event);
     $count = $DB->count_records('event', array('repeatid' => $this->event->id));
     $this->assertEquals(11, $count);
     for ($i = 0, $time = $this->event->timestart; $time < $until; $i++) {
         $result = $DB->record_exists('event', array('repeatid' => $this->event->id, 'timestart' => $time));
         $this->assertTrue($result);
         $time = strtotime("+11 months +{$i} years", $yearstart);
         $time = strtotime("+1 Monday", $time) + $offset;
     }
     // This should generate 5 events in total, every second year in the month of december.
     $rrule = 'FREQ=YEARLY;BYMONTH=12;INTERVAL=2;COUNT=5;BYDAY=1MO';
     $mang = new \core_calendar\rrule_manager($rrule);
     $mang->parse_rrule();
     $mang->create_events($this->event);
     $count = $DB->count_records('event', array('repeatid' => $this->event->id));
     $this->assertEquals(5, $count);
     for ($i = $yoffset = 0, $time = $this->event->timestart; $i < 5; $i++, $yoffset = $i * 2) {
         $result = $DB->record_exists('event', array('repeatid' => $this->event->id, 'timestart' => $time));
         $this->assertTrue($result);
         $time = strtotime("+11 months +{$yoffset} years", $yearstart);
         $time = strtotime("+1 Monday", $time) + $offset;
     }
     $rrule = 'FREQ=YEARLY;BYMONTH=12;INTERVAL=2;BYDAY=1MO';
     // Forever event.
     $mang = new \core_calendar\rrule_manager($rrule);
     $until = time() + YEARSECS * $mang::TIME_UNLIMITED_YEARS;
     $mang->parse_rrule();
     $mang->create_events($this->event);
     $count = $DB->count_records('event', array('repeatid' => $this->event->id));
     $this->assertEquals(6, $count);
     for ($i = 0, $time = $this->event->timestart; $time < $until; $i++, $yoffset = $i * 2) {
         $result = $DB->record_exists('event', array('repeatid' => $this->event->id, 'timestart' => $time));
         $this->assertTrue($result);
         $time = strtotime("+11 months +{$yoffset} years", $yearstart);
         $time = strtotime("+1 Monday", $time) + $offset;
     }
     $rrule = 'FREQ=YEARLY;INTERVAL=2';
     // Forever event.
     $mang = new \core_calendar\rrule_manager($rrule);
     $until = time() + YEARSECS * $mang::TIME_UNLIMITED_YEARS;
     $mang->parse_rrule();
     $mang->create_events($this->event);
     $count = $DB->count_records('event', array('repeatid' => $this->event->id));
     $this->assertEquals(6, $count);
     for ($i = 0, $time = $this->event->timestart; $time < $until; $i++, $yoffset = $i * 2) {
         $result = $DB->record_exists('event', array('repeatid' => $this->event->id, 'timestart' => $time));
         $this->assertTrue($result);
         $time = strtotime("+11 months +{$yoffset} years", $yearstart);
         $time = strtotime("+1 Monday", $time) + $offset;
     }
 }
예제 #2
0
파일: lib.php 프로젝트: bewanyk/moodle
/**
 * Add an iCalendar event to the Moodle calendar.
 *
 * @param stdClass $event The RFC-2445 iCalendar event
 * @param int $courseid The course ID
 * @param int $subscriptionid The iCalendar subscription ID
 * @param string $timezone The X-WR-TIMEZONE iCalendar property if provided
 * @throws dml_exception A DML specific exception is thrown for invalid subscriptionids.
 * @return int Code: CALENDAR_IMPORT_EVENT_UPDATED = updated,  CALENDAR_IMPORT_EVENT_INSERTED = inserted, 0 = error
 */
function calendar_add_icalendar_event($event, $courseid, $subscriptionid, $timezone = 'UTC')
{
    global $DB;
    // Probably an unsupported X-MICROSOFT-CDO-BUSYSTATUS event.
    if (empty($event->properties['SUMMARY'])) {
        return 0;
    }
    $name = $event->properties['SUMMARY'][0]->value;
    $name = str_replace('\\n', '<br />', $name);
    $name = str_replace('\\', '', $name);
    $name = preg_replace('/\\s+/u', ' ', $name);
    $eventrecord = new stdClass();
    $eventrecord->name = clean_param($name, PARAM_NOTAGS);
    if (empty($event->properties['DESCRIPTION'][0]->value)) {
        $description = '';
    } else {
        $description = $event->properties['DESCRIPTION'][0]->value;
        $description = clean_param($description, PARAM_NOTAGS);
        $description = str_replace('\\n', '<br />', $description);
        $description = str_replace('\\', '', $description);
        $description = preg_replace('/\\s+/u', ' ', $description);
    }
    $eventrecord->description = $description;
    // Probably a repeating event with RRULE etc. TODO: skip for now.
    if (empty($event->properties['DTSTART'][0]->value)) {
        return 0;
    }
    $tz = isset($event->properties['DTSTART'][0]->parameters['TZID']) ? $event->properties['DTSTART'][0]->parameters['TZID'] : $timezone;
    $tz = core_date::normalise_timezone($tz);
    $eventrecord->timestart = strtotime($event->properties['DTSTART'][0]->value . ' ' . $tz);
    if (empty($event->properties['DTEND'])) {
        $eventrecord->timeduration = 0;
        // no duration if no end time specified
    } else {
        $endtz = isset($event->properties['DTEND'][0]->parameters['TZID']) ? $event->properties['DTEND'][0]->parameters['TZID'] : $timezone;
        $endtz = core_date::normalise_timezone($endtz);
        $eventrecord->timeduration = strtotime($event->properties['DTEND'][0]->value . ' ' . $endtz) - $eventrecord->timestart;
    }
    // Check to see if it should be treated as an all day event.
    if ($eventrecord->timeduration == DAYSECS) {
        // Check to see if the event started at Midnight on the imported calendar.
        date_default_timezone_set($timezone);
        if (date('H:i:s', $eventrecord->timestart) === "00:00:00") {
            // This event should be an all day event.
            $eventrecord->timeduration = 0;
        }
        core_date::set_default_server_timezone();
    }
    $eventrecord->uuid = $event->properties['UID'][0]->value;
    $eventrecord->timemodified = time();
    // Add the iCal subscription details if required.
    // We should never do anything with an event without a subscription reference.
    $sub = calendar_get_subscription($subscriptionid);
    $eventrecord->subscriptionid = $subscriptionid;
    $eventrecord->userid = $sub->userid;
    $eventrecord->groupid = $sub->groupid;
    $eventrecord->courseid = $sub->courseid;
    $eventrecord->eventtype = $sub->eventtype;
    if ($updaterecord = $DB->get_record('event', array('uuid' => $eventrecord->uuid))) {
        $eventrecord->id = $updaterecord->id;
        $return = CALENDAR_IMPORT_EVENT_UPDATED;
        // Update.
    } else {
        $return = CALENDAR_IMPORT_EVENT_INSERTED;
        // Insert.
    }
    if ($createdevent = calendar_event::create($eventrecord, false)) {
        if (!empty($event->properties['RRULE'])) {
            // Repeating events.
            date_default_timezone_set($tz);
            // Change time zone to parse all events.
            $rrule = new \core_calendar\rrule_manager($event->properties['RRULE'][0]->value);
            $rrule->parse_rrule();
            $rrule->create_events($createdevent);
            core_date::set_default_server_timezone();
            // Change time zone back to what it was.
        }
        return $return;
    } else {
        return 0;
    }
}