Completed
Branch develop (80d269)
by
unknown
22:48
created
htdocs/includes/sabre/sabre/vobject/lib/Component/VJournal.php 1 patch
Indentation   +75 added lines, -75 removed lines patch added patch discarded remove patch
@@ -16,86 +16,86 @@
 block discarded – undo
16 16
  */
17 17
 class VJournal extends VObject\Component
18 18
 {
19
-    /**
20
-     * Returns true or false depending on if the event falls in the specified
21
-     * time-range. This is used for filtering purposes.
22
-     *
23
-     * The rules used to determine if an event falls within the specified
24
-     * time-range is based on the CalDAV specification.
25
-     *
26
-     * @return bool
27
-     */
28
-    public function isInTimeRange(DateTimeInterface $start, DateTimeInterface $end)
29
-    {
30
-        $dtstart = isset($this->DTSTART) ? $this->DTSTART->getDateTime() : null;
31
-        if ($dtstart) {
32
-            $effectiveEnd = $dtstart;
33
-            if (!$this->DTSTART->hasTime()) {
34
-                $effectiveEnd = $effectiveEnd->modify('+1 day');
35
-            }
19
+	/**
20
+	 * Returns true or false depending on if the event falls in the specified
21
+	 * time-range. This is used for filtering purposes.
22
+	 *
23
+	 * The rules used to determine if an event falls within the specified
24
+	 * time-range is based on the CalDAV specification.
25
+	 *
26
+	 * @return bool
27
+	 */
28
+	public function isInTimeRange(DateTimeInterface $start, DateTimeInterface $end)
29
+	{
30
+		$dtstart = isset($this->DTSTART) ? $this->DTSTART->getDateTime() : null;
31
+		if ($dtstart) {
32
+			$effectiveEnd = $dtstart;
33
+			if (!$this->DTSTART->hasTime()) {
34
+				$effectiveEnd = $effectiveEnd->modify('+1 day');
35
+			}
36 36
 
37
-            return $start <= $effectiveEnd && $end > $dtstart;
38
-        }
37
+			return $start <= $effectiveEnd && $end > $dtstart;
38
+		}
39 39
 
40
-        return false;
41
-    }
40
+		return false;
41
+	}
42 42
 
43
-    /**
44
-     * A simple list of validation rules.
45
-     *
46
-     * This is simply a list of properties, and how many times they either
47
-     * must or must not appear.
48
-     *
49
-     * Possible values per property:
50
-     *   * 0 - Must not appear.
51
-     *   * 1 - Must appear exactly once.
52
-     *   * + - Must appear at least once.
53
-     *   * * - Can appear any number of times.
54
-     *   * ? - May appear, but not more than once.
55
-     *
56
-     * @var array
57
-     */
58
-    public function getValidationRules()
59
-    {
60
-        return [
61
-            'UID' => 1,
62
-            'DTSTAMP' => 1,
43
+	/**
44
+	 * A simple list of validation rules.
45
+	 *
46
+	 * This is simply a list of properties, and how many times they either
47
+	 * must or must not appear.
48
+	 *
49
+	 * Possible values per property:
50
+	 *   * 0 - Must not appear.
51
+	 *   * 1 - Must appear exactly once.
52
+	 *   * + - Must appear at least once.
53
+	 *   * * - Can appear any number of times.
54
+	 *   * ? - May appear, but not more than once.
55
+	 *
56
+	 * @var array
57
+	 */
58
+	public function getValidationRules()
59
+	{
60
+		return [
61
+			'UID' => 1,
62
+			'DTSTAMP' => 1,
63 63
 
64
-            'CLASS' => '?',
65
-            'CREATED' => '?',
66
-            'DTSTART' => '?',
67
-            'LAST-MODIFIED' => '?',
68
-            'ORGANIZER' => '?',
69
-            'RECURRENCE-ID' => '?',
70
-            'SEQUENCE' => '?',
71
-            'STATUS' => '?',
72
-            'SUMMARY' => '?',
73
-            'URL' => '?',
64
+			'CLASS' => '?',
65
+			'CREATED' => '?',
66
+			'DTSTART' => '?',
67
+			'LAST-MODIFIED' => '?',
68
+			'ORGANIZER' => '?',
69
+			'RECURRENCE-ID' => '?',
70
+			'SEQUENCE' => '?',
71
+			'STATUS' => '?',
72
+			'SUMMARY' => '?',
73
+			'URL' => '?',
74 74
 
75
-            'RRULE' => '?',
75
+			'RRULE' => '?',
76 76
 
77
-            'ATTACH' => '*',
78
-            'ATTENDEE' => '*',
79
-            'CATEGORIES' => '*',
80
-            'COMMENT' => '*',
81
-            'CONTACT' => '*',
82
-            'DESCRIPTION' => '*',
83
-            'EXDATE' => '*',
84
-            'RELATED-TO' => '*',
85
-            'RDATE' => '*',
86
-        ];
87
-    }
77
+			'ATTACH' => '*',
78
+			'ATTENDEE' => '*',
79
+			'CATEGORIES' => '*',
80
+			'COMMENT' => '*',
81
+			'CONTACT' => '*',
82
+			'DESCRIPTION' => '*',
83
+			'EXDATE' => '*',
84
+			'RELATED-TO' => '*',
85
+			'RDATE' => '*',
86
+		];
87
+	}
88 88
 
89
-    /**
90
-     * This method should return a list of default property values.
91
-     *
92
-     * @return array
93
-     */
94
-    protected function getDefaults()
95
-    {
96
-        return [
97
-            'UID' => 'sabre-vobject-'.VObject\UUIDUtil::getUUID(),
98
-            'DTSTAMP' => gmdate('Ymd\\THis\\Z'),
99
-        ];
100
-    }
89
+	/**
90
+	 * This method should return a list of default property values.
91
+	 *
92
+	 * @return array
93
+	 */
94
+	protected function getDefaults()
95
+	{
96
+		return [
97
+			'UID' => 'sabre-vobject-'.VObject\UUIDUtil::getUUID(),
98
+			'DTSTAMP' => gmdate('Ymd\\THis\\Z'),
99
+		];
100
+	}
101 101
 }
Please login to merge, or discard this patch.
htdocs/includes/sabre/sabre/vobject/lib/Component/VAvailability.php 1 patch
Indentation   +119 added lines, -119 removed lines patch added patch discarded remove patch
@@ -17,133 +17,133 @@
 block discarded – undo
17 17
  */
18 18
 class VAvailability extends VObject\Component
19 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:
26
-     *
27
-     * https://tools.ietf.org/html/draft-daboo-calendar-availability-05#section-3.1
28
-     *
29
-     * @return bool
30
-     */
31
-    public function isInTimeRange(DateTimeInterface $start, DateTimeInterface $end)
32
-    {
33
-        list($effectiveStart, $effectiveEnd) = $this->getEffectiveStartEnd();
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:
26
+	 *
27
+	 * https://tools.ietf.org/html/draft-daboo-calendar-availability-05#section-3.1
28
+	 *
29
+	 * @return bool
30
+	 */
31
+	public function isInTimeRange(DateTimeInterface $start, DateTimeInterface $end)
32
+	{
33
+		list($effectiveStart, $effectiveEnd) = $this->getEffectiveStartEnd();
34 34
 
35
-        return
36
-            (is_null($effectiveStart) || $start < $effectiveEnd) &&
37
-            (is_null($effectiveEnd) || $end > $effectiveStart)
38
-        ;
39
-    }
35
+		return
36
+			(is_null($effectiveStart) || $start < $effectiveEnd) &&
37
+			(is_null($effectiveEnd) || $end > $effectiveStart)
38
+		;
39
+	}
40 40
 
41
-    /**
42
-     * Returns the 'effective start' and 'effective end' of this VAVAILABILITY
43
-     * component.
44
-     *
45
-     * We use the DTSTART and DTEND or DURATION to determine this.
46
-     *
47
-     * The returned value is an array containing DateTimeImmutable instances.
48
-     * If either the start or end is 'unbounded' its value will be null
49
-     * instead.
50
-     *
51
-     * @return array
52
-     */
53
-    public function getEffectiveStartEnd()
54
-    {
55
-        $effectiveStart = null;
56
-        $effectiveEnd = null;
41
+	/**
42
+	 * Returns the 'effective start' and 'effective end' of this VAVAILABILITY
43
+	 * component.
44
+	 *
45
+	 * We use the DTSTART and DTEND or DURATION to determine this.
46
+	 *
47
+	 * The returned value is an array containing DateTimeImmutable instances.
48
+	 * If either the start or end is 'unbounded' its value will be null
49
+	 * instead.
50
+	 *
51
+	 * @return array
52
+	 */
53
+	public function getEffectiveStartEnd()
54
+	{
55
+		$effectiveStart = null;
56
+		$effectiveEnd = null;
57 57
 
58
-        if (isset($this->DTSTART)) {
59
-            $effectiveStart = $this->DTSTART->getDateTime();
60
-        }
61
-        if (isset($this->DTEND)) {
62
-            $effectiveEnd = $this->DTEND->getDateTime();
63
-        } elseif ($effectiveStart && isset($this->DURATION)) {
64
-            $effectiveEnd = $effectiveStart->add(VObject\DateTimeParser::parseDuration($this->DURATION));
65
-        }
58
+		if (isset($this->DTSTART)) {
59
+			$effectiveStart = $this->DTSTART->getDateTime();
60
+		}
61
+		if (isset($this->DTEND)) {
62
+			$effectiveEnd = $this->DTEND->getDateTime();
63
+		} elseif ($effectiveStart && isset($this->DURATION)) {
64
+			$effectiveEnd = $effectiveStart->add(VObject\DateTimeParser::parseDuration($this->DURATION));
65
+		}
66 66
 
67
-        return [$effectiveStart, $effectiveEnd];
68
-    }
67
+		return [$effectiveStart, $effectiveEnd];
68
+	}
69 69
 
70
-    /**
71
-     * A simple list of validation rules.
72
-     *
73
-     * This is simply a list of properties, and how many times they either
74
-     * must or must not appear.
75
-     *
76
-     * Possible values per property:
77
-     *   * 0 - Must not appear.
78
-     *   * 1 - Must appear exactly once.
79
-     *   * + - Must appear at least once.
80
-     *   * * - Can appear any number of times.
81
-     *   * ? - May appear, but not more than once.
82
-     *
83
-     * @var array
84
-     */
85
-    public function getValidationRules()
86
-    {
87
-        return [
88
-            'UID' => 1,
89
-            'DTSTAMP' => 1,
70
+	/**
71
+	 * A simple list of validation rules.
72
+	 *
73
+	 * This is simply a list of properties, and how many times they either
74
+	 * must or must not appear.
75
+	 *
76
+	 * Possible values per property:
77
+	 *   * 0 - Must not appear.
78
+	 *   * 1 - Must appear exactly once.
79
+	 *   * + - Must appear at least once.
80
+	 *   * * - Can appear any number of times.
81
+	 *   * ? - May appear, but not more than once.
82
+	 *
83
+	 * @var array
84
+	 */
85
+	public function getValidationRules()
86
+	{
87
+		return [
88
+			'UID' => 1,
89
+			'DTSTAMP' => 1,
90 90
 
91
-            'BUSYTYPE' => '?',
92
-            'CLASS' => '?',
93
-            'CREATED' => '?',
94
-            'DESCRIPTION' => '?',
95
-            'DTSTART' => '?',
96
-            'LAST-MODIFIED' => '?',
97
-            'ORGANIZER' => '?',
98
-            'PRIORITY' => '?',
99
-            'SEQUENCE' => '?',
100
-            'SUMMARY' => '?',
101
-            'URL' => '?',
102
-            'DTEND' => '?',
103
-            'DURATION' => '?',
91
+			'BUSYTYPE' => '?',
92
+			'CLASS' => '?',
93
+			'CREATED' => '?',
94
+			'DESCRIPTION' => '?',
95
+			'DTSTART' => '?',
96
+			'LAST-MODIFIED' => '?',
97
+			'ORGANIZER' => '?',
98
+			'PRIORITY' => '?',
99
+			'SEQUENCE' => '?',
100
+			'SUMMARY' => '?',
101
+			'URL' => '?',
102
+			'DTEND' => '?',
103
+			'DURATION' => '?',
104 104
 
105
-            'CATEGORIES' => '*',
106
-            'COMMENT' => '*',
107
-            'CONTACT' => '*',
108
-        ];
109
-    }
105
+			'CATEGORIES' => '*',
106
+			'COMMENT' => '*',
107
+			'CONTACT' => '*',
108
+		];
109
+	}
110 110
 
