ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
Sabre\CalDAV\CalendarQueryValidator Class Reference

CalendarQuery Validator. More...

+ Collaboration diagram for Sabre\CalDAV\CalendarQueryValidator:

Public Member Functions

 validate (VObject\Component\VCalendar $vObject, array $filters)
 Verify if a list of filters applies to the calendar data object. More...
 

Protected Member Functions

 validateCompFilters (VObject\Component $parent, array $filters)
 This method checks the validity of comp-filters. More...
 
 validatePropFilters (VObject\Component $parent, array $filters)
 This method checks the validity of prop-filters. More...
 
 validateParamFilters (VObject\Property $parent, array $filters)
 This method checks the validity of param-filters. More...
 
 validateTextMatch ($check, array $textMatch)
 This method checks the validity of a text-match. More...
 
 validateTimeRange (VObject\Node $component, $start, $end)
 Validates if a component matches the given time range. More...
 

Detailed Description

CalendarQuery Validator.

This class is responsible for checking if an iCalendar object matches a set of filters. The main function to do this is 'validate'.

This is used to determine which icalendar objects should be returned for a calendar-query REPORT request.

Author
Evert Pot (http://evertpot.com/) http://sabre.io/license/ Modified BSD License

Definition at line 21 of file CalendarQueryValidator.php.

Member Function Documentation

◆ validate()

Sabre\CalDAV\CalendarQueryValidator::validate ( VObject\Component\VCalendar  $vObject,
array  $filters 
)

Verify if a list of filters applies to the calendar data object.

The list of filters must be formatted as parsed by

Parameters
VObject\Component\VCalendar$vObject
array$filters
Returns
bool

Definition at line 32 of file CalendarQueryValidator.php.

References Sabre\CalDAV\CalendarQueryValidator\validateCompFilters(), and Sabre\CalDAV\CalendarQueryValidator\validatePropFilters().

32  {
33 
34  // The top level object is always a component filter.
35  // We'll parse it manually, as it's pretty simple.
36  if ($vObject->name !== $filters['name']) {
37  return false;
38  }
39 
40  return
41  $this->validateCompFilters($vObject, $filters['comp-filters']) &&
42  $this->validatePropFilters($vObject, $filters['prop-filters']);
43 
44 
45  }
validatePropFilters(VObject\Component $parent, array $filters)
This method checks the validity of prop-filters.
validateCompFilters(VObject\Component $parent, array $filters)
This method checks the validity of comp-filters.
+ Here is the call graph for this function:

◆ validateCompFilters()

Sabre\CalDAV\CalendarQueryValidator::validateCompFilters ( VObject\Component  $parent,
array  $filters 
)
protected

This method checks the validity of comp-filters.

A list of comp-filters needs to be specified. Also the parent of the component we're checking should be specified, not the component to check itself.

Parameters
VObject\Component$parent
array$filters
Returns
bool

Definition at line 58 of file CalendarQueryValidator.php.

References Sabre\CalDAV\CalendarQueryValidator\validatePropFilters(), and Sabre\CalDAV\CalendarQueryValidator\validateTimeRange().

Referenced by Sabre\CalDAV\CalendarQueryValidator\validate().

58  {
59 
60  foreach ($filters as $filter) {
61 
62  $isDefined = isset($parent->{$filter['name']});
63 
64  if ($filter['is-not-defined']) {
65 
66  if ($isDefined) {
67  return false;
68  } else {
69  continue;
70  }
71 
72  }
73  if (!$isDefined) {
74  return false;
75  }
76 
77  if ($filter['time-range']) {
78  foreach ($parent->{$filter['name']} as $subComponent) {
79  if ($this->validateTimeRange($subComponent, $filter['time-range']['start'], $filter['time-range']['end'])) {
80  continue 2;
81  }
82  }
83  return false;
84  }
85 
86  if (!$filter['comp-filters'] && !$filter['prop-filters']) {
87  continue;
88  }
89 
90  // If there are sub-filters, we need to find at least one component
91  // for which the subfilters hold true.
92  foreach ($parent->{$filter['name']} as $subComponent) {
93 
94  if (
95  $this->validateCompFilters($subComponent, $filter['comp-filters']) &&
96  $this->validatePropFilters($subComponent, $filter['prop-filters'])) {
97  // We had a match, so this comp-filter succeeds
98  continue 2;
99  }
100 
101  }
102 
103  // If we got here it means there were sub-comp-filters or
104  // sub-prop-filters and there was no match. This means this filter
105  // needs to return false.
106  return false;
107 
108  }
109 
110  // If we got here it means we got through all comp-filters alive so the
111  // filters were all true.
112  return true;
113 
114  }
validateTimeRange(VObject\Node $component, $start, $end)
Validates if a component matches the given time range.
validatePropFilters(VObject\Component $parent, array $filters)
This method checks the validity of prop-filters.
validateCompFilters(VObject\Component $parent, array $filters)
This method checks the validity of comp-filters.
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ validateParamFilters()

Sabre\CalDAV\CalendarQueryValidator::validateParamFilters ( VObject\Property  $parent,
array  $filters 
)
protected

This method checks the validity of param-filters.

A list of param-filters needs to be specified. Also the parent of the parameter we're checking should be specified, not the parameter to check itself.

Parameters
VObject\Property$parent
array$filters
Returns
bool

Definition at line 197 of file CalendarQueryValidator.php.

References Sabre\CalDAV\CalendarQueryValidator\validateTextMatch().

Referenced by Sabre\CalDAV\CalendarQueryValidator\validatePropFilters().

197  {
198 
199  foreach ($filters as $filter) {
200 
201  $isDefined = isset($parent[$filter['name']]);
202 
203  if ($filter['is-not-defined']) {
204 
205  if ($isDefined) {
206  return false;
207  } else {
208  continue;
209  }
210 
211  }
212  if (!$isDefined) {
213  return false;
214  }
215 
216  if (!$filter['text-match']) {
217  continue;
218  }
219 
220  // If there are sub-filters, we need to find at least one parameter
221  // for which the subfilters hold true.
222  foreach ($parent[$filter['name']]->getParts() as $paramPart) {
223 
224  if ($this->validateTextMatch($paramPart, $filter['text-match'])) {
225  // We had a match, so this param-filter succeeds
226  continue 2;
227  }
228 
229  }
230 
231  // If we got here it means there was a text-match filter and there
232  // were no matches. This means the filter needs to return false.
233  return false;
234 
235  }
236 
237  // If we got here it means we got through all param-filters alive so the
238  // filters were all true.
239  return true;
240 
241  }
validateTextMatch($check, array $textMatch)
This method checks the validity of a text-match.
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ validatePropFilters()

Sabre\CalDAV\CalendarQueryValidator::validatePropFilters ( VObject\Component  $parent,
array  $filters 
)
protected

This method checks the validity of prop-filters.

A list of prop-filters needs to be specified. Also the parent of the property we're checking should be specified, not the property to check itself.

Parameters
VObject\Component$parent
array$filters
Returns
bool

Definition at line 127 of file CalendarQueryValidator.php.

References Sabre\CalDAV\CalendarQueryValidator\validateParamFilters(), Sabre\CalDAV\CalendarQueryValidator\validateTextMatch(), and Sabre\CalDAV\CalendarQueryValidator\validateTimeRange().

Referenced by Sabre\CalDAV\CalendarQueryValidator\validate(), and Sabre\CalDAV\CalendarQueryValidator\validateCompFilters().

127  {
128 
129  foreach ($filters as $filter) {
130 
131  $isDefined = isset($parent->{$filter['name']});
132 
133  if ($filter['is-not-defined']) {
134 
135  if ($isDefined) {
136  return false;
137  } else {
138  continue;
139  }
140 
141  }
142  if (!$isDefined) {
143  return false;
144  }
145 
146  if ($filter['time-range']) {
147  foreach ($parent->{$filter['name']} as $subComponent) {
148  if ($this->validateTimeRange($subComponent, $filter['time-range']['start'], $filter['time-range']['end'])) {
149  continue 2;
150  }
151  }
152  return false;
153  }
154 
155  if (!$filter['param-filters'] && !$filter['text-match']) {
156  continue;
157  }
158 
159  // If there are sub-filters, we need to find at least one property
160  // for which the subfilters hold true.
161  foreach ($parent->{$filter['name']} as $subComponent) {
162 
163  if (
164  $this->validateParamFilters($subComponent, $filter['param-filters']) &&
165  (!$filter['text-match'] || $this->validateTextMatch($subComponent, $filter['text-match']))
166  ) {
167  // We had a match, so this prop-filter succeeds
168  continue 2;
169  }
170 
171  }
172 
173  // If we got here it means there were sub-param-filters or
174  // text-match filters and there was no match. This means the
175  // filter needs to return false.
176  return false;
177 
178  }
179 
180  // If we got here it means we got through all prop-filters alive so the
181  // filters were all true.
182  return true;
183 
184  }
validateTimeRange(VObject\Node $component, $start, $end)
Validates if a component matches the given time range.
validateParamFilters(VObject\Property $parent, array $filters)
This method checks the validity of param-filters.
validateTextMatch($check, array $textMatch)
This method checks the validity of a text-match.
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ validateTextMatch()

Sabre\CalDAV\CalendarQueryValidator::validateTextMatch (   $check,
array  $textMatch 
)
protected

This method checks the validity of a text-match.

A single text-match should be specified as well as the specific property or parameter we need to validate.

Parameters
VObject\Node | string$checkValue to check against.
array$textMatch
Returns
bool

Definition at line 253 of file CalendarQueryValidator.php.

References Sabre\DAV\StringUtil\textMatch().

Referenced by Sabre\CalDAV\CalendarQueryValidator\validateParamFilters(), and Sabre\CalDAV\CalendarQueryValidator\validatePropFilters().

253  {
254 
255  if ($check instanceof VObject\Node) {
256  $check = $check->getValue();
257  }
258 
259  $isMatching = \Sabre\DAV\StringUtil::textMatch($check, $textMatch['value'], $textMatch['collation']);
260 
261  return ($textMatch['negate-condition'] xor $isMatching);
262 
263  }
static textMatch($haystack, $needle, $collation, $matchType='contains')
Checks if a needle occurs in a haystack ;)
Definition: StringUtil.php:27
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ validateTimeRange()

