1<?php 2 3namespace Sabre\VObject\Component; 4 5use DateTimeInterface; 6use Sabre\VObject; 7use Sabre\VObject\Recur\EventIterator; 8use Sabre\VObject\Recur\NoInstancesException; 9 10/** 11 * VEvent component. 12 * 13 * This component contains some additional functionality specific for VEVENT's. 14 * 15 * @copyright Copyright (C) fruux GmbH (https://fruux.com/) 16 * @author Evert Pot (http://evertpot.com/) 17 * @license http://sabre.io/license/ Modified BSD License 18 */ 19class VEvent extends VObject\Component 20{ 21 /** 22 * Returns true or false depending on if the event falls in the specified 23 * time-range. This is used for filtering purposes. 24 * 25 * The rules used to determine if an event falls within the specified 26 * time-range is based on the CalDAV specification. 27 * 28 * @param DateTimeInterface $start 29 * @param DateTimeInterface $end 30 * 31 * @return bool 32 */ 33 public function isInTimeRange(DateTimeInterface $start, DateTimeInterface $end) 34 { 35 if ($this->RRULE) { 36 try { 37 $it = new EventIterator($this, null, $start->getTimezone()); 38 } catch (NoInstancesException $e) { 39 // If we've caught this exception, there are no instances 40 // for the event that fall into the specified time-range. 41 return false; 42 } 43 44 $it->fastForward($start); 45 46 // We fast-forwarded to a spot where the end-time of the 47 // recurrence instance exceeded the start of the requested 48 // time-range. 49 // 50 // If the starttime of the recurrence did not exceed the 51 // end of the time range as well, we have a match. 52 return $it->getDTStart() < $end && $it->getDTEnd() > $start; 53 } 54 55 $effectiveStart = $this->DTSTART->getDateTime($start->getTimezone()); 56 if (isset($this->DTEND)) { 57 // The DTEND property is considered non inclusive. So for a 3 day 58 // event in july, dtstart and dtend would have to be July 1st and 59 // July 4th respectively. 60 // 61 // See: 62 // http://tools.ietf.org/html/rfc5545#page-54 63 $effectiveEnd = $this->DTEND->getDateTime($end->getTimezone()); 64 } elseif (isset($this->DURATION)) { 65 $effectiveEnd = $effectiveStart->add(VObject\DateTimeParser::parseDuration($this->DURATION)); 66 } elseif (!$this->DTSTART->hasTime()) { 67 $effectiveEnd = $effectiveStart->modify('+1 day'); 68 } else { 69 $effectiveEnd = $effectiveStart; 70 } 71 72 return 73 ($start < $effectiveEnd) && ($end > $effectiveStart) 74 ; 75 } 76 77 /** 78 * This method should return a list of default property values. 79 * 80 * @return array 81 */ 82 protected function getDefaults() 83 { 84 return [ 85 'UID' => 'sabre-vobject-'.VObject\UUIDUtil::getUUID(), 86 'DTSTAMP' => gmdate('Ymd\\THis\\Z'), 87 ]; 88 } 89 90 /** 91 * A simple list of validation rules. 92 * 93 * This is simply a list of properties, and how many times they either 94 * must or must not appear. 95 * 96 * Possible values per property: 97 * * 0 - Must not appear. 98 * * 1 - Must appear exactly once. 99 * * + - Must appear at least once. 100 * * * - Can appear any number of times. 101 * * ? - May appear, but not more than once. 102 * 103 * @var array 104 */ 105 public function getValidationRules() 106 { 107 $hasMethod = isset($this->parent->METHOD); 108 109 return [ 110 'UID' => 1, 111 'DTSTAMP' => 1, 112 'DTSTART' => $hasMethod ? '?' : '1', 113 'CLASS' => '?', 114 'CREATED' => '?', 115 'DESCRIPTION' => '?', 116 'GEO' => '?', 117 'LAST-MODIFIED' => '?', 118 'LOCATION' => '?', 119 'ORGANIZER' => '?', 120 'PRIORITY' => '?', 121 'SEQUENCE' => '?', 122 'STATUS' => '?', 123 'SUMMARY' => '?', 124 'TRANSP' => '?', 125 'URL' => '?', 126 'RECURRENCE-ID' => '?', 127 'RRULE' => '?', 128 'DTEND' => '?', 129 'DURATION' => '?', 130 131 'ATTACH' => '*', 132 'ATTENDEE' => '*', 133 'CATEGORIES' => '*', 134 'COMMENT' => '*', 135 'CONTACT' => '*', 136 'EXDATE' => '*', 137 'REQUEST-STATUS' => '*', 138 'RELATED-TO' => '*', 139 'RESOURCES' => '*', 140 'RDATE' => '*', 141 ]; 142 } 143} 144