111
-    /**
112
-     * Validates the node for correctness.
113
-     *
114
-     * The following options are supported:
115
-     *   Node::REPAIR - May attempt to automatically repair the problem.
116
-     *   Node::PROFILE_CARDDAV - Validate the vCard for CardDAV purposes.
117
-     *   Node::PROFILE_CALDAV - Validate the iCalendar for CalDAV purposes.
118
-     *
119
-     * This method returns an array with detected problems.
120
-     * Every element has the following properties:
121
-     *
122
-     *  * level - problem level.
123
-     *  * message - A human-readable string describing the issue.
124
-     *  * node - A reference to the problematic node.
125
-     *
126
-     * The level means:
127
-     *   1 - The issue was repaired (only happens if REPAIR was turned on).
128
-     *   2 - A warning.
129
-     *   3 - An error.
130
-     *
131
-     * @param int $options
132
-     *
133
-     * @return array
134
-     */
135
-    public function validate($options = 0)
136
-    {
137
-        $result = parent::validate($options);
111
+	/**
112
+	 * Validates the node for correctness.
113
+	 *
114
+	 * The following options are supported:
115
+	 *   Node::REPAIR - May attempt to automatically repair the problem.
116
+	 *   Node::PROFILE_CARDDAV - Validate the vCard for CardDAV purposes.
117
+	 *   Node::PROFILE_CALDAV - Validate the iCalendar for CalDAV purposes.
118
+	 *
119
+	 * This method returns an array with detected problems.
120
+	 * Every element has the following properties:
121
+	 *
122
+	 *  * level - problem level.
123
+	 *  * message - A human-readable string describing the issue.
124
+	 *  * node - A reference to the problematic node.
125
+	 *
126
+	 * The level means:
127
+	 *   1 - The issue was repaired (only happens if REPAIR was turned on).
128
+	 *   2 - A warning.
129
+	 *   3 - An error.
130
+	 *
131
+	 * @param int $options
132
+	 *
133
+	 * @return array
134
+	 */
135
+	public function validate($options = 0)
136
+	{
137
+		$result = parent::validate($options);
138 138
 
139
-        if (isset($this->DTEND) && isset($this->DURATION)) {
140
-            $result[] = [
141
-                'level' => 3,
142
-                'message' => 'DTEND and DURATION cannot both be present',
143
-                'node' => $this,
144
-            ];
145
-        }
139
+		if (isset($this->DTEND) && isset($this->DURATION)) {
140
+			$result[] = [
141
+				'level' => 3,
142
+				'message' => 'DTEND and DURATION cannot both be present',
143
+				'node' => $this,
144
+			];
145
+		}
146 146
 
147
-        return $result;
148
-    }
147
+		return $result;
148
+	}
149 149
 }
Please login to merge, or discard this patch.
htdocs/includes/sabre/sabre/vobject/lib/Component/VCalendar.php 1 patch
Indentation   +503 added lines, -503 removed lines patch added patch discarded remove patch
@@ -22,507 +22,507 @@
 block discarded – undo
22 22
  */
23 23
 class VCalendar extends VObject\Document
