PageRenderTime 105ms CodeModel.GetById 51ms app.highlight 13ms RepoModel.GetById 37ms app.codeStats 0ms

/htdocs/agenda/class/ical.class.php

https://bitbucket.org/speedealing/speedealing
PHP | 392 lines | 211 code | 50 blank | 131 comment | 20 complexity | ffe27cfb0e89226e2078357fdd0a01e1 MD5 | raw file
  1<?php
  2/* Copyright (C) 2006	Roman Ozana			<ozana@omdesign.cz>
  3 * Copyright (C) 2011	Juanjo Menent		<jmenent@2byte.es>
  4 * Copyright (C) 2012	Laurent Destailleur	<eldy@users.sourceforge.net>
  5 * Copyright (C) 2012	Regis Houssin		<regis.houssin@capnetworks.com>
  6 *
  7 * This program is free software; you can redistribute it and/or modify
  8 * it under the terms of the GNU General Public License as published by
  9 * the Free Software Foundation; either version 3 of the License, or
 10 * (at your option) any later version.
 11 *
 12 * This program is distributed in the hope that it will be useful,
 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 15 * GNU General Public License for more details.
 16 *
 17 * You should have received a copy of the GNU General Public License
 18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 19 */
 20
 21/**
 22 *       \file       htdocs/comm/action/class/ical.class.php
 23 *       \ingroup    agenda
 24 *       \brief      File of class to parse ical calendars
 25 */
 26
 27
 28/**
 29 *		Class to parse ICal calendars
 30 */
 31class ICal
 32{
 33    var $file_text; // Text in file
 34    var $cal; // Array to save iCalendar parse data
 35    var $event_count; // Number of Events
 36    var $todo_count; // Number of Todos
 37    var $freebusy_count; // Number of Freebusy
 38    var $last_key; //Help variable save last key (multiline string)
 39
 40
 41	/**
 42	 * Constructor
 43	 */
 44	public function __construct()
 45	{
 46
 47	}
 48
 49	/**
 50     * Read text file, icalender text file
 51     *
 52     * @param 	string 	$file		File
 53     * @return	string
 54     */
 55    function read_file($file)
 56    {
 57        $this->file = $file;
 58        $file_text = join("", file($file)); //load file
 59        $file_text = preg_replace("/[\r\n]{1,} ([:;])/","\\1",$file_text);
 60
 61        return $file_text; // return all text
 62    }
 63
 64    /**
 65     * Returns the number of calendar events
 66     *
 67     * @return int
 68     */
 69    function get_event_count()
 70    {
 71        return $this->event_count;
 72    }
 73
 74    /**
 75     * Returns the number of to do
 76     *
 77     * @return int
 78     */
 79    function get_todo_count()
 80    {
 81        return $this->todo_count;
 82    }
 83
 84    /**
 85     * Translate Calendar
 86     *
 87     * @param	string 	$uri	Url
 88     * @return	array
 89     */
 90    function parse($uri)
 91    {
 92        $this->cal = array(); // new empty array
 93
 94        $this->event_count = -1;
 95
 96        // read FILE text
 97        $this->file_text = $this->read_file($uri);
 98
 99        $this->file_text = preg_split("[\n]", $this->file_text);
100
101        // is this text vcalendar standart text ? on line 1 is BEGIN:VCALENDAR
102        if (!stristr($this->file_text[0],'BEGIN:VCALENDAR')) return 'error not VCALENDAR';
103
104        $insidealarm=0;
105        foreach ($this->file_text as $text)
106        {
107            $text = trim($text); // trim one line
108            if (!empty($text))
109            {
110                // get Key and Value VCALENDAR:Begin -> Key = VCALENDAR, Value = begin
111                list($key, $value) = $this->retun_key_value($text);
112
113                switch ($text) // search special string
114                {
115                    case "BEGIN:VTODO":
116                        $this->todo_count = $this->todo_count+1; // new to do begin
117                        $type = "VTODO";
118                        break;
119
120                    case "BEGIN:VEVENT":
121                        $this->event_count = $this->event_count+1; // new event begin
122                        $type = "VEVENT";
123                        break;
124
125                    case "BEGIN:VFREEBUSY":
126                        $this->freebusy_count = $this->freebusy_count+1; // new event begin
127                        $type = "VFREEBUSY";
128                        break;
129
130                    case "BEGIN:VCALENDAR": // all other special string
131                    case "BEGIN:DAYLIGHT":
132                    case "BEGIN:VTIMEZONE":
133                    case "BEGIN:STANDARD":
134                        $type = $value; // save tu array under value key
135                        break;
136
137                    case "END:VTODO": // end special text - goto VCALENDAR key
138                    case "END:VEVENT":
139                    case "END:VFREEBUSY":
140
141                    case "END:VCALENDAR":
142                    case "END:DAYLIGHT":
143                    case "END:VTIMEZONE":
144                    case "END:STANDARD":
145                        $type = "VCALENDAR";
146                        break;
147
148                    // Manage VALARM that are inside a VEVENT to avoid fields of VALARM to overwrites fields of VEVENT
149                    case "BEGIN:VALARM":
150                        $insidealarm=1;
151                        break;
152                    case "END:VALARM":
153                        $insidealarm=0;
154                        break;
155
156                    default: // no special string
157                        if (! $insidealarm) $this->add_to_array($type, $key, $value); // add to array
158                        break;
159                }
160            }
161        }
162        return $this->cal;
163    }
164
165    /**
166     * Add to $this->ical array one value and key.
167     *
168     * @param 	string 	$type		Type ('VTODO', 'VEVENT', 'VFREEBUSY', 'VCALENDAR'...)
169     * @param 	string 	$key		Key	('DTSTART', ...). Note: Field is never 'DTSTART;TZID=...' because ';...' was before removed and added as another property
170     * @param 	string 	$value		Value
171     * @return	void
172     */
173    function add_to_array($type, $key, $value)
174    {
175
176        //print 'type='.$type.' key='.$key.' value='.$value.'<br>'."\n";
177
178        if ($key == false)
179        {
180            $key = $this->last_key;
181            switch ($type)
182            {
183                case 'VEVENT': $value = $this->cal[$type][$this->event_count][$key].$value;break;
184                case 'VFREEBUSY': $value = $this->cal[$type][$this->freebusy_count][$key].$value;break;
185                case 'VTODO': $value = $this->cal[$type][$this->todo_count][$key].$value;break;
186            }
187        }
188
189        if (($key == "DTSTAMP") or ($key == "LAST-MODIFIED") or ($key == "CREATED")) $value = $this->ical_date_to_unix($value);
190        if ($key == "RRULE" ) $value = $this->ical_rrule($value);
191
192        if (stristr($key,"DTSTART") or stristr($key,"DTEND") or stristr($key,"DTSTART;VALUE=DATE") or stristr($key,"DTEND;VALUE=DATE"))
193        {
194        	if (stristr($key,"DTSTART;VALUE=DATE") or stristr($key,"DTEND;VALUE=DATE"))
195        	{
196        		list($key,$value) = array($key,$value);
197        	}
198        	else
199        	{
200        		list($key,$value) = $this->ical_dt_date($key,$value);
201        	}
202        }
203
204        switch ($type)
205        {
206            case "VTODO":
207                $this->cal[$type][$this->todo_count][$key] = $value;
208                break;
209
210            case "VEVENT":
211                $this->cal[$type][$this->event_count][$key] = $value;
212                break;
213
214            case "VFREEBUSY":
215                $this->cal[$type][$this->freebusy_count][$key] = $value;
216                break;
217
218            default:
219                $this->cal[$type][$key] = $value;
220                break;
221        }
222        $this->last_key = $key;
223    }
224
225    /**
226     * Parse text "XXXX:value text some with : " and return array($key = "XXXX", $value="value");
227     *
228     * @param 	string 	$text	Text
229     * @return 	array
230     */
231    function retun_key_value($text)
232    {
233        preg_match("/([^:]+)[:]([\w\W]+)/", $text, $matches);
234
235        if (empty($matches))
236        {
237            return array(false,$text);
238        }
239        else
240        {
241            $matches = array_splice($matches, 1, 2);
242            return $matches;
243        }
244
245    }
246
247    /**
248     * Parse RRULE  return array
249     *
250     * @param 	string 	$value	string
251     * @return 	array
252     */
253    function ical_rrule($value)
254    {
255        $rrule = explode(';',$value);
256        foreach ($rrule as $line)
257        {
258            $rcontent = explode('=', $line);
259            $result[$rcontent[0]] = $rcontent[1];
260        }
261        return $result;
262    }
263    /**
264     * Return Unix time from ical date time fomrat (YYYYMMDD[T]HHMMSS[Z] or YYYYMMDD[T]HHMMSS)
265     *
266     * @param 	string		$ical_date		String date
267     * @return 	timestamp
268     */
269    function ical_date_to_unix($ical_date)
270    {
271        $ical_date = str_replace('T', '', $ical_date);
272        $ical_date = str_replace('Z', '', $ical_date);
273
274        $ntime=0;
275        // TIME LIMITED EVENT
276        if (preg_match('/([0-9]{4})([0-9]{2})([0-9]{2})([0-9]{0,2})([0-9]{0,2})([0-9]{0,2})/', $ical_date, $date))
277            $ntime=dol_mktime($date[4], $date[5], $date[6], $date[2],$date[3], $date[1], true);
278
279        //if (empty($date[4])) print 'Error bad date: '.$ical_date.' - date1='.$date[1];
280        //print dol_print_date($ntime,'dayhour');exit;
281        return $ntime;      // ntime is a GTM time
282    }
283
284    /**
285     * Return unix date from iCal date format
286     *
287     * @param 	string 		$key			Key
288     * @param 	string 		$value			Value
289     * @return 	array
290     */
291    function ical_dt_date($key, $value)
292    {
293        $value = $this->ical_date_to_unix($value);
294
295        // Analyse TZID
296        $temp = explode(";",$key);
297
298        if (empty($temp[1])) // not TZID
299        {
300            $value = str_replace('T', '', $value);
301            return array($key,$value);
302        }
303        // adding $value and $tzid
304        $key =     $temp[0];
305        $temp = explode("=", $temp[1]);
306        $return_value[$temp[0]] = $temp[1];
307        $return_value['unixtime'] = $value;
308
309        return array($key,$return_value);
310    }
311
312    /**
313     * Return sorted eventlist as array or false if calenar is empty
314     *
315     * @return array
316     */
317    function get_sort_event_list()
318    {
319        $temp = $this->get_event_list();
320        if (!empty($temp))
321        {
322            usort($temp, array(&$this, "ical_dtstart_compare"));
323            return $temp;
324        } else
325        {
326            return false;
327        }
328    }
329
330    /**
331     * Compare two unix timestamp
332     *
333     * @param 	array 	$a		Operand a
334     * @param 	array 	$b		Operand b
335     * @return 	integer
336     */
337    function ical_dtstart_compare($a, $b)
338    {
339        return strnatcasecmp($a['DTSTART']['unixtime'], $b['DTSTART']['unixtime']);
340    }
341
342    /**
343     * Return eventlist array (not sort eventlist array)
344     *
345     * @return array
346     */
347    function get_event_list()
348    {
349        return (! empty($this->cal['VEVENT'])?$this->cal['VEVENT']:'');
350    }
351
352    /**
353     * Return eventlist array (not sort eventlist array)
354     *
355     * @return array
356     */
357    function get_freebusy_list()
358    {
359        return $this->cal['VFREEBUSY'];
360    }
361
362    /**
363     * Return to do array (not sort to do array)
364     *
365     * @return array
366     */
367    function get_todo_list()
368    {
369        return $this->cal['VTODO'];
370    }
371
372    /**
373     * Return base calendar data
374     *
375     * @return array
376     */
377    function get_calender_data()
378    {
379        return $this->cal['VCALENDAR'];
380    }
381
382    /**
383     * Return array with all data
384     *
385     * @return array
386     */
387    function get_all_data()
388    {
389        return $this->cal;
390    }
391}
392?>