xref: /plugin/davcal/vendor/sabre/vobject/lib/Splitter/ICalendar.php (revision a1a3b6794e0e143a4a8b51d3185ce2d339be61ab)
1*a1a3b679SAndreas Boehler<?php
2*a1a3b679SAndreas Boehler
3*a1a3b679SAndreas Boehlernamespace Sabre\VObject\Splitter;
4*a1a3b679SAndreas Boehler
5*a1a3b679SAndreas Boehleruse
6*a1a3b679SAndreas Boehler    Sabre\VObject,
7*a1a3b679SAndreas Boehler    Sabre\VObject\Component\VCalendar;
8*a1a3b679SAndreas Boehler
9*a1a3b679SAndreas Boehler/**
10*a1a3b679SAndreas Boehler * Splitter
11*a1a3b679SAndreas Boehler *
12*a1a3b679SAndreas Boehler * This class is responsible for splitting up iCalendar objects.
13*a1a3b679SAndreas Boehler *
14*a1a3b679SAndreas Boehler * This class expects a single VCALENDAR object with one or more
15*a1a3b679SAndreas Boehler * calendar-objects inside. Objects with identical UID's will be combined into
16*a1a3b679SAndreas Boehler * a single object.
17*a1a3b679SAndreas Boehler *
18*a1a3b679SAndreas Boehler * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
19*a1a3b679SAndreas Boehler * @author Dominik Tobschall
20*a1a3b679SAndreas Boehler * @author Armin Hackmann
21*a1a3b679SAndreas Boehler * @license http://sabre.io/license/ Modified BSD License
22*a1a3b679SAndreas Boehler */
23*a1a3b679SAndreas Boehlerclass ICalendar implements SplitterInterface {
24*a1a3b679SAndreas Boehler
25*a1a3b679SAndreas Boehler    /**
26*a1a3b679SAndreas Boehler     * Timezones
27*a1a3b679SAndreas Boehler     *
28*a1a3b679SAndreas Boehler     * @var array
29*a1a3b679SAndreas Boehler     */
30*a1a3b679SAndreas Boehler    protected $vtimezones = array();
31*a1a3b679SAndreas Boehler
32*a1a3b679SAndreas Boehler    /**
33*a1a3b679SAndreas Boehler     * iCalendar objects
34*a1a3b679SAndreas Boehler     *
35*a1a3b679SAndreas Boehler     * @var array
36*a1a3b679SAndreas Boehler     */
37*a1a3b679SAndreas Boehler    protected $objects = array();
38*a1a3b679SAndreas Boehler
39*a1a3b679SAndreas Boehler    /**
40*a1a3b679SAndreas Boehler     * Constructor
41*a1a3b679SAndreas Boehler     *
42*a1a3b679SAndreas Boehler     * The splitter should receive an readable file stream as it's input.
43*a1a3b679SAndreas Boehler     *
44*a1a3b679SAndreas Boehler     * @param resource $input
45*a1a3b679SAndreas Boehler     * @param int $options Parser options, see the OPTIONS constants.
46*a1a3b679SAndreas Boehler     */
47*a1a3b679SAndreas Boehler    public function __construct($input, $options = 0) {
48*a1a3b679SAndreas Boehler
49*a1a3b679SAndreas Boehler        $data = VObject\Reader::read($input, $options);
50*a1a3b679SAndreas Boehler        $vtimezones = array();
51*a1a3b679SAndreas Boehler        $components = array();
52*a1a3b679SAndreas Boehler
53*a1a3b679SAndreas Boehler        if (!$data instanceof VObject\Component\VCalendar) {
54*a1a3b679SAndreas Boehler            throw new VObject\ParseException('Supplied input could not be parsed as VCALENDAR.');
55*a1a3b679SAndreas Boehler        }
56*a1a3b679SAndreas Boehler
57*a1a3b679SAndreas Boehler        foreach($data->children() as $component) {
58*a1a3b679SAndreas Boehler            if (!$component instanceof VObject\Component) {
59*a1a3b679SAndreas Boehler                continue;
60*a1a3b679SAndreas Boehler            }
61*a1a3b679SAndreas Boehler
62*a1a3b679SAndreas Boehler            // Get all timezones
63*a1a3b679SAndreas Boehler            if ($component->name === 'VTIMEZONE') {
64*a1a3b679SAndreas Boehler                $this->vtimezones[(string)$component->TZID] = $component;
65*a1a3b679SAndreas Boehler                continue;
66*a1a3b679SAndreas Boehler            }
67*a1a3b679SAndreas Boehler
68*a1a3b679SAndreas Boehler            // Get component UID for recurring Events search
69*a1a3b679SAndreas Boehler            if(!$component->UID) {
70*a1a3b679SAndreas Boehler                $component->UID = sha1(microtime()) . '-vobjectimport';
71*a1a3b679SAndreas Boehler            }
72*a1a3b679SAndreas Boehler            $uid = (string)$component->UID;
73*a1a3b679SAndreas Boehler
74*a1a3b679SAndreas Boehler            // Take care of recurring events
75*a1a3b679SAndreas Boehler            if (!array_key_exists($uid, $this->objects)) {
76*a1a3b679SAndreas Boehler                $this->objects[$uid] = new VCalendar();
77*a1a3b679SAndreas Boehler            }
78*a1a3b679SAndreas Boehler
79*a1a3b679SAndreas Boehler            $this->objects[$uid]->add(clone $component);
80*a1a3b679SAndreas Boehler        }
81*a1a3b679SAndreas Boehler
82*a1a3b679SAndreas Boehler    }
83*a1a3b679SAndreas Boehler
84*a1a3b679SAndreas Boehler    /**
85*a1a3b679SAndreas Boehler     * Every time getNext() is called, a new object will be parsed, until we
86*a1a3b679SAndreas Boehler     * hit the end of the stream.
87*a1a3b679SAndreas Boehler     *
88*a1a3b679SAndreas Boehler     * When the end is reached, null will be returned.
89*a1a3b679SAndreas Boehler     *
90*a1a3b679SAndreas Boehler     * @return Sabre\VObject\Component|null
91*a1a3b679SAndreas Boehler     */
92*a1a3b679SAndreas Boehler    public function getNext() {
93*a1a3b679SAndreas Boehler
94*a1a3b679SAndreas Boehler        if($object=array_shift($this->objects)) {
95*a1a3b679SAndreas Boehler
96*a1a3b679SAndreas Boehler            // create our baseobject
97*a1a3b679SAndreas Boehler            $object->version = '2.0';
98*a1a3b679SAndreas Boehler            $object->prodid = '-//Sabre//Sabre VObject ' . VObject\Version::VERSION . '//EN';
99*a1a3b679SAndreas Boehler            $object->calscale = 'GREGORIAN';
100*a1a3b679SAndreas Boehler
101*a1a3b679SAndreas Boehler            // add vtimezone information to obj (if we have it)
102*a1a3b679SAndreas Boehler            foreach ($this->vtimezones as $vtimezone) {
103*a1a3b679SAndreas Boehler                $object->add($vtimezone);
104*a1a3b679SAndreas Boehler            }
105*a1a3b679SAndreas Boehler
106*a1a3b679SAndreas Boehler            return $object;
107*a1a3b679SAndreas Boehler
108*a1a3b679SAndreas Boehler        } else {
109*a1a3b679SAndreas Boehler
110*a1a3b679SAndreas Boehler            return null;
111*a1a3b679SAndreas Boehler
112*a1a3b679SAndreas Boehler        }
113*a1a3b679SAndreas Boehler
114*a1a3b679SAndreas Boehler    }
115*a1a3b679SAndreas Boehler
116*a1a3b679SAndreas Boehler}
117