summaryrefslogtreecommitdiffstats
path: root/3rdparty/Sabre/VObject/Component/VCalendar.php
blob: f3be29afdbb492c16b7fe28f0e04888c3291fd43 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
<?php

/**
 * The VCalendar component
 *
 * This component adds functionality to a component, specific for a VCALENDAR.
 * 
 * @package Sabre
 * @subpackage VObject
 * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
 * @author Evert Pot (http://www.rooftopsolutions.nl/) 
 * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
 */
class Sabre_VObject_Component_VCalendar extends Sabre_VObject_Component {

    /**
     * Returns a list of all 'base components'. For instance, if an Event has 
     * a recurrence rule, and one instance is overridden, the overridden event 
     * will have the same UID, but will be excluded from this list.
     *
     * VTIMEZONE components will always be excluded. 
     *
     * @param string $componentName filter by component name 
     * @return array 
     */
    public function getBaseComponents($componentName = null) {

        $components = array();
        foreach($this->children as $component) {

            if (!$component instanceof Sabre_VObject_Component)
                continue;

            if (isset($component->{'RECURRENCE-ID'})) 
                continue;

            if ($componentName && $component->name !== strtoupper($componentName)) 
                continue;

            if ($component->name === 'VTIMEZONE')
                continue;

            $components[] = $component;

        }

        return $components;

    }

    /**
     * If this calendar object, has events with recurrence rules, this method 
     * can be used to expand the event into multiple sub-events.
     *
     * Each event will be stripped from it's recurrence information, and only 
     * the instances of the event in the specified timerange will be left 
     * alone.
     *
     * In addition, this method will cause timezone information to be stripped, 
     * and normalized to UTC.
     *
     * This method will alter the VCalendar. This cannot be reversed.
     *
     * This functionality is specifically used by the CalDAV standard. It is 
     * possible for clients to request expand events, if they are rather simple 
     * clients and do not have the possibility to calculate recurrences.
     *
     * @param DateTime $start
     * @param DateTime $end 
     * @return void
     */
    public function expand(DateTime $start, DateTime $end) {

        $newEvents = array();

        foreach($this->select('VEVENT') as $key=>$vevent) {

            if (isset($vevent->{'RECURRENCE-ID'})) {
                unset($this->children[$key]);
                continue;
            } 


            if (!$vevent->rrule) {
                unset($this->children[$key]);
                if ($vevent->isInTimeRange($start, $end)) {
                    $newEvents[] = $vevent;
                }
                continue;
            }

            $uid = (string)$vevent->uid;
            if (!$uid) {
                throw new LogicException('Event did not have a UID!');
            }

            $it = new Sabre_VObject_RecurrenceIterator($this, $vevent->uid);
            $it->fastForward($start);

            while($it->valid() && $it->getDTStart() < $end) {

                if ($it->getDTEnd() > $start) {

                    $newEvents[] = $it->getEventObject();

                }
                $it->next();

            }
            unset($this->children[$key]);

        }

        foreach($newEvents as $newEvent) {

            foreach($newEvent->children as $child) {
                if ($child instanceof Sabre_VObject_Property_DateTime &&
                    $child->getDateType() == Sabre_VObject_Property_DateTime::LOCALTZ) {
                        $child->setDateTime($child->getDateTime(),Sabre_VObject_Property_DateTime::UTC);
                    }
            }

            $this->add($newEvent);

        }

        // Removing all VTIMEZONE components
        unset($this->VTIMEZONE);

    } 

}