source: trunk/zpush/backend/zarafa/icalparser.php @ 7589

Revision 7589, 9.4 KB checked in by douglas, 11 years ago (diff)

Ticket #3209 - Integrar módulo de sincronização Z-push ao Expresso

Line 
1<?php
2/***********************************************
3* File      :   z_ical.php
4* Project   :   Z-Push
5* Descr     :   This is a very basic iCalendar parser
6*               used to process incoming meeting requests
7*               and responses.
8*
9* Created   :   01.12.2008
10*
11* Copyright 2007 - 2012 Zarafa Deutschland GmbH
12*
13* This program is free software: you can redistribute it and/or modify
14* it under the terms of the GNU Affero General Public License, version 3,
15* as published by the Free Software Foundation with the following additional
16* term according to sec. 7:
17*
18* According to sec. 7 of the GNU Affero General Public License, version 3,
19* the terms of the AGPL are supplemented with the following terms:
20*
21* "Zarafa" is a registered trademark of Zarafa B.V.
22* "Z-Push" is a registered trademark of Zarafa Deutschland GmbH
23* The licensing of the Program under the AGPL does not imply a trademark license.
24* Therefore any rights, title and interest in our trademarks remain entirely with us.
25*
26* However, if you propagate an unmodified version of the Program you are
27* allowed to use the term "Z-Push" to indicate that you distribute the Program.
28* Furthermore you may use our trademarks where it is necessary to indicate
29* the intended purpose of a product or service provided you use it in accordance
30* with honest practices in industrial or commercial matters.
31* If you want to propagate modified versions of the Program under the name "Z-Push",
32* you may only do so if you have a written permission by Zarafa Deutschland GmbH
33* (to acquire a permission please contact Zarafa at trademark@zarafa.com).
34*
35* This program is distributed in the hope that it will be useful,
36* but WITHOUT ANY WARRANTY; without even the implied warranty of
37* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38* GNU Affero General Public License for more details.
39*
40* You should have received a copy of the GNU Affero General Public License
41* along with this program.  If not, see <http://www.gnu.org/licenses/>.
42*
43* Consult LICENSE file for details
44************************************************/
45
46class ICalParser{
47    private $props;
48
49    /**
50     * Constructor
51     *
52     * @param mapistore     $store
53     * @param array         &$props     properties to be set
54     *
55     * @access public
56     */
57    public function ICalParser(&$store, &$props){
58         $this->props = $props;
59    }
60
61    /**
62     * Function reads calendar part and puts mapi properties into an array.
63     *
64     * @param string        $ical       the ical data
65     * @param array         &$mapiprops mapi properties
66     *
67     * @access public
68     */
69    public function ExtractProps($ical, &$mapiprops) {
70        //mapping between partstat in ical and MAPI Meeting Response classes as well as icons
71        $aClassMap = array(
72            "ACCEPTED"          => array("class" => "IPM.Schedule.Meeting.Resp.Pos", "icon" => 0x405),
73            "DECLINED"          => array("class" => "IPM.Schedule.Meeting.Resp.Neg", "icon" => 0x406),
74            "TENTATIVE"         => array("class" => "IPM.Schedule.Meeting.Resp.Tent", "icon" => 0x407),
75            "NEEDS-ACTION"      => array("class" => "IPM.Schedule.Meeting.Request", "icon" => 0x404), //iphone
76            "REQ-PARTICIPANT"   => array("class" => "IPM.Schedule.Meeting.Request", "icon" => 0x404), //nokia
77        );
78
79        $aical = preg_split("/[\n]/", $ical);
80        $elemcount = count($aical);
81        $i=0;
82        $nextline = $aical[0];
83
84        //last element is empty
85        while ($i < $elemcount - 1) {
86            $line = $nextline;
87            $nextline = $aical[$i+1];
88
89            //if a line starts with a space or a tab it belongs to the previous line
90            while (strlen($nextline) > 0 && ($nextline{0} == " " || $nextline{0} == "\t")) {
91                $line = rtrim($line) . substr($nextline, 1);
92                $nextline = $aical[++$i + 1];
93            }
94            $line = rtrim($line);
95
96            switch (strtoupper($line)) {
97                case "BEGIN:VCALENDAR":
98                case "BEGIN:VEVENT":
99                case "END:VEVENT":
100                case "END:VCALENDAR":
101                    break;
102                default:
103                    unset ($field, $data, $prop_pos, $property);
104                    if (preg_match ("/([^:]+):(.*)/", $line, $line)){
105                        $field = $line[1];
106                        $data = $line[2];
107                        $property = $field;
108                        $prop_pos = strpos($property,';');
109                        if ($prop_pos !== false) $property = substr($property, 0, $prop_pos);
110                        $property = strtoupper($property);
111
112                        switch ($property) {
113                            case 'DTSTART':
114                                $data = $this->getTimestampFromStreamerDate($data);
115                                $mapiprops[$this->props["starttime"]] = $mapiprops[$this->props["commonstart"]] = $mapiprops[$this->props["clipstart"]] = $mapiprops[PR_START_DATE] = $data;
116                                break;
117
118                            case 'DTEND':
119                                $data = $this->getTimestampFromStreamerDate($data);
120                                $mapiprops[$this->props["endtime"]] = $mapiprops[$this->props["commonend"]] = $mapiprops[$this->props["recurrenceend"]] = $mapiprops[PR_END_DATE] = $data;
121                                break;
122
123                            case 'UID':
124                                $mapiprops[$this->props["goidtag"]] = $mapiprops[$this->props["goid2tag"]] = Utils::GetOLUidFromICalUid($data);
125                                break;
126
127                            case 'ATTENDEE':
128                                $fields = explode(";", $field);
129                                foreach ($fields as $field) {
130                                    $prop_pos     = strpos($field, '=');
131                                    if ($prop_pos !== false) {
132                                        switch (substr($field, 0, $prop_pos)) {
133                                            case 'PARTSTAT'    : $partstat = substr($field, $prop_pos+1); break;
134                                            case 'CN'        : $cn = substr($field, $prop_pos+1); break;
135                                            case 'ROLE'        : $role = substr($field, $prop_pos+1); break;
136                                            case 'RSVP'        : $rsvp = substr($field, $prop_pos+1); break;
137                                        }
138                                    }
139                                }
140                                if (isset($partstat) && isset($aClassMap[$partstat]) &&
141
142                                   (!isset($mapiprops[PR_MESSAGE_CLASS]) || $mapiprops[PR_MESSAGE_CLASS] == "IPM.Schedule.Meeting.Request")) {
143                                    $mapiprops[PR_MESSAGE_CLASS] = $aClassMap[$partstat]['class'];
144                                    $mapiprops[PR_ICON_INDEX] = $aClassMap[$partstat]['icon'];
145                                }
146                                // START ADDED dw2412 to support meeting requests on HTC Android Mail App
147                                elseif (isset($role) && isset($aClassMap[$role]) &&
148                                   (!isset($mapiprops[PR_MESSAGE_CLASS]) || $mapiprops[PR_MESSAGE_CLASS] == "IPM.Schedule.Meeting.Request")) {
149                                    $mapiprops[PR_MESSAGE_CLASS] = $aClassMap[$role]['class'];
150                                    $mapiprops[PR_ICON_INDEX] = $aClassMap[$role]['icon'];
151                                }
152                                // END ADDED dw2412 to support meeting requests on HTC Android Mail App
153                                if (!isset($cn)) $cn = "";
154                                $data         = str_replace ("MAILTO:", "", $data);
155                                $attendee[] = array ('name' => stripslashes($cn), 'email' => stripslashes($data));
156                                break;
157
158                            case 'ORGANIZER':
159                                $field          = str_replace("ORGANIZER;CN=", "", $field);
160                                $data          = str_replace ("MAILTO:", "", $data);
161                                $organizer[] = array ('name' => stripslashes($field), 'email' => stripslashes($data));
162                                break;
163
164                            case 'LOCATION':
165                                $data = str_replace("\\n", "<br />", $data);
166                                $data = str_replace("\\t", "&nbsp;", $data);
167                                $data = str_replace("\\r", "<br />", $data);
168                                $data = stripslashes($data);
169                                $mapiprops[$this->props["tneflocation"]] = $mapiprops[$this->props["location"]] = $data;
170                                break;
171                        }
172                    }
173                    break;
174            }
175            $i++;
176
177        }
178        $mapiprops[$this->props["usetnef"]] = true;
179    }
180
181    /**
182     * Converts an YYYYMMDDTHHMMSSZ kind of string into an unixtimestamp
183     *
184     * @param string $data
185     *
186     * @access private
187     * @return long
188     */
189    private function getTimestampFromStreamerDate ($data) {
190        $data = str_replace('Z', '', $data);
191        $data = str_replace('T', '', $data);
192
193        preg_match ('/([0-9]{4})([0-9]{2})([0-9]{2})([0-9]{0,2})([0-9]{0,2})([0-9]{0,2})/', $data, $regs);
194        if ($regs[1] < 1970) {
195            $regs[1] = '1971';
196        }
197        return gmmktime($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]);
198    }
199}
200
201?>
Note: See TracBrowser for help on using the repository browser.