Sabre\CalDAV\CalendarQueryValidator::validateTimeRange ( VObject\Node  $component,
  $start,
  $end 
)
protected

Validates if a component matches the given time range.

This is all based on the rules specified in rfc4791, which are quite complex.

Parameters
VObject\Node$component
DateTime$start
DateTime$end
Returns
bool

Definition at line 276 of file CalendarQueryValidator.php.

References $end, and $start.

Referenced by Sabre\CalDAV\CalendarQueryValidator\validateCompFilters(), and Sabre\CalDAV\CalendarQueryValidator\validatePropFilters().

276  {
277 
278  if (is_null($start)) {
279  $start = new DateTime('1900-01-01');
280  }
281  if (is_null($end)) {
282  $end = new DateTime('3000-01-01');
283  }
284 
285  switch ($component->name) {
286 
287  case 'VEVENT' :
288  case 'VTODO' :
289  case 'VJOURNAL' :
290 
291  return $component->isInTimeRange($start, $end);
292 
293  case 'VALARM' :
294 
295  // If the valarm is wrapped in a recurring event, we need to
296  // expand the recursions, and validate each.
297  //
298  // Our datamodel doesn't easily allow us to do this straight
299  // in the VALARM component code, so this is a hack, and an
300  // expensive one too.
301  if ($component->parent->name === 'VEVENT' && $component->parent->RRULE) {
302 
303  // Fire up the iterator!
304  $it = new VObject\Recur\EventIterator($component->parent->parent, (string)$component->parent->UID);
305  while ($it->valid()) {
306  $expandedEvent = $it->getEventObject();
307 
308  // We need to check from these expanded alarms, which
309  // one is the first to trigger. Based on this, we can
310  // determine if we can 'give up' expanding events.
311  $firstAlarm = null;
312  if ($expandedEvent->VALARM !== null) {
313  foreach ($expandedEvent->VALARM as $expandedAlarm) {
314 
315  $effectiveTrigger = $expandedAlarm->getEffectiveTriggerTime();
316  if ($expandedAlarm->isInTimeRange($start, $end)) {
317  return true;
318  }
319 
320  if ((string)$expandedAlarm->TRIGGER['VALUE'] === 'DATE-TIME') {
321  // This is an alarm with a non-relative trigger
322  // time, likely created by a buggy client. The
323  // implication is that every alarm in this
324  // recurring event trigger at the exact same
325  // time. It doesn't make sense to traverse
326  // further.
327  } else {
328  // We store the first alarm as a means to
329  // figure out when we can stop traversing.
330  if (!$firstAlarm || $effectiveTrigger < $firstAlarm) {
331  $firstAlarm = $effectiveTrigger;
332  }
333  }
334  }
335  }
336  if (is_null($firstAlarm)) {
337  // No alarm was found.
338  //
339  // Or technically: No alarm that will change for
340  // every instance of the recurrence was found,
341  // which means we can assume there was no match.
342  return false;
343  }
344  if ($firstAlarm > $end) {
345  return false;
346  }
347  $it->next();
348  }
349  return false;
350  } else {
351  return $component->isInTimeRange($start, $end);
352  }
353 
354  case 'VFREEBUSY' :
355  throw new \Sabre\DAV\Exception\NotImplemented('time-range filters are currently not supported on ' . $component->name . ' components');
356 
357  case 'COMPLETED' :
358  case 'CREATED' :
359  case 'DTEND' :
360  case 'DTSTAMP' :
361  case 'DTSTART' :
362  case 'DUE' :
363  case 'LAST-MODIFIED' :
364  return ($start <= $component->getDateTime() && $end >= $component->getDateTime());
365 
366 
367 
368  default :
369  throw new \Sabre\DAV\Exception\BadRequest('You cannot create a time-range filter on a ' . $component->name . ' component');
370 
371  }
372 
373  }
$start
Definition: bench.php:8
+ Here is the caller graph for this function:

The documentation for this class was generated from the following file: