protected function validateTimeRange(VObject\Node $component, $start, $end)
    {
        if (is_null($start)) {
            $start = new DateTime('1900-01-01');
        }
        if (is_null($end)) {
            $end = new DateTime('3000-01-01');
        }

        switch ($component->name) {
            case 'VEVENT':
            case 'VTODO':
            case 'VJOURNAL':

                return $component->isInTimeRange($start, $end);

            case 'VALARM':

                // If the valarm is wrapped in a recurring event, we need to
                // expand the recursions, and validate each.
                //
                // Our datamodel doesn't easily allow us to do this straight
                // in the VALARM component code, so this is a hack, and an
                // expensive one too.
                if ('VEVENT' === $component->parent->name && $component->parent->RRULE) {
                    // Fire up the iterator!
                    $it = new VObject\Recur\EventIterator($component->parent->parent, (string) $component->parent->UID);
                    while ($it->valid()) {
                        $expandedEvent = $it->getEventObject();

                        // We need to check from these expanded alarms, which
                        // one is the first to trigger. Based on this, we can
                        // determine if we can 'give up' expanding events.
                        $firstAlarm = null;
                        if (null !== $expandedEvent->VALARM) {
                            foreach ($expandedEvent->VALARM as $expandedAlarm) {
                                $effectiveTrigger = $expandedAlarm->getEffectiveTriggerTime();
                                if ($expandedAlarm->isInTimeRange($start, $end)) {
                                    return true;
                                }

                                if ('DATE-TIME' === (string) $expandedAlarm->TRIGGER['VALUE']) {
                                    // This is an alarm with a non-relative trigger
                                    // time, likely created by a buggy client. The
                                    // implication is that every alarm in this
                                    // recurring event trigger at the exact same
                                    // time. It doesn't make sense to traverse
                                    // further.
                                } else {
                                    // We store the first alarm as a means to
                                    // figure out when we can stop traversing.
                                    if (!$firstAlarm || $effectiveTrigger < $firstAlarm) {
                                        $firstAlarm = $effectiveTrigger;
                                    }
                                }
                            }
                        }
                        if (is_null($firstAlarm)) {
                            // No alarm was found.
                            //
                            // Or technically: No alarm that will change for
                            // every instance of the recurrence was found,
                            // which means we can assume there was no match.
                            return false;
                        }
                        if ($firstAlarm > $end) {
                            return false;
                        }
                        $it->next();
                    }

                    return false;
                } else {
                    return $component->isInTimeRange($start, $end);
                }

                // no break
            case 'VFREEBUSY':
                throw new \Sabre\DAV\Exception\NotImplemented('time-range filters are currently not supported on '.$component->name.' components');
            case 'COMPLETED':
            case 'CREATED':
            case 'DTEND':
            case 'DTSTAMP':
            case 'DTSTART':
            case 'DUE':
            case 'LAST-MODIFIED':
                return $start <= $component->getDateTime() && $end >= $component->getDateTime();

            default:
                throw new \Sabre\DAV\Exception\BadRequest('You cannot create a time-range filter on a '.$component->name.' component');
        }
    }
protected function validateTimeRange(VObject\Node $component, $start, $end)
    {
        if (is_null($start)) {
            $start = new DateTime('1900-01-01');
        }
        if (is_null($end)) {
            $end = new DateTime('3000-01-01');
        }

        switch ($component->name) {
            case 'VEVENT':
            case 'VTODO':
            case 'VJOURNAL':

                return $component->isInTimeRange($start, $end);

            case 'VALARM':

                // If the valarm is wrapped in a recurring event, we need to
                // expand the recursions, and validate each.
                //
                // Our datamodel doesn't easily allow us to do this straight
                // in the VALARM component code, so this is a hack, and an
                // expensive one too.
                if ('VEVENT' === $component->parent->name && $component->parent->RRULE) {
                    // Fire up the iterator!
                    $it = new VObject\Recur\EventIterator($component->parent->parent, (string) $component->parent->UID);
                    while ($it->valid()) {
                        $expandedEvent = $it->getEventObject();

                        // We need to check from these expanded alarms, which
                        // one is the first to trigger. Based on this, we can
                        // determine if we can 'give up' expanding events.
                        $firstAlarm = null;
                        if (null !== $expandedEvent->VALARM) {
                            foreach ($expandedEvent->VALARM as $expandedAlarm) {
                                $effectiveTrigger = $expandedAlarm->getEffectiveTriggerTime();
                                if ($expandedAlarm->isInTimeRange($start, $end)) {
                                    return true;
                                }

                                if ('DATE-TIME' === (string) $expandedAlarm->TRIGGER['VALUE']) {
                                    // This is an alarm with a non-relative trigger
                                    // time, likely created by a buggy client. The
                                    // implication is that every alarm in this
                                    // recurring event trigger at the exact same
                                    // time. It doesn't make sense to traverse
                                    // further.
                                } else {
                                    // We store the first alarm as a means to
                                    // figure out when we can stop traversing.
                                    if (!$firstAlarm || $effectiveTrigger < $firstAlarm) {
                                        $firstAlarm = $effectiveTrigger;
                                    }
                                }
                            }
                        }
                        if (is_null($firstAlarm)) {
                            // No alarm was found.
                            //
                            // Or technically: No alarm that will change for
                            // every instance of the recurrence was found,
                            // which means we can assume there was no match.
                            return false;
                        }
                        if ($firstAlarm > $end) {
                            return false;
                        }
                        $it->next();
                    }

                    return false;
                } else {
                    return $component->isInTimeRange($start, $end);
                }

                // no break
            case 'VFREEBUSY':
                throw new \Sabre\DAV\Exception\NotImplemented('time-range filters are currently not supported on '.$component->name.' components');
            case 'COMPLETED':
            case 'CREATED':
            case 'DTEND':
            case 'DTSTAMP':
            case 'DTSTART':
            case 'DUE':
            case 'LAST-MODIFIED':
                return $start <= $component->getDateTime() && $end >= $component->getDateTime();

            default:
                throw new \Sabre\DAV\Exception\BadRequest('You cannot create a time-range filter on a '.$component->name.' component');
        }
    }