24 24
 {
25
-    /**
26
-     * The default name for this component.
27
-     *
28
-     * This should be 'VCALENDAR' or 'VCARD'.
29
-     *
30
-     * @var string
31
-     */
32
-    public static $defaultName = 'VCALENDAR';
33
-
34
-    /**
35
-     * This is a list of components, and which classes they should map to.
36
-     *
37
-     * @var array
38
-     */
39
-    public static $componentMap = [
40
-        'VCALENDAR' => self::class,
41
-        'VALARM' => VAlarm::class,
42
-        'VEVENT' => VEvent::class,
43
-        'VFREEBUSY' => VFreeBusy::class,
44
-        'VAVAILABILITY' => VAvailability::class,
45
-        'AVAILABLE' => Available::class,
46
-        'VJOURNAL' => VJournal::class,
47
-        'VTIMEZONE' => VTimeZone::class,
48
-        'VTODO' => VTodo::class,
49
-    ];
50
-
51
-    /**
52
-     * List of value-types, and which classes they map to.
53
-     *
54
-     * @var array
55
-     */
56
-    public static $valueMap = [
57
-        'BINARY' => VObject\Property\Binary::class,
58
-        'BOOLEAN' => VObject\Property\Boolean::class,
59
-        'CAL-ADDRESS' => VObject\Property\ICalendar\CalAddress::class,
60
-        'DATE' => VObject\Property\ICalendar\Date::class,
61
-        'DATE-TIME' => VObject\Property\ICalendar\DateTime::class,
62
-        'DURATION' => VObject\Property\ICalendar\Duration::class,
63
-        'FLOAT' => VObject\Property\FloatValue::class,
64
-        'INTEGER' => VObject\Property\IntegerValue::class,
65
-        'PERIOD' => VObject\Property\ICalendar\Period::class,
66
-        'RECUR' => VObject\Property\ICalendar\Recur::class,
67
-        'TEXT' => VObject\Property\Text::class,
68
-        'TIME' => VObject\Property\Time::class,
69
-        'UNKNOWN' => VObject\Property\Unknown::class, // jCard / jCal-only.
70
-        'URI' => VObject\Property\Uri::class,
71
-        'UTC-OFFSET' => VObject\Property\UtcOffset::class,
72
-    ];
73
-
74
-    /**
75
-     * List of properties, and which classes they map to.
76
-     *
77
-     * @var array
78
-     */
79
-    public static $propertyMap = [
80
-        // Calendar properties
81
-        'CALSCALE' => VObject\Property\FlatText::class,
82
-        'METHOD' => VObject\Property\FlatText::class,
83
-        'PRODID' => VObject\Property\FlatText::class,
84
-        'VERSION' => VObject\Property\FlatText::class,
85
-
86
-        // Component properties
87
-        'ATTACH' => VObject\Property\Uri::class,
88
-        'CATEGORIES' => VObject\Property\Text::class,
89
-        'CLASS' => VObject\Property\FlatText::class,
90
-        'COMMENT' => VObject\Property\FlatText::class,
91
-        'DESCRIPTION' => VObject\Property\FlatText::class,
92
-        'GEO' => VObject\Property\FloatValue::class,
93
-        'LOCATION' => VObject\Property\FlatText::class,
94
-        'PERCENT-COMPLETE' => VObject\Property\IntegerValue::class,
95
-        'PRIORITY' => VObject\Property\IntegerValue::class,
96
-        'RESOURCES' => VObject\Property\Text::class,
97
-        'STATUS' => VObject\Property\FlatText::class,
98
-        'SUMMARY' => VObject\Property\FlatText::class,
99
-
100
-        // Date and Time Component Properties
101
-        'COMPLETED' => VObject\Property\ICalendar\DateTime::class,
102
-        'DTEND' => VObject\Property\ICalendar\DateTime::class,
103
-        'DUE' => VObject\Property\ICalendar\DateTime::class,
104
-        'DTSTART' => VObject\Property\ICalendar\DateTime::class,
105
-        'DURATION' => VObject\Property\ICalendar\Duration::class,
106
-        'FREEBUSY' => VObject\Property\ICalendar\Period::class,
107
-        'TRANSP' => VObject\Property\FlatText::class,
108
-
109
-        // Time Zone Component Properties
110
-        'TZID' => VObject\Property\FlatText::class,
111
-        'TZNAME' => VObject\Property\FlatText::class,
112
-        'TZOFFSETFROM' => VObject\Property\UtcOffset::class,
113
-        'TZOFFSETTO' => VObject\Property\UtcOffset::class,
114
-        'TZURL' => VObject\Property\Uri::class,
115
-
116
-        // Relationship Component Properties
117
-        'ATTENDEE' => VObject\Property\ICalendar\CalAddress::class,
118
-        'CONTACT' => VObject\Property\FlatText::class,
119
-        'ORGANIZER' => VObject\Property\ICalendar\CalAddress::class,
120
-        'RECURRENCE-ID' => VObject\Property\ICalendar\DateTime::class,
121
-        'RELATED-TO' => VObject\Property\FlatText::class,
122
-        'URL' => VObject\Property\Uri::class,
123
-        'UID' => VObject\Property\FlatText::class,
124
-
125
-        // Recurrence Component Properties
126
-        'EXDATE' => VObject\Property\ICalendar\DateTime::class,
127
-        'RDATE' => VObject\Property\ICalendar\DateTime::class,
128
-        'RRULE' => VObject\Property\ICalendar\Recur::class,
129
-        'EXRULE' => VObject\Property\ICalendar\Recur::class, // Deprecated since rfc5545
130
-
131
-        // Alarm Component Properties
132
-        'ACTION' => VObject\Property\FlatText::class,
133
-        'REPEAT' => VObject\Property\IntegerValue::class,
134
-        'TRIGGER' => VObject\Property\ICalendar\Duration::class,
135
-
136
-        // Change Management Component Properties
137
-        'CREATED' => VObject\Property\ICalendar\DateTime::class,
138
-        'DTSTAMP' => VObject\Property\ICalendar\DateTime::class,
139
-        'LAST-MODIFIED' => VObject\Property\ICalendar\DateTime::class,
140
-        'SEQUENCE' => VObject\Property\IntegerValue::class,
141
-
142
-        // Request Status
143
-        'REQUEST-STATUS' => VObject\Property\Text::class,
144
-
145
-        // Additions from draft-daboo-valarm-extensions-04
146
-        'ALARM-AGENT' => VObject\Property\Text::class,
147
-        'ACKNOWLEDGED' => VObject\Property\ICalendar\DateTime::class,
148
-        'PROXIMITY' => VObject\Property\Text::class,
149
-        'DEFAULT-ALARM' => VObject\Property\Boolean::class,
150
-
151
-        // Additions from draft-daboo-calendar-availability-05
152
-        'BUSYTYPE' => VObject\Property\Text::class,
153
-    ];
154
-
155
-    /**
156
-     * Returns the current document type.
157
-     *
158
-     * @return int
159
-     */
160
-    public function getDocumentType()
161
-    {
162
-        return self::ICALENDAR20;
163
-    }
164
-
165
-    /**
166
-     * Returns a list of all 'base components'. For instance, if an Event has
167
-     * a recurrence rule, and one instance is overridden, the overridden event
168
-     * will have the same UID, but will be excluded from this list.
169
-     *
170
-     * VTIMEZONE components will always be excluded.
171
-     *
172
-     * @param string $componentName filter by component name
173
-     *
174
-     * @return VObject\Component[]
175
-     */
176
-    public function getBaseComponents($componentName = null)
177
-    {
178
-        $isBaseComponent = function ($component) {
179
-            if (!$component instanceof VObject\Component) {
180
-                return false;
181
-            }
182
-            if ('VTIMEZONE' === $component->name) {
183
-                return false;
184
-            }
185
-            if (isset($component->{'RECURRENCE-ID'})) {
186
-                return false;
187
-            }
188
-
189
-            return true;
190
-        };
191
-
192
-        if ($componentName) {
193
-            // Early exit
194
-            return array_filter(
195
-                $this->select($componentName),
196
-                $isBaseComponent
197
-            );
198
-        }
199
-
200
-        $components = [];
201
-        foreach ($this->children as $childGroup) {
202
-            foreach ($childGroup as $child) {
203
-                if (!$child instanceof Component) {
204
-                    // If one child is not a component, they all are so we skip
205
-                    // the entire group.
206
-                    continue 2;
207
-                }
208
-                if ($isBaseComponent($child)) {
209
-                    $components[] = $child;
210
-                }
211
-            }
212
-        }
213
-
214
-        return $components;
215
-    }
216
-
217
-    /**
218
-     * Returns the first component that is not a VTIMEZONE, and does not have
219
-     * an RECURRENCE-ID.
220
-     *
221
-     * If there is no such component, null will be returned.
222
-     *
223
-     * @param string $componentName filter by component name
224
-     *
225
-     * @return VObject\Component|null
226
-     */
227
-    public function getBaseComponent($componentName = null)
228
-    {
229
-        $isBaseComponent = function ($component) {
230
-            if (!$component instanceof VObject\Component) {
231
-                return false;
232
-            }
233
-            if ('VTIMEZONE' === $component->name) {
234
-                return false;
235
-            }
236
-            if (isset($component->{'RECURRENCE-ID'})) {
237
-                return false;
238
-            }
239
-
240
-            return true;
241
-        };
242
-
243
-        if ($componentName) {
244
-            foreach ($this->select($componentName) as $child) {
245
-                if ($isBaseComponent($child)) {
246
-                    return $child;
247
-                }
248
-            }
249
-
250
-            return null;
251
-        }
252
-
253
-        // Searching all components
254
-        foreach ($this->children as $childGroup) {
255
-            foreach ($childGroup as $child) {
256
-                if ($isBaseComponent($child)) {
257
-                    return $child;
258
-                }
259
-            }
260
-        }
261
-
262
-        return null;
263
-    }
264
-
265
-    /**
266
-     * Expand all events in this VCalendar object and return a new VCalendar
267
-     * with the expanded events.
268
-     *
269
-     * If this calendar object, has events with recurrence rules, this method
270
-     * can be used to expand the event into multiple sub-events.
271
-     *
272
-     * Each event will be stripped from its recurrence information, and only
273
-     * the instances of the event in the specified timerange will be left
274
-     * alone.
275
-     *
276
-     * In addition, this method will cause timezone information to be stripped,
277
-     * and normalized to UTC.
278
-     *
279
-     * @param DateTimeZone $timeZone reference timezone for floating dates and
280
-     *                               times
281
-     *
282
-     * @return VCalendar
283
-     */
284
-    public function expand(DateTimeInterface $start, DateTimeInterface $end, DateTimeZone $timeZone = null)
285
-    {
286
-        $newChildren = [];
287
-        $recurringEvents = [];
288
-
289
-        if (!$timeZone) {
290
-            $timeZone = new DateTimeZone('UTC');
291
-        }
292
-
293
-        $stripTimezones = function (Component $component) use ($timeZone, &$stripTimezones) {
294
-            foreach ($component->children() as $componentChild) {
295
-                if ($componentChild instanceof Property\ICalendar\DateTime && $componentChild->hasTime()) {
296
-                    $dt = $componentChild->getDateTimes($timeZone);
297
-                    // We only need to update the first timezone, because
298
-                    // setDateTimes will match all other timezones to the
299
-                    // first.
300
-                    $dt[0] = $dt[0]->setTimeZone(new DateTimeZone('UTC'));
301
-                    $componentChild->setDateTimes($dt);
302
-                } elseif ($componentChild instanceof Component) {
303
-                    $stripTimezones($componentChild);
304
-                }
305
-            }
306
-
307
-            return $component;
308
-        };
309
-
310
-        foreach ($this->children() as $child) {
311
-            if ($child instanceof Property && 'PRODID' !== $child->name) {
312
-                // We explicitly want to ignore PRODID, because we want to
313
-                // overwrite it with our own.
314
-                $newChildren[] = clone $child;
315
-            } elseif ($child instanceof Component && 'VTIMEZONE' !== $child->name) {
316
-                // We're also stripping all VTIMEZONE objects because we're
317
-                // converting everything to UTC.
318
-                if ('VEVENT' === $child->name && (isset($child->{'RECURRENCE-ID'}) || isset($child->RRULE) || isset($child->RDATE))) {
319
-                    // Handle these a bit later.
320
-                    $uid = (string) $child->UID;
321
-                    if (!$uid) {
322
-                        throw new InvalidDataException('Every VEVENT object must have a UID property');
323
-                    }
324
-                    if (isset($recurringEvents[$uid])) {
325
-                        $recurringEvents[$uid][] = clone $child;
326
-                    } else {
327
-                        $recurringEvents[$uid] = [clone $child];
328
-                    }
329
-                } elseif ('VEVENT' === $child->name && $child->isInTimeRange($start, $end)) {
330
-                    $newChildren[] = $stripTimezones(clone $child);
331
-                }
332
-            }
333
-        }
334
-
335
-        foreach ($recurringEvents as $events) {
336
-            try {
337
-                $it = new EventIterator($events, null, $timeZone);
338
-            } catch (NoInstancesException $e) {
339
-                // This event is recurring, but it doesn't have a single
340
-                // instance. We are skipping this event from the output
341
-                // entirely.
342
-                continue;
343
-            }
344
-            $it->fastForward($start);
345
-
346
-            while ($it->valid() && $it->getDTStart() < $end) {
347
-                if ($it->getDTEnd() > $start) {
348
-                    $newChildren[] = $stripTimezones($it->getEventObject());
349
-                }
350
-                $it->next();
351
-            }
352
-        }
353
-
354
-        return new self($newChildren);
355
-    }
356
-
357
-    /**
358
-     * This method should return a list of default property values.
359
-     *
360
-     * @return array
361
-     */
362
-    protected function getDefaults()
363
-    {
364
-        return [
365
-            'VERSION' => '2.0',
366
-            'PRODID' => '-//Sabre//Sabre VObject '.VObject\Version::VERSION.'//EN',
367
-            'CALSCALE' => 'GREGORIAN',
368
-        ];
369
-    }
370
-
371
-    /**
372
-     * A simple list of validation rules.
373
-     *
374
-     * This is simply a list of properties, and how many times they either
375
-     * must or must not appear.
376
-     *
377
-     * Possible values per property:
378
-     *   * 0 - Must not appear.
379
-     *   * 1 - Must appear exactly once.
380
-     *   * + - Must appear at least once.
381
-     *   * * - Can appear any number of times.
382
-     *   * ? - May appear, but not more than once.
383
-     *
384
-     * @var array
385
-     */
386
-    public function getValidationRules()
387
-    {
388
-        return [
389
-            'PRODID' => 1,
390
-            'VERSION' => 1,
391
-
392
-            'CALSCALE' => '?',
393
-            'METHOD' => '?',
394
-        ];
395
-    }
396
-
397
-    /**
398
-     * Validates the node for correctness.
399
-     *
400
-     * The following options are supported:
401
-     *   Node::REPAIR - May attempt to automatically repair the problem.
402
-     *   Node::PROFILE_CARDDAV - Validate the vCard for CardDAV purposes.
403
-     *   Node::PROFILE_CALDAV - Validate the iCalendar for CalDAV purposes.
404
-     *
405
-     * This method returns an array with detected problems.
406
-     * Every element has the following properties:
407
-     *
408
-     *  * level - problem level.
409
-     *  * message - A human-readable string describing the issue.
410
-     *  * node - A reference to the problematic node.
411
-     *
412
-     * The level means:
413
-     *   1 - The issue was repaired (only happens if REPAIR was turned on).
414
-     *   2 - A warning.
415
-     *   3 - An error.
416
-     *
417
-     * @param int $options
418
-     *
419
-     * @return array
420
-     */
421
-    public function validate($options = 0)
422
-    {
423
-        $warnings = parent::validate($options);
424
-
425
-        if ($ver = $this->VERSION) {
426
-            if ('2.0' !== (string) $ver) {
427
-                $warnings[] = [
428
-                    'level' => 3,
429
-                    'message' => 'Only iCalendar version 2.0 as defined in rfc5545 is supported.',
430
-                    'node' => $this,
431
-                ];
432
-            }
433
-        }
434
-
435
-        $uidList = [];
436
-        $componentsFound = 0;
437
-        $componentTypes = [];
438
-
439
-        foreach ($this->children() as $child) {
440
-            if ($child instanceof Component) {
441
-                ++$componentsFound;
442
-
443
-                if (!in_array($child->name, ['VEVENT', 'VTODO', 'VJOURNAL'])) {
444
-                    continue;
445
-                }
446
-                $componentTypes[] = $child->name;
447
-
448
-                $uid = (string) $child->UID;
449
-                $isMaster = isset($child->{'RECURRENCE-ID'}) ? 0 : 1;
450
-                if (isset($uidList[$uid])) {
451
-                    ++$uidList[$uid]['count'];
452
-                    if ($isMaster && $uidList[$uid]['hasMaster']) {
453
-                        $warnings[] = [
454
-                            'level' => 3,
455
-                            'message' => 'More than one master object was found for the object with UID '.$uid,
456
-                            'node' => $this,
457
-                        ];
458
-                    }
459
-                    $uidList[$uid]['hasMaster'] += $isMaster;
460
-                } else {
461
-                    $uidList[$uid] = [
462
-                        'count' => 1,
463
-                        'hasMaster' => $isMaster,
464
-                    ];
465
-                }
466
-            }
467
-        }
468
-
469
-        if (0 === $componentsFound) {
470
-            $warnings[] = [
471
-                'level' => 3,
472
-                'message' => 'An iCalendar object must have at least 1 component.',
473
-                'node' => $this,
474
-            ];
475
-        }
476
-
477
-        if ($options & self::PROFILE_CALDAV) {
478
-            if (count($uidList) > 1) {
479
-                $warnings[] = [
480
-                    'level' => 3,
481
-                    'message' => 'A calendar object on a CalDAV server may only have components with the same UID.',
482
-                    'node' => $this,
483
-                ];
484
-            }
485
-            if (0 === count($componentTypes)) {
486
-                $warnings[] = [
487
-                    'level' => 3,
488
-                    'message' => 'A calendar object on a CalDAV server must have at least 1 component (VTODO, VEVENT, VJOURNAL).',
489
-                    'node' => $this,
490
-                ];
491
-            }
492
-            if (count(array_unique($componentTypes)) > 1) {
493
-                $warnings[] = [
494
-                    'level' => 3,
495
-                    'message' => 'A calendar object on a CalDAV server may only have 1 type of component (VEVENT, VTODO or VJOURNAL).',
496
-                    'node' => $this,
497
-                ];
498
-            }
499
-
500
-            if (isset($this->METHOD)) {
501
-                $warnings[] = [
502
-                    'level' => 3,
503
-                    'message' => 'A calendar object on a CalDAV server MUST NOT have a METHOD property.',
504
-                    'node' => $this,
505
-                ];
506
-            }
507
-        }
508
-
509
-        return $warnings;
510
-    }
511
-
512
-    /**
513
-     * Returns all components with a specific UID value.
514
-     *
515
-     * @return array
516
-     */
517
-    public function getByUID($uid)
518
-    {
519
-        return array_filter($this->getComponents(), function ($item) use ($uid) {
520
-            if (!$itemUid = $item->select('UID')) {
521
-                return false;
522
-            }
523
-            $itemUid = current($itemUid)->getValue();
524
-
525
-            return $uid === $itemUid;
526
-        });
527
-    }
25
+	/**
26
+	 * The default name for this component.
27
+	 *
28
+	 * This should be 'VCALENDAR' or 'VCARD'.
29
+	 *
30
+	 * @var string
31
+	 */
32
+	public static $defaultName = 'VCALENDAR';
33
+
34
+	/**
35
+	 * This is a list of components, and which classes they should map to.
36
+	 *
37
+	 * @var array
38
+	 */
39
+	public static $componentMap = [
40
+		'VCALENDAR' => self::class,
41
+		'VALARM' => VAlarm::class,
42
+		'VEVENT' => VEvent::class,
43
+		'VFREEBUSY' => VFreeBusy::class,
44
+		'VAVAILABILITY' => VAvailability::class,
45
+		'AVAILABLE' => Available::class,
46
+		'VJOURNAL' => VJournal::class,
47
+		'VTIMEZONE' => VTimeZone::class,
48
+		'VTODO' => VTodo::class,
49
+	];
50
+
51
+	/**
52
+	 * List of value-types, and which classes they map to.
53
+	 *
54
+	 * @var array
55
+	 */
56
+	public static $valueMap = [
57
+		'BINARY' => VObject\Property\Binary::class,
58
+		'BOOLEAN' => VObject\Property\Boolean::class,
59
+		'CAL-ADDRESS' => VObject\Property\ICalendar\CalAddress::class,
60
+		'DATE' => VObject\Property\ICalendar\Date::class,
61
+		'DATE-TIME' => VObject\Property\ICalendar\DateTime::class,
62
+		'DURATION' => VObject\Property\ICalendar\Duration::class,
63
+		'FLOAT' => VObject\Property\FloatValue::class,
64
+		'INTEGER' => VObject\Property\IntegerValue::class,
65
+		'PERIOD' => VObject\Property\ICalendar\Period::class,
66
+		'RECUR' => VObject\Property\ICalendar\Recur::class,
67
+		'TEXT' => VObject\Property\Text::class,
68
+		'TIME' => VObject\Property\Time::class,
69
+		'UNKNOWN' => VObject\Property\Unknown::class, // jCard / jCal-only.
70
+		'URI' => VObject\Property\Uri::class,
71
+		'UTC-OFFSET' => VObject\Property\UtcOffset::class,
72
+	];
73
+
74
+	/**
75
+	 * List of properties, and which classes they map to.
76
+	 *
77
+	 * @var array
78
+	 */
79
+	public static $propertyMap = [
80
+		// Calendar properties
81
+		'CALSCALE' => VObject\Property\FlatText::class,
82
+		'METHOD' => VObject\Property\FlatText::class,
83
+		'PRODID' => VObject\Property\FlatText::class,
84
+		'VERSION' => VObject\Property\FlatText::class,
85
+
86
+		// Component properties
87
+		'ATTACH' => VObject\Property\Uri::class,
88
+		'CATEGORIES' => VObject\Property\Text::class,
89
+		'CLASS' => VObject\Property\FlatText::class,
90
+		'COMMENT' => VObject\Property\FlatText::class,
91
+		'DESCRIPTION' => VObject\Property\FlatText::class,
92
+		'GEO' => VObject\Property\FloatValue::class,
93
+		'LOCATION' => VObject\Property\FlatText::class,
94
+		'PERCENT-COMPLETE' => VObject\Property\IntegerValue::class,
95
+		'PRIORITY' => VObject\Property\IntegerValue::class,
96
+		'RESOURCES' => VObject\Property\Text::class,
97
+		'STATUS' => VObject\Property\FlatText::class,
98
+		'SUMMARY' => VObject\Property\FlatText::class,
99
+
100
+		// Date and Time Component Properties
101
+		'COMPLETED' => VObject\Property\ICalendar\DateTime::class,
102
+		'DTEND' => VObject\Property\ICalendar\DateTime::class,
103
+		'DUE' => VObject\Property\ICalendar\DateTime::class,
104
+		'DTSTART' => VObject\Property\ICalendar\DateTime::class,
105
+		'DURATION' => VObject\Property\ICalendar\Duration::class,
106
+		'FREEBUSY' => VObject\Property\ICalendar\Period::class,
107
+		'TRANSP' => VObject\Property\FlatText::class,
108
+
109
+		// Time Zone Component Properties
110
+		'TZID' => VObject\Property\FlatText::class,
111
+		'TZNAME' => VObject\Property\FlatText::class,
112
+		'TZOFFSETFROM' => VObject\Property\UtcOffset::class,
113
+		'TZOFFSETTO' => VObject\Property\UtcOffset::class,
114
+		'TZURL' => VObject\Property\Uri::class,
115
+
116
+		// Relationship Component Properties
117
+		'ATTENDEE' => VObject\Property\ICalendar\CalAddress::class,
118
+		'CONTACT' => VObject\Property\FlatText::class,
119
+		'ORGANIZER' => VObject\Property\ICalendar\CalAddress::class,
120
+		'RECURRENCE-ID' => VObject\Property\ICalendar\DateTime::class,
121
+		'RELATED-TO' => VObject\Property\FlatText::class,
122
+		'URL' => VObject\Property\Uri::class,
123
+		'UID' => VObject\Property\FlatText::class,
124
+
125
+		// Recurrence Component Properties
126
+		'EXDATE' => VObject\Property\ICalendar\DateTime::class,
127
+		'RDATE' => VObject\Property\ICalendar\DateTime::class,
128
+		'RRULE' => VObject\Property\ICalendar\Recur::class,
129
+		'EXRULE' => VObject\Property\ICalendar\Recur::class, // Deprecated since rfc5545
130
+
131
+		// Alarm Component Properties
132
+		'ACTION' => VObject\Property\FlatText::class,
133
+		'REPEAT' => VObject\Property\IntegerValue::class,
134
+		'TRIGGER' => VObject\Property\ICalendar\Duration::class,
135
+
136
+		// Change Management Component Properties
137
+		'CREATED' => VObject\Property\ICalendar\DateTime::class,
138
+		'DTSTAMP' => VObject\Property\ICalendar\DateTime::class,
139
+		'LAST-MODIFIED' => VObject\Property\ICalendar\DateTime::class,
140
+		'SEQUENCE' => VObject\Property\IntegerValue::class,
141
+
142
+		// Request Status
143
+		'REQUEST-STATUS' => VObject\Property\Text::class,
144
+
145
+		// Additions from draft-daboo-valarm-extensions-04
146
+		'ALARM-AGENT' => VObject\Property\Text::class,
147
+		'ACKNOWLEDGED' => VObject\Property\ICalendar\DateTime::class,
148
+		'PROXIMITY' => VObject\Property\Text::class,
149
+		'DEFAULT-ALARM' => VObject\Property\Boolean::class,
150
+
151
+		// Additions from draft-daboo-calendar-availability-05
152
+		'BUSYTYPE' => VObject\Property\Text::class,
153
+	];
154
+
155
+	/**
156
+	 * Returns the current document type.
157
+	 *
158
+	 * @return int
159
+	 */
160
+	public function getDocumentType()
161
+	{
162
+		return self::ICALENDAR20;
163
+	}
164
+
165
+	/**
166
+	 * Returns a list of all 'base components'. For instance, if an Event has
167
+	 * a recurrence rule, and one instance is overridden, the overridden event
168
+	 * will have the same UID, but will be excluded from this list.
169
+	 *
170
+	 * VTIMEZONE components will always be excluded.
171
+	 *
172
+	 * @param string $componentName filter by component name
173
+	 *
174
+	 * @return VObject\Component[]
175
+	 */
176
+	public function getBaseComponents($componentName = null)
177
+	{
178
+		$isBaseComponent = function ($component) {
179
+			if (!$component instanceof VObject\Component) {
180
+				return false;
181
+			}
182
+			if ('VTIMEZONE' === $component->name) {
183
+				return false;
184
+			}
185
+			if (isset($component->{'RECURRENCE-ID'})) {
186
+				return false;
187
+			}
188
+
189
+			return true;
190
+		};
191
+
192
+		if ($componentName) {
193
+			// Early exit
194
+			return array_filter(
195
+				$this->select($componentName),
196
+				$isBaseComponent
197
+			);
198
+		}
199
+
200
+		$components = [];
201
+		foreach ($this->children as $childGroup) {
202
+			foreach ($childGroup as $child) {
203
+				if (!$child instanceof Component) {
204
+					// If one child is not a component, they all are so we skip
205
+					// the entire group.
206
+					continue 2;
207
+				}
208
+				if ($isBaseComponent($child)) {
209
+					$components[] = $child;
210
+				}
211
+			}
212
+		}
213
+
214
+		return $components;
215
+	}
216
+
217
+	/**
218
+	 * Returns the first component that is not a VTIMEZONE, and does not have
219
+	 * an RECURRENCE-ID.
220
+	 *
221
+	 * If there is no such component, null will be returned.
222
+	 *
223
+	 * @param string $componentName filter by component name
224
+	 *
225
+	 * @return VObject\Component|null
226
+	 */
227
+	public function getBaseComponent($componentName = null)
228
+	{
229
+		$isBaseComponent = function ($component) {
230
+			if (!$component instanceof VObject\Component) {
231
+				return false;
232
+			}
233
+			if ('VTIMEZONE' === $component->name) {
234
+				return false;
235
+			}
236
+			if (isset($component->{'RECURRENCE-ID'})) {
237
+				return false;
238
+			}
239
+
240
+			return true;
241
+		};
242
+
243
+		if ($componentName) {
244
+			foreach ($this->select($componentName) as $child) {
245
+				if ($isBaseComponent($child)) {
246
+					return $child;
247
+				}
248
+			}
249
+
250
+			return null;
251
+		}
252
+
253
+		// Searching all components
254
+		foreach ($this->children as $childGroup) {
255
+			foreach ($childGroup as $child) {
256
+				if ($isBaseComponent($child)) {
257
+					return $child;
258
+				}
259
+			}
260
+		}
261
+
262
+		return null;
263
+	}
264
+
265
+	/**
266
+	 * Expand all events in this VCalendar object and return a new VCalendar
267
+	 * with the expanded events.
268
+	 *
269
+	 * If this calendar object, has events with recurrence rules, this method
270
+	 * can be used to expand the event into multiple sub-events.
271
+	 *
272
+	 * Each event will be stripped from its recurrence information, and only
273
+	 * the instances of the event in the specified timerange will be left
274
+	 * alone.
275
+	 *
276
+	 * In addition, this method will cause timezone information to be stripped,
277
+	 * and normalized to UTC.
278
+	 *
279
+	 * @param DateTimeZone $timeZone reference timezone for floating dates and
280
+	 *                               times
281
+	 *
282
+	 * @return VCalendar
283
+	 */
284
+	public function expand(DateTimeInterface $start, DateTimeInterface $end, DateTimeZone $timeZone = null)
285
+	{
286
+		$newChildren = [];
287
+		$recurringEvents = [];
288
+
289
+		if (!$timeZone) {
290
+			$timeZone = new DateTimeZone('UTC');
291
+		}
292
+
293
+		$stripTimezones = function (Component $component) use ($timeZone, &$stripTimezones) {
294
+			foreach ($component->children() as $componentChild) {
295
+				if ($componentChild instanceof Property\ICalendar\DateTime && $componentChild->hasTime()) {
296
+					$dt = $componentChild->getDateTimes($timeZone);
297
+					// We only need to update the first timezone, because
298
+					// setDateTimes will match all other timezones to the
299
+					// first.
300
+					$dt[0] = $dt[0]->setTimeZone(new DateTimeZone('UTC'));
301
+					$componentChild->setDateTimes($dt);
302
+				} elseif ($componentChild instanceof Component) {
303
+					$stripTimezones($componentChild);
304
+				}
305
+			}
306
+
307
+			return $component;
308
+		};
309
+
310
+		foreach ($this->children() as $child) {
311
+			if ($child instanceof Property && 'PRODID' !== $child->name) {
312
+				// We explicitly want to ignore PRODID, because we want to
313
+				// overwrite it with our own.
314
+				$newChildren[] = clone $child;
315
+			} elseif ($child instanceof Component && 'VTIMEZONE' !== $child->name) {
316
+				// We're also stripping all VTIMEZONE objects because we're
317
+				// converting everything to UTC.
318
+				if ('VEVENT' === $child->name && (isset($child->{'RECURRENCE-ID'}) || isset($child->RRULE) || isset($child->RDATE))) {
319
+					// Handle these a bit later.
320
+					$uid = (string) $child->UID;
321
+					if (!$uid) {
322
+						throw new InvalidDataException('Every VEVENT object must have a UID property');
323
+					}
324
+					if (isset($recurringEvents[$uid])) {
325
+						$recurringEvents[$uid][] = clone $child;
326
+					} else {
327
+						$recurringEvents[$uid] = [clone $child];
328
+					}
329
+				} elseif ('VEVENT' === $child->name && $child->isInTimeRange($start, $end)) {
330
+					$newChildren[] = $stripTimezones(clone $child);
331
+				}
332
+			}
333
+		}
334
+
335
+		foreach ($recurringEvents as $events) {
336
+			try {
337
+				$it = new EventIterator($events, null, $timeZone);
338
+			} catch (NoInstancesException $e) {
339
+				// This event is recurring, but it doesn't have a single
340
+				// instance. We are skipping this event from the output
341
+				// entirely.
342
+				continue;
343
+			}
344
+			$it->fastForward($start);
345
+
346
+			while ($it->valid() && $it->getDTStart() < $end) {
347
+				if ($it->getDTEnd() > $start) {
348
+					$newChildren[] = $stripTimezones($it->getEventObject());
349
+				}
350
+				$it->next();
351
+			}
352
+		}
353
+
354
+		return new self($newChildren);
355
+	}
356
+
357
+	/**
358
+	 * This method should return a list of default property values.
359
+	 *
360
+	 * @return array
361
+	 */
362
+	protected function getDefaults()
363
+	{
364
+		return [
365
+			'VERSION' => '2.0',
366
+			'PRODID' => '-//Sabre//Sabre VObject '.VObject\Version::VERSION.'//EN',
367
+			'CALSCALE' => 'GREGORIAN',
368
+		];
369
+	}
370
+
371
+	/**
372
+	 * A simple list of validation rules.
373
+	 *
374
+	 * This is simply a list of properties, and how many times they either
375
+	 * must or must not appear.
376
+	 *
377
+	 * Possible values per property:
378
+	 *   * 0 - Must not appear.
379
+	 *   * 1 - Must appear exactly once.
380
+	 *   * + - Must appear at least once.
381
+	 *   * * - Can appear any number of times.
382
+	 *   * ? - May appear, but not more than once.
383
+	 *
384
+	 * @var array
385
+	 */
386
+	public function getValidationRules()
387
+	{
388
+		return [
389
+			'PRODID' => 1,
390
+			'VERSION' => 1,
391
+
392
+			'CALSCALE' => '?',
393
+			'METHOD' => '?',
394
+		];
395
+	}
396
+
397
+	/**
398
+	 * Validates the node for correctness.
399
+	 *
400
+	 * The following options are supported:
401
+	 *   Node::REPAIR - May attempt to automatically repair the problem.
402
+	 *   Node::PROFILE_CARDDAV - Validate the vCard for CardDAV purposes.
403
+	 *   Node::PROFILE_CALDAV - Validate the iCalendar for CalDAV purposes.
404
+	 *
405
+	 * This method returns an array with detected problems.
406
+	 * Every element has the following properties:
407
+	 *
408
+	 *  * level - problem level.
409
+	 *  * message - A human-readable string describing the issue.
410
+	 *  * node - A reference to the problematic node.
411
+	 *
412
+	 * The level means:
413
+	 *   1 - The issue was repaired (only happens if REPAIR was turned on).
414
+	 *   2 - A warning.
415
+	 *   3 - An error.
416
+	 *
417
+	 * @param int $options
418
+	 *
419
+	 * @return array
420
+	 */
421
+	public function validate($options = 0)
422
+	{
423
+		$warnings = parent::validate($options);
424
+
425
+		if ($ver = $this->VERSION) {
426
+			if ('2.0' !== (string) $ver) {
427
+				$warnings[] = [
428
+					'level' => 3,
429
+					'message' => 'Only iCalendar version 2.0 as defined in rfc5545 is supported.',
430
+					'node' => $this,
431
+				];
432
+			}
433
+		}
434
+
435
+		$uidList = [];
436
+		$componentsFound = 0;
437
+		$componentTypes = [];
438
+
439
+		foreach ($this->children() as $child) {
440
+			if ($child instanceof Component) {
441
+				++$componentsFound;
442
+
443
+				if (!in_array($child->name, ['VEVENT', 'VTODO', 'VJOURNAL'])) {
444
+					continue;
445
+				}
446
+				$componentTypes[] = $child->name;
447
+
448
+				$uid = (string) $child->UID;
449
+				$isMaster = isset($child->{'RECURRENCE-ID'}) ? 0 : 1;
450
+				if (isset($uidList[$uid])) {
451
+					++$uidList[$uid]['count'];
452
+					if ($isMaster && $uidList[$uid]['hasMaster']) {
453
+						$warnings[] = [
454
+							'level' => 3,
455
+							'message' => 'More than one master object was found for the object with UID '.$uid,
456
+							'node' => $this,
457
+						];
458
+					}
459
+					$uidList[$uid]['hasMaster'] += $isMaster;
460
+				} else {
461
+					$uidList[$uid] = [
462
+						'count' => 1,
463
+						'hasMaster' => $isMaster,
464
+					];
465
+				}
466
+			}
467
+		}
468
+
469
+		if (0 === $componentsFound) {
470
+			$warnings[] = [
471
+				'level' => 3,
472
+				'message' => 'An iCalendar object must have at least 1 component.',
473
+				'node' => $this,
474
+			];
475
+		}
476
+
477
+		if ($options & self::PROFILE_CALDAV) {
478
+			if (count($uidList) > 1) {
479
+				$warnings[] = [
480
+					'level' => 3,
481
+					'message' => 'A calendar object on a CalDAV server may only have components with the same UID.',
482
+					'node' => $this,
483
+				];
484
+			}
485
+			if (0 === count($componentTypes)) {
486
+				$warnings[] = [
487
+					'level' => 3,
488
+					'message' => 'A calendar object on a CalDAV server must have at least 1 component (VTODO, VEVENT, VJOURNAL).',
489
+					'node' => $this,
490
+				];
491
+			}
492
+			if (count(array_unique($componentTypes)) > 1) {
493
+				$warnings[] = [
494
+					'level' => 3,
495
+					'message' => 'A calendar object on a CalDAV server may only have 1 type of component (VEVENT, VTODO or VJOURNAL).',
496
+					'node' => $this,
497
+				];
498
+			}
499
+
500
+			if (isset($this->METHOD)) {
501
+				$warnings[] = [
502
+					'level' => 3,
503
+					'message' => 'A calendar object on a CalDAV server MUST NOT have a METHOD property.',
504
+					'node' => $this,
505
+				];
506
+			}
507
+		}
508
+
509
+		return $warnings;
510
+	}
511
+
512
+	/**
513
+	 * Returns all components with a specific UID value.
514
+	 *
515
+	 * @return array
516
+	 */
517
+	public function getByUID($uid)
518
+	{
519
+		return array_filter($this->getComponents(), function ($item) use ($uid) {
520
+			if (!$itemUid = $item->select('UID')) {
521
+				return false;
522
+			}
523
+			$itemUid = current($itemUid)->getValue();
524
+
525
+			return $uid === $itemUid;
526
+		});
527
+	}
528 528
 }
