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