protected function validateTimeRange ( VObject \ Node $ component , $ start , $ end ) { if ( is_null ( $ start ) ) { $ start = new DateTime ( '1900-01-01' ) ; } if ( is_null ( $ end ) ) { $ end = new DateTime ( '3000-01-01' ) ; } switch ( $ component -> name ) { case 'VEVENT' : case 'VTODO' : case 'VJOURNAL' : return $ component -> isInTimeRange ( $ start , $ end ) ; case 'VALARM' : // If the valarm is wrapped in a recurring event, we need to // expand the recursions, and validate each. // // Our datamodel doesn't easily allow us to do this straight // in the VALARM component code, so this is a hack, and an // expensive one too. if ( 'VEVENT' === $ component -> parent -> name && $ component -> parent -> RRULE ) { // Fire up the iterator! $ it = new VObject \ Recur \ EventIterator ( $ component -> parent -> parent , ( string ) $ component -> parent -> UID ) ; while ( $ it -> valid ( ) ) { $ expandedEvent = $ it -> getEventObject ( ) ; // We need to check from these expanded alarms, which // one is the first to trigger. Based on this, we can // determine if we can 'give up' expanding events. $ firstAlarm = null ; if ( null !== $ expandedEvent -> VALARM ) { foreach ( $ expandedEvent -> VALARM as $ expandedAlarm ) { $ effectiveTrigger = $ expandedAlarm -> getEffectiveTriggerTime ( ) ; if ( $ expandedAlarm -> isInTimeRange ( $ start , $ end ) ) { return true ; } if ( 'DATE-TIME' === ( string ) $ expandedAlarm -> TRIGGER [ 'VALUE' ] ) { // This is an alarm with a non-relative trigger // time, likely created by a buggy client. The // implication is that every alarm in this // recurring event trigger at the exact same // time. It doesn't make sense to traverse // further. } else { // We store the first alarm as a means to // figure out when we can stop traversing. if ( ! $ firstAlarm || $ effectiveTrigger < $ firstAlarm ) { $ firstAlarm = $ effectiveTrigger ; } } } } if ( is_null ( $ firstAlarm ) ) { // No alarm was found. // // Or technically: No alarm that will change for // every instance of the recurrence was found, // which means we can assume there was no match. return false ; } if ( $ firstAlarm > $ end ) { return false ; } $ it -> next ( ) ; } return false ; } else { return $ component -> isInTimeRange ( $ start , $ end ) ; } // no break case 'VFREEBUSY' : throw new \ Sabre \ DAV \ Exception \ NotImplemented ( 'time-range filters are currently not supported on ' . $ component -> name . ' components' ) ; case 'COMPLETED' : case 'CREATED' : case 'DTEND' : case 'DTSTAMP' : case 'DTSTART' : case 'DUE' : case 'LAST-MODIFIED' : return $ start <= $ component -> getDateTime ( ) && $ end >= $ component -> getDateTime ( ) ; default : throw new \ Sabre \ DAV \ Exception \ BadRequest ( 'You cannot create a time-range filter on a ' . $ component -> name . ' component' ) ; } }
Validates if a component matches the given time range.

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

@param VObject\Node $component
@param DateTime     $start
@param DateTime     $end

@return bool
Validates if a component matches the given time range .