Please login to merge, or discard this patch.
htdocs/includes/sabre/sabre/vobject/lib/Component/VAlarm.php 1 patch
Indentation   +105 added lines, -105 removed lines patch added patch discarded remove patch
@@ -18,121 +18,121 @@
 block discarded – undo
18 18
  */
19 19
 class VAlarm extends VObject\Component
20 20
 {
21
-    /**
22
-     * Returns a DateTime object when this alarm is going to trigger.
23
-     *
24
-     * This ignores repeated alarm, only the first trigger is returned.
25
-     *
26
-     * @return DateTimeImmutable
27
-     */
28
-    public function getEffectiveTriggerTime()
29
-    {
30
-        $trigger = $this->TRIGGER;
31
-        if (!isset($trigger['VALUE']) || 'DURATION' === strtoupper($trigger['VALUE'])) {
32
-            $triggerDuration = VObject\DateTimeParser::parseDuration($this->TRIGGER);
33
-            $related = (isset($trigger['RELATED']) && 'END' == strtoupper($trigger['RELATED'])) ? 'END' : 'START';
21
+	/**
22
+	 * Returns a DateTime object when this alarm is going to trigger.
23
+	 *
24
+	 * This ignores repeated alarm, only the first trigger is returned.
25
+	 *
26
+	 * @return DateTimeImmutable
27
+	 */
28
+	public function getEffectiveTriggerTime()
29
+	{
30
+		$trigger = $this->TRIGGER;
31
+		if (!isset($trigger['VALUE']) || 'DURATION' === strtoupper($trigger['VALUE'])) {
32
+			$triggerDuration = VObject\DateTimeParser::parseDuration($this->TRIGGER);
33
+			$related = (isset($trigger['RELATED']) && 'END' == strtoupper($trigger['RELATED'])) ? 'END' : 'START';
34 34
 
35
-            $parentComponent = $this->parent;
36
-            if ('START' === $related) {
37
-                if ('VTODO' === $parentComponent->name) {
38
-                    $propName = 'DUE';
39
-                } else {
40
-                    $propName = 'DTSTART';
41
-                }
35
+			$parentComponent = $this->parent;
36
+			if ('START' === $related) {
37
+				if ('VTODO' === $parentComponent->name) {
38
+					$propName = 'DUE';
39
+				} else {
40
+					$propName = 'DTSTART';
41
+				}
42 42
 
43
-                $effectiveTrigger = $parentComponent->$propName->getDateTime();
44
-                $effectiveTrigger = $effectiveTrigger->add($triggerDuration);
45
-            } else {
46
-                if ('VTODO' === $parentComponent->name) {
47
-                    $endProp = 'DUE';
48
-                } elseif ('VEVENT' === $parentComponent->name) {
49
-                    $endProp = 'DTEND';
50
-                } else {
51
-                    throw new InvalidDataException('time-range filters on VALARM components are only supported when they are a child of VTODO or VEVENT');
52
-                }
43
+				$effectiveTrigger = $parentComponent->$propName->getDateTime();
44
+				$effectiveTrigger = $effectiveTrigger->add($triggerDuration);
45
+			} else {
46
+				if ('VTODO' === $parentComponent->name) {
47
+					$endProp = 'DUE';
48
+				} elseif ('VEVENT' === $parentComponent->name) {
49
+					$endProp = 'DTEND';
50
+				} else {
51
+					throw new InvalidDataException('time-range filters on VALARM components are only supported when they are a child of VTODO or VEVENT');
52
+				}
53 53
 
54
-                if (isset($parentComponent->$endProp)) {
55
-                    $effectiveTrigger = $parentComponent->$endProp->getDateTime();
56
-                    $effectiveTrigger = $effectiveTrigger->add($triggerDuration);
57
-                } elseif (isset($parentComponent->DURATION)) {
58
-                    $effectiveTrigger = $parentComponent->DTSTART->getDateTime();
59
-                    $duration = VObject\DateTimeParser::parseDuration($parentComponent->DURATION);
60
-                    $effectiveTrigger = $effectiveTrigger->add($duration);
61
-                    $effectiveTrigger = $effectiveTrigger->add($triggerDuration);
62
-                } else {
63
-                    $effectiveTrigger = $parentComponent->DTSTART->getDateTime();
64
-                    $effectiveTrigger = $effectiveTrigger->add($triggerDuration);
65
-                }
66
-            }
67
-        } else {
68
-            $effectiveTrigger = $trigger->getDateTime();
69
-        }
54
+				if (isset($parentComponent->$endProp)) {
55
+					$effectiveTrigger = $parentComponent->$endProp->getDateTime();
56
+					$effectiveTrigger = $effectiveTrigger->add($triggerDuration);
57
+				} elseif (isset($parentComponent->DURATION)) {
58
+					$effectiveTrigger = $parentComponent->DTSTART->getDateTime();
59
+					$duration = VObject\DateTimeParser::parseDuration($parentComponent->DURATION);
60
+					$effectiveTrigger = $effectiveTrigger->add($duration);
61
+					$effectiveTrigger = $effectiveTrigger->add($triggerDuration);
62
+				} else {
63
+					$effectiveTrigger = $parentComponent->DTSTART->getDateTime();
64
+					$effectiveTrigger = $effectiveTrigger->add($triggerDuration);
65
+				}
66
+			}
67
+		} else {
68
+			$effectiveTrigger = $trigger->getDateTime();
69
+		}
70 70
 
71
-        return $effectiveTrigger;
72
-    }
71
+		return $effectiveTrigger;
72
+	}
73 73
 
74
-    /**
75
-     * Returns true or false depending on if the event falls in the specified
76
-     * time-range. This is used for filtering purposes.
77
-     *
78
-     * The rules used to determine if an event falls within the specified
79
-     * time-range is based on the CalDAV specification.
80
-     *
81
-     * @param DateTime $start
82
-     * @param DateTime $end
83
-     *
84
-     * @return bool
85
-     */
86
-    public function isInTimeRange(DateTimeInterface $start, DateTimeInterface $end)
87
-    {
88
-        $effectiveTrigger = $this->getEffectiveTriggerTime();
74
+	/**
75
+	 * Returns true or false depending on if the event falls in the specified
76
+	 * time-range. This is used for filtering purposes.
77
+	 *
78
+	 * The rules used to determine if an event falls within the specified
79
+	 * time-range is based on the CalDAV specification.
80
+	 *
81
+	 * @param DateTime $start
82
+	 * @param DateTime $end
83
+	 *
84
+	 * @return bool
85
+	 */
86
+	public function isInTimeRange(DateTimeInterface $start, DateTimeInterface $end)
87
+	{
88
+		$effectiveTrigger = $this->getEffectiveTriggerTime();
89 89
 
90
-        if (isset($this->DURATION)) {
91
-            $duration = VObject\DateTimeParser::parseDuration($this->DURATION);
92
-            $repeat = (string) $this->REPEAT;
93
-            if (!$repeat) {
94
-                $repeat = 1;
95
-            }
90
+		if (isset($this->DURATION)) {
91
+			$duration = VObject\DateTimeParser::parseDuration($this->DURATION);
92
+			$repeat = (string) $this->REPEAT;
93
+			if (!$repeat) {
94
+				$repeat = 1;
95
+			}
96 96
 
97
-            $period = new \DatePeriod($effectiveTrigger, $duration, (int) $repeat);
97
+			$period = new \DatePeriod($effectiveTrigger, $duration, (int) $repeat);
98 98
 
99
-            foreach ($period as $occurrence) {
100
-                if ($start <= $occurrence && $end > $occurrence) {
101
-                    return true;
102
-                }
103
-            }
99
+			foreach ($period as $occurrence) {
100
+				if ($start <= $occurrence && $end > $occurrence) {
101
+					return true;
102
+				}
103
+			}
104 104
 
105
-            return false;
106
-        } else {
107
-            return $start <= $effectiveTrigger && $end > $effectiveTrigger;
108
-        }
109
-    }
105
+			return false;
106
+		} else {
107
+			return $start <= $effectiveTrigger && $end > $effectiveTrigger;
108
+		}
109
+	}
110 110
 
111
-    /**
112
-     * A simple list of validation rules.
113
-     *
114
-     * This is simply a list of properties, and how many times they either
115
-     * must or must not appear.
116
-     *
117
-     * Possible values per property:
118
-     *   * 0 - Must not appear.
119
-     *   * 1 - Must appear exactly once.
120
-     *   * + - Must appear at least once.
121
-     *   * * - Can appear any number of times.
122
-     *   * ? - May appear, but not more than once.
123
-     *
124
-     * @var array
125
-     */
126
-    public function getValidationRules()
127
-    {
128
-        return [
129
-            'ACTION' => 1,
130
-            'TRIGGER' => 1,
111
+	/**
112
+	 * A simple list of validation rules.
113
+	 *
114
+	 * This is simply a list of properties, and how many times they either
115
+	 * must or must not appear.
116
+	 *
117
+	 * Possible values per property:
118
+	 *   * 0 - Must not appear.
119
+	 *   * 1 - Must appear exactly once.
120
+	 *   * + - Must appear at least once.
121
+	 *   * * - Can appear any number of times.
122
+	 *   * ? - May appear, but not more than once.
123
+	 *
124
+	 * @var array
125
+	 */
126
+	public function getValidationRules()
127
+	{
128
+		return [
129
+			'ACTION' => 1,
130
+			'TRIGGER' => 1,
131 131
 
132
-            'DURATION' => '?',
133
-            'REPEAT' => '?',
132
+			'DURATION' => '?',
133
+			'REPEAT' => '?',
134 134
 
135
-            'ATTACH' => '?',
136
-        ];
137
-    }
135
+			'ATTACH' => '?',
136
+		];
137
+	}
138 138
 }
Please login to merge, or discard this patch.
htdocs/includes/sabre/sabre/vobject/lib/Component/VTodo.php 1 patch
Indentation   +151 added lines, -151 removed lines patch added patch discarded remove patch
@@ -16,166 +16,166 @@
 block discarded – undo
16 16
  */
17 17
 class VTodo extends VObject\Component
18 18
 {
19
-    /**
20
-     * Returns true or false depending on if the event falls in the specified
21
-     * time-range. This is used for filtering purposes.
22
-     *
23
-     * The rules used to determine if an event falls within the specified
24
-     * time-range is based on the CalDAV specification.
25
-     *
26
-     * @return bool
27
-     */
28
-    public function isInTimeRange(DateTimeInterface $start, DateTimeInterface $end)
29
-    {
30
-        $dtstart = isset($this->DTSTART) ? $this->DTSTART->getDateTime() : null;
31
-        $duration = isset($this->DURATION) ? VObject\DateTimeParser::parseDuration($this->DURATION) : null;
32
-        $due = isset($this->DUE) ? $this->DUE->getDateTime() : null;
33
-        $completed = isset($this->COMPLETED) ? $this->COMPLETED->getDateTime() : null;
34
-        $created = isset($this->CREATED) ? $this->CREATED->getDateTime() : null;
19
+	/**
20
+	 * Returns true or false depending on if the event falls in the specified
21
+	 * time-range. This is used for filtering purposes.
22
+	 *
23
+	 * The rules used to determine if an event falls within the specified
24
+	 * time-range is based on the CalDAV specification.
25
+	 *
26
+	 * @return bool
27
+	 */
28
+	public function isInTimeRange(DateTimeInterface $start, DateTimeInterface $end)
29
+	{
30
+		$dtstart = isset($this->DTSTART) ? $this->DTSTART->getDateTime() : null;
31
+		$duration = isset($this->DURATION) ? VObject\DateTimeParser::parseDuration($this->DURATION) : null;
32
+		$due = isset($this->DUE) ? $this->DUE->getDateTime() : null;
33
+		$completed = isset($this->COMPLETED) ? $this->COMPLETED->getDateTime() : null;
34
+		$created = isset($this->CREATED) ? $this->CREATED->getDateTime() : null;
35 35
 
36
-        if ($dtstart) {
37
-            if ($duration) {
38
-                $effectiveEnd = $dtstart->add($duration);
36
+		if ($dtstart) {
37
+			if ($duration) {
38
+				$effectiveEnd = $dtstart->add($duration);
39 39
 
40
-                return $start <= $effectiveEnd && $end > $dtstart;
41
-            } elseif ($due) {
42
-                return
43
-                    ($start < $due || $start <= $dtstart) &&
44
-                    ($end > $dtstart || $end >= $due);
45
-            } else {
46
-                return $start <= $dtstart && $end > $dtstart;
47
-            }
48
-        }
49
-        if ($due) {
50
-            return $start < $due && $end >= $due;
51
-        }
52
-        if ($completed && $created) {
53
-            return
54
-                ($start <= $created || $start <= $completed) &&
55
-                ($end >= $created || $end >= $completed);
56
-        }
57
-        if ($completed) {
58
-            return $start <= $completed && $end >= $completed;
59
-        }
60
-        if ($created) {
61
-            return $end > $created;
62
-        }
40
+				return $start <= $effectiveEnd && $end > $dtstart;
41
+			} elseif ($due) {
42
+				return
43
+					($start < $due || $start <= $dtstart) &&
44
+					($end > $dtstart || $end >= $due);
45
+			} else {
46
+				return $start <= $dtstart && $end > $dtstart;
47
+			}
48
+		}
49
+		if ($due) {
50
+			return $start < $due && $end >= $due;
51
+		}
52
+		if ($completed && $created) {
53
+			return
54
+				($start <= $created || $start <= $completed) &&
55
+				($end >= $created || $end >= $completed);
56
+		}
57
+		if ($completed) {
58
+			return $start <= $completed && $end >= $completed;
59
+		}
60
+		if ($created) {
61
+			return $end > $created;
62
+		}
63 63
 
64
-        return true;
65
-    }
64
+		return true;
65
+	}
66 66
 
67
-    /**
68
-     * A simple list of validation rules.
69
-     *
70
-     * This is simply a list of properties, and how many times they either
71
-     * must or must not appear.
72
-     *
73
-     * Possible values per property:
74
-     *   * 0 - Must not appear.
75
-     *   * 1 - Must appear exactly once.
76
-     *   * + - Must appear at least once.
77
-     *   * * - Can appear any number of times.
78
-     *   * ? - May appear, but not more than once.
79
-     *
80
-     * @var array
81
-     */
82
-    public function getValidationRules()
83
-    {
84
-        return [
85
-            'UID' => 1,
86
-            'DTSTAMP' => 1,
67
+	/**
68
+	 * A simple list of validation rules.
69
+	 *
70
+	 * This is simply a list of properties, and how many times they either
71
+	 * must or must not appear.
72
+	 *
73
+	 * Possible values per property:
74
+	 *   * 0 - Must not appear.
75
+	 *   * 1 - Must appear exactly once.
76
+	 *   * + - Must appear at least once.
77
+	 *   * * - Can appear any number of times.
78
+	 *   * ? - May appear, but not more than once.
79
+	 *
80
+	 * @var array
81
+	 */
82
+	public function getValidationRules()
83
+	{
84
+		return [
85
+			'UID' => 1,
86
+			'DTSTAMP' => 1,
87 87
 
88
-            'CLASS' => '?',
89
-            'COMPLETED' => '?',
90
-            'CREATED' => '?',
91
-            'DESCRIPTION' => '?',
92
-            'DTSTART' => '?',
93
-            'GEO' => '?',
94
-            'LAST-MODIFIED' => '?',
95
-            'LOCATION' => '?',
96
-            'ORGANIZER' => '?',
97
-            'PERCENT' => '?',
98
-            'PRIORITY' => '?',
99
-            'RECURRENCE-ID' => '?',
100
-            'SEQUENCE' => '?',
101
-            'STATUS' => '?',
102
-            'SUMMARY' => '?',
103
-            'URL' => '?',
88
+			'CLASS' => '?',
89
+			'COMPLETED' => '?',
90
+			'CREATED' => '?',
91
+			'DESCRIPTION' => '?',
92
+			'DTSTART' => '?',
93
+			'GEO' => '?',
94
+			'LAST-MODIFIED' => '?',
95
+			'LOCATION' => '?',
96
+			'ORGANIZER' => '?',
97
+			'PERCENT' => '?',
98
+			'PRIORITY' => '?',
99
+			'RECURRENCE-ID' => '?',
100
+			'SEQUENCE' => '?',
101
+			'STATUS' => '?',
102
+			'SUMMARY' => '?',
103
+			'URL' => '?',
104 104
 
105
-            'RRULE' => '?',
106
-            'DUE' => '?',
107
-            'DURATION' => '?',
105
+			'RRULE' => '?',
106
+			'DUE' => '?',
107
+			'DURATION' => '?',
108 108
 
109
-            'ATTACH' => '*',
110
-            'ATTENDEE' => '*',
111
-            'CATEGORIES' => '*',
112
-            'COMMENT' => '*',
113
-            'CONTACT' => '*',
114
-            'EXDATE' => '*',
115
-            'REQUEST-STATUS' => '*',
116
-            'RELATED-TO' => '*',
117
-            'RESOURCES' => '*',
118
-            'RDATE' => '*',
119
-        ];
120
-    }
109
+			'ATTACH' => '*',
110
+			'ATTENDEE' => '*',
111
+			'CATEGORIES' => '*',
112
+			'COMMENT' => '*',
113
+			'CONTACT' => '*',
114
+			'EXDATE' => '*',
115
+			'REQUEST-STATUS' => '*',
116
+			'RELATED-TO' => '*',
117
+			'RESOURCES' => '*',
118
+			'RDATE' => '*',
119
+		];
120
+	}
121 121
 
122
-    /**
123
-     * Validates the node for correctness.
124
-     *
125
-     * The following options are supported:
126
-     *   Node::REPAIR - May attempt to automatically repair the problem.
127
-     *
128
-     * This method returns an array with detected problems.
129
-     * Every element has the following properties:
130
-     *
131
-     *  * level - problem level.
132
-     *  * message - A human-readable string describing the issue.
133
-     *  * node - A reference to the problematic node.
134
-     *
135
-     * The level means:
136
-     *   1 - The issue was repaired (only happens if REPAIR was turned on)
137
-     *   2 - An inconsequential issue
138
-     *   3 - A severe issue.
139
-     *
140
-     * @param int $options
141
-     *
142
-     * @return array
143
-     */
144
-    public function validate($options = 0)
145
-    {
146
-        $result = parent::validate($options);
147
-        if (isset($this->DUE) && isset($this->DTSTART)) {
148
-            $due = $this->DUE;
149
-            $dtStart = $this->DTSTART;
122
+	/**
123
+	 * Validates the node for correctness.
124
+	 *
125
+	 * The following options are supported:
126
+	 *   Node::REPAIR - May attempt to automatically repair the problem.
127
+	 *
128
+	 * This method returns an array with detected problems.
129
+	 * Every element has the following properties:
130
+	 *
131
+	 *  * level - problem level.
132
+	 *  * message - A human-readable string describing the issue.
133
+	 *  * node - A reference to the problematic node.
134
+	 *
135
+	 * The level means:
136
+	 *   1 - The issue was repaired (only happens if REPAIR was turned on)
137
+	 *   2 - An inconsequential issue
138
+	 *   3 - A severe issue.
139
+	 *
140
+	 * @param int $options
141
+	 *
142
+	 * @return array
143
+	 */
144
+	public function validate($options = 0)
145
+	{
146
+		$result = parent::validate($options);
147
+		if (isset($this->DUE) && isset($this->DTSTART)) {
148
+			$due = $this->DUE;
149
+			$dtStart = $this->DTSTART;
150 150
 
151
-            if ($due->getValueType() !== $dtStart->getValueType()) {
152
-                $result[] = [
153
-                    'level' => 3,
154
-                    'message' => 'The value type (DATE or DATE-TIME) must be identical for DUE and DTSTART',
155
-                    'node' => $due,
156
-                ];
157
-            } elseif ($due->getDateTime() < $dtStart->getDateTime()) {
158
-                $result[] = [
159
-                    'level' => 3,
160
-                    'message' => 'DUE must occur after DTSTART',
161
-                    'node' => $due,
162
-                ];
163
-            }
164
-        }
151
+			if ($due->getValueType() !== $dtStart->getValueType()) {
152
+				$result[] = [
153
+					'level' => 3,
154
+					'message' => 'The value type (DATE or DATE-TIME) must be identical for DUE and DTSTART',
155
+					'node' => $due,
156
+				];
157
+			} elseif ($due->getDateTime() < $dtStart->getDateTime()) {
158
+				$result[] = [
159
+					'level' => 3,
160
+					'message' => 'DUE must occur after DTSTART',
161
+					'node' => $due,
162
+				];
163
+			}
164
+		}
165 165
 
166
-        return $result;
167
-    }
166
+		return $result;
167
+	}
168 168
 
169
-    /**
170
-     * This method should return a list of default property values.
171
-     *
172
-     * @return array
173
-     */
174
-    protected function getDefaults()
175
-    {
176
-        return [
177
-            'UID' => 'sabre-vobject-'.VObject\UUIDUtil::getUUID(),
178
-            'DTSTAMP' => date('Ymd\\THis\\Z'),
179
-        ];
180
-    }
169
+	/**
170
+	 * This method should return a list of default property values.
171
+	 *
172
+	 * @return array
173
+	 */
174
+	protected function getDefaults()
175
+	{
176
+		return [
177
+			'UID' => 'sabre-vobject-'.VObject\UUIDUtil::getUUID(),
178
+			'DTSTAMP' => date('Ymd\\THis\\Z'),
179
+		];
180
+	}
181 181
 }
Please login to merge, or discard this patch.
htdocs/includes/sabre/sabre/vobject/lib/Component/VFreeBusy.php 1 patch
Indentation   +65 added lines, -65 removed lines patch added patch discarded remove patch
@@ -17,77 +17,77 @@
 block discarded – undo
17 17
  */
18 18
 class VFreeBusy extends VObject\Component
19 19
 {
20
-    /**
21
-     * Checks based on the contained FREEBUSY information, if a timeslot is
22
-     * available.
23
-     *
24
-     * @return bool
25
-     */
26
-    public function isFree(DateTimeInterface $start, DatetimeInterface $end)
27
-    {
28
-        foreach ($this->select('FREEBUSY') as $freebusy) {
29
-            // We are only interested in FBTYPE=BUSY (the default),
30
-            // FBTYPE=BUSY-TENTATIVE or FBTYPE=BUSY-UNAVAILABLE.
31
-            if (isset($freebusy['FBTYPE']) && 'BUSY' !== strtoupper(substr((string) $freebusy['FBTYPE'], 0, 4))) {
32
-                continue;
33
-            }
20
+	/**
21
+	 * Checks based on the contained FREEBUSY information, if a timeslot is
22
+	 * available.
23
+	 *
24
+	 * @return bool
25
+	 */
26
+	public function isFree(DateTimeInterface $start, DatetimeInterface $end)
27
+	{
28
+		foreach ($this->select('FREEBUSY') as $freebusy) {
29
+			// We are only interested in FBTYPE=BUSY (the default),
30
+			// FBTYPE=BUSY-TENTATIVE or FBTYPE=BUSY-UNAVAILABLE.
31
+			if (isset($freebusy['FBTYPE']) && 'BUSY' !== strtoupper(substr((string) $freebusy['FBTYPE'], 0, 4))) {
32
+				continue;
33
+			}
34 34
 
35
-            // The freebusy component can hold more than 1 value, separated by
36
-            // commas.
37
-            $periods = explode(',', (string) $freebusy);
35
+			// The freebusy component can hold more than 1 value, separated by
36
+			// commas.
37
+			$periods = explode(',', (string) $freebusy);
38 38
 
39
-            foreach ($periods as $period) {
40
-                // Every period is formatted as [start]/[end]. The start is an
41
-                // absolute UTC time, the end may be an absolute UTC time, or
42
-                // duration (relative) value.
43
-                list($busyStart, $busyEnd) = explode('/', $period);
39
+			foreach ($periods as $period) {
40
+				// Every period is formatted as [start]/[end]. The start is an
41
+				// absolute UTC time, the end may be an absolute UTC time, or
42
+				// duration (relative) value.
43
+				list($busyStart, $busyEnd) = explode('/', $period);
44 44
 
45
-                $busyStart = VObject\DateTimeParser::parse($busyStart);
46
-                $busyEnd = VObject\DateTimeParser::parse($busyEnd);
47
-                if ($busyEnd instanceof \DateInterval) {
48
-                    $busyEnd = $busyStart->add($busyEnd);
49
-                }
45
+				$busyStart = VObject\DateTimeParser::parse($busyStart);
46
+				$busyEnd = VObject\DateTimeParser::parse($busyEnd);
47
+				if ($busyEnd instanceof \DateInterval) {
48
+					$busyEnd = $busyStart->add($busyEnd);
49
+				}
50 50
 
51
-                if ($start < $busyEnd && $end > $busyStart) {
52
-                    return false;
53
-                }
54
-            }
55
-        }
51
+				if ($start < $busyEnd && $end > $busyStart) {
52
+					return false;
53
+				}
54
+			}
55
+		}
56 56
 
57
-        return true;
58
-    }
57
+		return true;
58
+	}
59 59
 
60
-    /**
61
-     * A simple list of validation rules.
62
-     *
63
-     * This is simply a list of properties, and how many times they either
64
-     * must or must not appear.
65
-     *
66
-     * Possible values per property:
67
-     *   * 0 - Must not appear.
68
-     *   * 1 - Must appear exactly once.
69
-     *   * + - Must appear at least once.
70
-     *   * * - Can appear any number of times.
71
-     *   * ? - May appear, but not more than once.
72
-     *
73
-     * @var array
74
-     */
75
-    public function getValidationRules()
76
-    {
77
-        return [
78
-            'UID' => 1,
79
-            'DTSTAMP' => 1,
60
+	/**
61
+	 * A simple list of validation rules.
62
+	 *
63
+	 * This is simply a list of properties, and how many times they either
64
+	 * must or must not appear.
65
+	 *
66
+	 * Possible values per property:
67
+	 *   * 0 - Must not appear.
68
+	 *   * 1 - Must appear exactly once.
69
+	 *   * + - Must appear at least once.
70
+	 *   * * - Can appear any number of times.
71
+	 *   * ? - May appear, but not more than once.
72
+	 *
73
+	 * @var array
74
+	 */
75
+	public function getValidationRules()
76
+	{
77
+		return [
78
+			'UID' => 1,
79
+			'DTSTAMP' => 1,
80 80
 
81
-            'CONTACT' => '?',
82
-            'DTSTART' => '?',
83
-            'DTEND' => '?',
84
-            'ORGANIZER' => '?',
85
-            'URL' => '?',
81
+			'CONTACT' => '?',
82
+			'DTSTART' => '?',
83
+			'DTEND' => '?',
84
+			'ORGANIZER' => '?',
85
+			'URL' => '?',
86 86
 
87
-            'ATTENDEE' => '*',
88
-            'COMMENT' => '*',
89
-            'FREEBUSY' => '*',
90
-            'REQUEST-STATUS' => '*',
91
-        ];
92
-    }
87
+			'ATTENDEE' => '*',
88
+			'COMMENT' => '*',
89
+			'FREEBUSY' => '*',
90
+			'REQUEST-STATUS' => '*',
91
+		];
92
+	}
93 93
 }
Please login to merge, or discard this patch.
htdocs/includes/sabre/sabre/vobject/lib/Component/VEvent.php 1 patch
Indentation   +111 added lines, -111 removed lines patch added patch discarded remove patch
@@ -18,123 +18,123 @@
 block discarded – undo
18 18
  */
19 19
 class VEvent extends VObject\Component
20 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
-     * @return bool
29
-     */
30
-    public function isInTimeRange(DateTimeInterface $start, DateTimeInterface $end)
31
-    {
32
-        if ($this->RRULE) {
33
-            try {
34
-                $it = new EventIterator($this, null, $start->getTimezone());
35
-            } catch (NoInstancesException $e) {
36
-                // If we've caught this exception, there are no instances
37
-                // for the event that fall into the specified time-range.
38
-                return false;
39
-            }
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
+	 * @return bool
29
+	 */
30
+	public function isInTimeRange(DateTimeInterface $start, DateTimeInterface $end)
31
+	{
32
+		if ($this->RRULE) {
33
+			try {
34
+				$it = new EventIterator($this, null, $start->getTimezone());
35
+			} catch (NoInstancesException $e) {
36
+				// If we've caught this exception, there are no instances
37
+				// for the event that fall into the specified time-range.
38
+				return false;
39
+			}
40 40
 
41
-            $it->fastForward($start);
41
+			$it->fastForward($start);
42 42
 
43
-            // We fast-forwarded to a spot where the end-time of the
44
-            // recurrence instance exceeded the start of the requested
45
-            // time-range.
46
-            //
47
-            // If the starttime of the recurrence did not exceed the
48
-            // end of the time range as well, we have a match.
49
-            return $it->getDTStart() < $end && $it->getDTEnd() > $start;
50
-        }
43
+			// We fast-forwarded to a spot where the end-time of the
44
+			// recurrence instance exceeded the start of the requested
45
+			// time-range.
46
+			//
47
+			// If the starttime of the recurrence did not exceed the
48
+			// end of the time range as well, we have a match.
49
+			return $it->getDTStart() < $end && $it->getDTEnd() > $start;
50
+		}
51 51
 
52
-        $effectiveStart = $this->DTSTART->getDateTime($start->getTimezone());
53
-        if (isset($this->DTEND)) {
54
-            // The DTEND property is considered non inclusive. So for a 3 day
55
-            // event in july, dtstart and dtend would have to be July 1st and
56
-            // July 4th respectively.
57
-            //
58
-            // See:
59
-            // http://tools.ietf.org/html/rfc5545#page-54
60
-            $effectiveEnd = $this->DTEND->getDateTime($end->getTimezone());
61
-        } elseif (isset($this->DURATION)) {
62
-            $effectiveEnd = $effectiveStart->add(VObject\DateTimeParser::parseDuration($this->DURATION));
63
-        } elseif (!$this->DTSTART->hasTime()) {
64
-            $effectiveEnd = $effectiveStart->modify('+1 day');
65
-        } else {
66
-            $effectiveEnd = $effectiveStart;
67
-        }
52
+		$effectiveStart = $this->DTSTART->getDateTime($start->getTimezone());
53
+		if (isset($this->DTEND)) {
54
+			// The DTEND property is considered non inclusive. So for a 3 day
55
+			// event in july, dtstart and dtend would have to be July 1st and
56
+			// July 4th respectively.
57
+			//
58
+			// See:
59
+			// http://tools.ietf.org/html/rfc5545#page-54
60
+			$effectiveEnd = $this->DTEND->getDateTime($end->getTimezone());
61
+		} elseif (isset($this->DURATION)) {
62
+			$effectiveEnd = $effectiveStart->add(VObject\DateTimeParser::parseDuration($this->DURATION));
63
+		} elseif (!$this->DTSTART->hasTime()) {
64
+			$effectiveEnd = $effectiveStart->modify('+1 day');
65
+		} else {
66
+			$effectiveEnd = $effectiveStart;
67
+		}
68 68
 
69
-        return
70
-            ($start < $effectiveEnd) && ($end > $effectiveStart)
71
-        ;
72
-    }
69
+		return
70
+			($start < $effectiveEnd) && ($end > $effectiveStart)
71
+		;
72
+	}
73 73
 
74
-    /**
75
-     * This method should return a list of default property values.
76
-     *
77
-     * @return array
78
-     */
79
-    protected function getDefaults()
80
-    {
81
-        return [
82
-            'UID' => 'sabre-vobject-'.VObject\UUIDUtil::getUUID(),
83
-            'DTSTAMP' => gmdate('Ymd\\THis\\Z'),
84
-        ];
85
-    }
74
+	/**
75
+	 * This method should return a list of default property values.
76
+	 *
77
+	 * @return array
78
+	 */
79
+	protected function getDefaults()
80
+	{
81
+		return [
82
+			'UID' => 'sabre-vobject-'.VObject\UUIDUtil::getUUID(),
83
+			'DTSTAMP' => gmdate('Ymd\\THis\\Z'),
84
+		];
85
+	}
86 86
 
87
-    /**
88
-     * A simple list of validation rules.
89
-     *
90
-     * This is simply a list of properties, and how many times they either
91
-     * must or must not appear.
92
-     *
93
-     * Possible values per property:
94
-     *   * 0 - Must not appear.
95
-     *   * 1 - Must appear exactly once.
96
-     *   * + - Must appear at least once.
97
-     *   * * - Can appear any number of times.
98
-     *   * ? - May appear, but not more than once.
99
-     *
100
-     * @var array
101
-     */
102
-    public function getValidationRules()
103
-    {
104
-        $hasMethod = isset($this->parent->METHOD);
87
+	/**
88
+	 * A simple list of validation rules.
89
+	 *
90
+	 * This is simply a list of properties, and how many times they either
91
+	 * must or must not appear.
92
+	 *
93
+	 * Possible values per property:
94
+	 *   * 0 - Must not appear.
95
+	 *   * 1 - Must appear exactly once.
96
+	 *   * + - Must appear at least once.
97
+	 *   * * - Can appear any number of times.
98
+	 *   * ? - May appear, but not more than once.
99
+	 *
100
+	 * @var array
101
+	 */
102
+	public function getValidationRules()
103
+	{
104
+		$hasMethod = isset($this->parent->METHOD);
105 105
 
106
-        return [
107
-            'UID' => 1,
108
-            'DTSTAMP' => 1,
109
-            'DTSTART' => $hasMethod ? '?' : '1',
110
-            'CLASS' => '?',
111
-            'CREATED' => '?',
112
-            'DESCRIPTION' => '?',
113
-            'GEO' => '?',
114
-            'LAST-MODIFIED' => '?',
115
-            'LOCATION' => '?',
116
-            'ORGANIZER' => '?',
117
-            'PRIORITY' => '?',
118
-            'SEQUENCE' => '?',
119
-            'STATUS' => '?',
120
-            'SUMMARY' => '?',
121
-            'TRANSP' => '?',
122
-            'URL' => '?',
123
-            'RECURRENCE-ID' => '?',
124
-            'RRULE' => '?',
125
-            'DTEND' => '?',
126
-            'DURATION' => '?',
106
+		return [
107
+			'UID' => 1,
108
+			'DTSTAMP' => 1,
109
+			'DTSTART' => $hasMethod ? '?' : '1',
110
+			'CLASS' => '?',
111
+			'CREATED' => '?',
112
+			'DESCRIPTION' => '?',
113
+			'GEO' => '?',
114
+			'LAST-MODIFIED' => '?',
115
+			'LOCATION' => '?',
116
+			'ORGANIZER' => '?',
117
+			'PRIORITY' => '?',
118
+			'SEQUENCE' => '?',
119
+			'STATUS' => '?',
120
+			'SUMMARY' => '?',
121
+			'TRANSP' => '?',
122
+			'URL' => '?',
123
+			'RECURRENCE-ID' => '?',
124
+			'RRULE' => '?',
125
+			'DTEND' => '?',
126
+			'DURATION' => '?',
127 127
 
128
-            'ATTACH' => '*',
129
-            'ATTENDEE' => '*',
130
-            'CATEGORIES' => '*',
131
-            'COMMENT' => '*',
132
-            'CONTACT' => '*',
133
-            'EXDATE' => '*',
134
-            'REQUEST-STATUS' => '*',
135
-            'RELATED-TO' => '*',
136
-            'RESOURCES' => '*',
137
-            'RDATE' => '*',
138
-        ];
139
-    }
128
+			'ATTACH' => '*',
129
+			'ATTENDEE' => '*',
130
+			'CATEGORIES' => '*',
131
+			'COMMENT' => '*',
132
+			'CONTACT' => '*',
133
+			'EXDATE' => '*',
134
+			'REQUEST-STATUS' => '*',
135
+			'RELATED-TO' => '*',
136
+			'RESOURCES' => '*',
137
+			'RDATE' => '*',
138
+		];
139
+	}
140 140
 }
Please login to merge, or discard this patch.
htdocs/includes/sabre/sabre/vobject/lib/Component/VTimeZone.php 1 patch
Indentation   +41 added lines, -41 removed lines patch added patch discarded remove patch
@@ -16,48 +16,48 @@
 block discarded – undo
16 16
  */
17 17
 class VTimeZone extends VObject\Component
18 18
 {
19
-    /**
20
-     * Returns the PHP DateTimeZone for this VTIMEZONE component.
21
-     *
22
-     * If we can't accurately determine the timezone, this method will return
23
-     * UTC.
24
-     *
25
-     * @return \DateTimeZone
26
-     */
27
-    public function getTimeZone()
28
-    {
29
-        return VObject\TimeZoneUtil::getTimeZone((string) $this->TZID, $this->root);
30
-    }
19
+	/**
20
+	 * Returns the PHP DateTimeZone for this VTIMEZONE component.
21
+	 *
22
+	 * If we can't accurately determine the timezone, this method will return
23
+	 * UTC.
24
+	 *
25
+	 * @return \DateTimeZone
26
+	 */
27
+	public function getTimeZone()
28
+	{
29
+		return VObject\TimeZoneUtil::getTimeZone((string) $this->TZID, $this->root);
30
+	}
31 31
 
32
-    /**
33
-     * A simple list of validation rules.
34
-     *
35
-     * This is simply a list of properties, and how many times they either
36
-     * must or must not appear.
37
-     *
38
-     * Possible values per property:
39
-     *   * 0 - Must not appear.
40
-     *   * 1 - Must appear exactly once.
41
-     *   * + - Must appear at least once.
42
-     *   * * - Can appear any number of times.
43
-     *   * ? - May appear, but not more than once.
44
-     *
45
-     * @var array
46
-     */
47
-    public function getValidationRules()
48
-    {
49
-        return [
50
-            'TZID' => 1,
32
+	/**
33
+	 * A simple list of validation rules.
34
+	 *
35
+	 * This is simply a list of properties, and how many times they either
36
+	 * must or must not appear.
37
+	 *
38
+	 * Possible values per property:
39
+	 *   * 0 - Must not appear.
40
+	 *   * 1 - Must appear exactly once.
41
+	 *   * + - Must appear at least once.
42
+	 *   * * - Can appear any number of times.
43
+	 *   * ? - May appear, but not more than once.
44
+	 *
45
+	 * @var array
46
+	 */
47
+	public function getValidationRules()
48
+	{
49
+		return [
50
+			'TZID' => 1,
51 51
 
52
-            'LAST-MODIFIED' => '?',
53
-            'TZURL' => '?',
52
+			'LAST-MODIFIED' => '?',
53
+			'TZURL' => '?',
54 54
 
55
-            // At least 1 STANDARD or DAYLIGHT must appear.
56
-            //
57
-            // The validator is not specific yet to pick this up, so these
58
-            // rules are too loose.
59
-            'STANDARD' => '*',
60
-            'DAYLIGHT' => '*',
61
-        ];
62
-    }
55
+			// At least 1 STANDARD or DAYLIGHT must appear.
56
+			//
57
+			// The validator is not specific yet to pick this up, so these
58
+			// rules are too loose.
59
+			'STANDARD' => '*',
60
+			'DAYLIGHT' => '*',
61
+		];
62
+	}
63 63
 }
Please login to merge, or discard this patch.
htdocs/includes/sabre/sabre/vobject/lib/Component/Available.php 1 patch
Indentation   +95 added lines, -95 removed lines patch added patch discarded remove patch
@@ -16,108 +16,108 @@
 block discarded – undo
16 16
  */
17 17
 class Available extends VObject\Component
18 18
 {
19
-    /**
20
-     * Returns the 'effective start' and 'effective end' of this VAVAILABILITY
21
-     * component.
22
-     *
23
-     * We use the DTSTART and DTEND or DURATION to determine this.
24
-     *
25
-     * The returned value is an array containing DateTimeImmutable instances.
26
-     * If either the start or end is 'unbounded' its value will be null
27
-     * instead.
28
-     *
29
-     * @return array
30
-     */
31
-    public function getEffectiveStartEnd()
32
-    {
33
-        $effectiveStart = $this->DTSTART->getDateTime();
34
-        if (isset($this->DTEND)) {
35
-            $effectiveEnd = $this->DTEND->getDateTime();
36
-        } else {
37
-            $effectiveEnd = $effectiveStart->add(VObject\DateTimeParser::parseDuration($this->DURATION));
38
-        }
19
+	/**
20
+	 * Returns the 'effective start' and 'effective end' of this VAVAILABILITY
21
+	 * component.
22
+	 *
23
+	 * We use the DTSTART and DTEND or DURATION to determine this.
24
+	 *
25
+	 * The returned value is an array containing DateTimeImmutable instances.
26
+	 * If either the start or end is 'unbounded' its value will be null
27
+	 * instead.
28
+	 *
29
+	 * @return array
30
+	 */
31
+	public function getEffectiveStartEnd()
32
+	{
33
+		$effectiveStart = $this->DTSTART->getDateTime();
34
+		if (isset($this->DTEND)) {
35
+			$effectiveEnd = $this->DTEND->getDateTime();
36
+		} else {
37
+			$effectiveEnd = $effectiveStart->add(VObject\DateTimeParser::parseDuration($this->DURATION));
38
+		}
39 39
 
40
-        return [$effectiveStart, $effectiveEnd];
41
-    }
40
+		return [$effectiveStart, $effectiveEnd];
41
+	}
42 42
 
43
-    /**
44
-     * A simple list of validation rules.
45
-     *
46
-     * This is simply a list of properties, and how many times they either
47
-     * must or must not appear.
48
-     *
49
-     * Possible values per property:
50
-     *   * 0 - Must not appear.
51
-     *   * 1 - Must appear exactly once.
52
-     *   * + - Must appear at least once.
53
-     *   * * - Can appear any number of times.
54
-     *   * ? - May appear, but not more than once.
55
-     *
56
-     * @var array
57
-     */
58
-    public function getValidationRules()
59
-    {
60
-        return [
61
-            'UID' => 1,
62
-            'DTSTART' => 1,
63
-            'DTSTAMP' => 1,
43
+	/**
44
+	 * A simple list of validation rules.
45
+	 *
46
+	 * This is simply a list of properties, and how many times they either
47
+	 * must or must not appear.
48
+	 *
49
+	 * Possible values per property:
50
+	 *   * 0 - Must not appear.
51
+	 *   * 1 - Must appear exactly once.
52
+	 *   * + - Must appear at least once.
53
+	 *   * * - Can appear any number of times.
54
+	 *   * ? - May appear, but not more than once.
55
+	 *
56
+	 * @var array
57
+	 */
58
+	public function getValidationRules()
59
+	{
60
+		return [
61
+			'UID' => 1,
62
+			'DTSTART' => 1,
63
+			'DTSTAMP' => 1,
64 64
 
65
-            'DTEND' => '?',
66
-            'DURATION' => '?',
65
+			'DTEND' => '?',
66
+			'DURATION' => '?',
67 67
 
68
-            'CREATED' => '?',
69
-            'DESCRIPTION' => '?',
70
-            'LAST-MODIFIED' => '?',
71
-            'RECURRENCE-ID' => '?',
72
-            'RRULE' => '?',
73
-            'SUMMARY' => '?',
68
+			'CREATED' => '?',
69
+			'DESCRIPTION' => '?',
70
+			'LAST-MODIFIED' => '?',
71
+			'RECURRENCE-ID' => '?',
72
+			'RRULE' => '?',
73
+			'SUMMARY' => '?',
74 74
 
75
-            'CATEGORIES' => '*',
76
-            'COMMENT' => '*',
77
-            'CONTACT' => '*',
78
-            'EXDATE' => '*',
79
-            'RDATE' => '*',
75
+			'CATEGORIES' => '*',
76
+			'COMMENT' => '*',
77
+			'CONTACT' => '*',
78
+			'EXDATE' => '*',
79
+			'RDATE' => '*',
80 80
 
81
-            'AVAILABLE' => '*',
82
-        ];
83
-    }
81
+			'AVAILABLE' => '*',
82
+		];
83
+	}
84 84
 
85
-    /**
86
-     * Validates the node for correctness.
87
-     *
88
-     * The following options are supported:
89
-     *   Node::REPAIR - May attempt to automatically repair the problem.
90
-     *   Node::PROFILE_CARDDAV - Validate the vCard for CardDAV purposes.
91
-     *   Node::PROFILE_CALDAV - Validate the iCalendar for CalDAV purposes.
92
-     *
93
-     * This method returns an array with detected problems.
94
-     * Every element has the following properties:
95
-     *
96
-     *  * level - problem level.
97
-     *  * message - A human-readable string describing the issue.
98
-     *  * node - A reference to the problematic node.
99
-     *
100
-     * The level means:
101
-     *   1 - The issue was repaired (only happens if REPAIR was turned on).
102
-     *   2 - A warning.
103
-     *   3 - An error.
104
-     *
105
-     * @param int $options
106
-     *
107
-     * @return array
108
-     */
109
-    public function validate($options = 0)
110
-    {
111
-        $result = parent::validate($options);
85
+	/**
86
+	 * Validates the node for correctness.
87
+	 *
88
+	 * The following options are supported:
89
+	 *   Node::REPAIR - May attempt to automatically repair the problem.
90
+	 *   Node::PROFILE_CARDDAV - Validate the vCard for CardDAV purposes.
91
+	 *   Node::PROFILE_CALDAV - Validate the iCalendar for CalDAV purposes.
92
+	 *
93
+	 * This method returns an array with detected problems.
94
+	 * Every element has the following properties:
95
+	 *
96
+	 *  * level - problem level.
97
+	 *  * message - A human-readable string describing the issue.
98
+	 *  * node - A reference to the problematic node.
99
+	 *
100
+	 * The level means:
101
+	 *   1 - The issue was repaired (only happens if REPAIR was turned on).
102
+	 *   2 - A warning.
103
+	 *   3 - An error.
104
+	 *
105
+	 * @param int $options
106
+	 *
107
+	 * @return array
108
+	 */
109
+	public function validate($options = 0)
110
+	{
111
+		$result = parent::validate($options);
112 112
 
113
-        if (isset($this->DTEND) && isset($this->DURATION)) {
114
-            $result[] = [
115
-                'level' => 3,
116
-                'message' => 'DTEND and DURATION cannot both be present',
117
-                'node' => $this,
118
-            ];
119
-        }
113
+		if (isset($this->DTEND) && isset($this->DURATION)) {
114
+			$result[] = [
115
+				'level' => 3,
116
+				'message' => 'DTEND and DURATION cannot both be present',
117
+				'node' => $this,
118
+			];
119
+		}
120 120
 
121
-        return $result;
122
-    }
121
+		return $result;
122
+	}
123 123
 }
Please login to merge, or discard this patch.