Passed
Pull Request — master (#2)
by
unknown
26:19
created

ICal::get_all_data()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
/* Copyright (C) 2006      Roman Ozana			<[email protected]>
3
 * Copyright (C) 2011	   Juanjo Menent		<[email protected]>
4
 * Copyright (C) 2013-2014 Laurent Destailleur	<[email protected]>
5
 * Copyright (C) 2012	   Regis Houssin		<[email protected]>
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
require_once DOL_DOCUMENT_ROOT.'/core/lib/xcal.lib.php';
27
28
29
/**
30
 *  Class to read/parse ICal calendars
31
 */
32
class ICal
33
{
34
    var $file_text; // Text in file
35
    var $cal; // Array to save iCalendar parse data
36
    var $event_count; // Number of Events
37
    var $todo_count; // Number of Todos
38
    var $freebusy_count; // Number of Freebusy
39
    var $last_key; //Help variable save last key (multiline string)
40
41
42
    /**
43
     * Constructor
44
     */
45
    public function __construct()
46
    {
47
    }
48
49
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
50
    /**
51
     * Read text file, icalender text file
52
     *
53
     * @param 	string 	$file		File
54
     * @return	string
55
     */
56
    function read_file($file)
57
    {
58
        // phpcs:enable
59
        $this->file = $file;
60
        $file_text='';
61
62
        $tmparray=file($file);
63
        if (is_array($tmparray))
64
        {
65
        	$file_text = join("", $tmparray); //load file
66
        	$file_text = preg_replace("/[\r\n]{1,} /","",$file_text);
67
        }
68
        return $file_text; // return all text
69
    }
70
71
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
72
    /**
73
     * Returns the number of calendar events
74
     *
75
     * @return int
76
     */
77
    function get_event_count()
78
    {
79
        // phpcs:enable
80
        return $this->event_count;
81
    }
82
83
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
84
    /**
85
     * Returns the number of to do
86
     *
87
     * @return int
88
     */
89
    function get_todo_count()
90
    {
91
        // phpcs:enable
92
        return $this->todo_count;
93
    }
94
95
    /**
96
     * Translate Calendar
97
     *
98
     * @param	string 	$uri	Url
99
     * @return	array
100
     */
101
    function parse($uri)
102
    {
103
        $this->cal = array(); // new empty array
104
105
        $this->event_count = -1;
106
107
        // read FILE text
108
        $this->file_text = $this->read_file($uri);
109
110
        $this->file_text = preg_split("[\n]", $this->file_text);
111
112
        // is this text vcalendar standart text ? on line 1 is BEGIN:VCALENDAR
113
        if (!stristr($this->file_text[0],'BEGIN:VCALENDAR')) return 'error not VCALENDAR';
114
115
        $insidealarm=0;
116
        $tmpkey='';$tmpvalue=''; $type='';
117
        foreach ($this->file_text as $text)
118
        {
119
            $text = trim($text); // trim one line
120
            if (!empty($text))
121
            {
122
                // get Key and Value VCALENDAR:Begin -> Key = VCALENDAR, Value = begin
123
                list($key, $value) = $this->retun_key_value($text);
124
				//var_dump($text.' -> '.$key.' - '.$value);
125
126
                switch ($text) // search special string
127
                {
128
                    case "BEGIN:VTODO":
129
                        $this->todo_count = $this->todo_count+1; // new to do begin
130
                        $type = "VTODO";
131
                        break;
132
133
                    case "BEGIN:VEVENT":
134
                        $this->event_count = $this->event_count+1; // new event begin
135
                        $type = "VEVENT";
136
                        break;
137
138
                    case "BEGIN:VFREEBUSY":
139
                        $this->freebusy_count = $this->freebusy_count+1; // new event begin
140
                        $type = "VFREEBUSY";
141
                        break;
142
143
                    case "BEGIN:VCALENDAR": // all other special string
144
                    case "BEGIN:DAYLIGHT":
145
                    case "BEGIN:VTIMEZONE":
146
                    case "BEGIN:STANDARD":
147
                        $type = $value; // save array under value key
148
                        break;
149
150
                    case "END:VTODO": // end special text - goto VCALENDAR key
151
                    case "END:VEVENT":
152
                    case "END:VFREEBUSY":
153
154
                    case "END:VCALENDAR":
155
                    case "END:DAYLIGHT":
156
                    case "END:VTIMEZONE":
157
                    case "END:STANDARD":
158
                        $type = "VCALENDAR";
159
                        break;
160
161
                    // Manage VALARM that are inside a VEVENT to avoid fields of VALARM to overwrites fields of VEVENT
162
                    case "BEGIN:VALARM":
163
                        $insidealarm=1;
164
                        break;
165
                    case "END:VALARM":
166
                        $insidealarm=0;
167
                        break;
168
169
                    default: // no special string (SUMMARY, DESCRIPTION, ...)
170
                    	if ($tmpvalue)
171
						{
172
							$tmpvalue .= $text;
173
							if (! preg_match('/=$/',$text))	// No more lines
174
							{
175
								$key=$tmpkey;
176
								$value=quotedPrintDecode(preg_replace('/^ENCODING=QUOTED-PRINTABLE:/i','',$tmpvalue));
177
								$tmpkey='';
178
								$tmpvalue='';
179
							}
180
						}
181
                    	elseif (preg_match('/^ENCODING=QUOTED-PRINTABLE:/i',$value))
182
                    	{
183
                    		if (preg_match('/=$/',$value))
184
                    		{
185
                    			$tmpkey=$key;
186
                    			$tmpvalue=$tmpvalue.preg_replace('/=$/',"",$value);	// We must wait to have next line to have complete message
187
                    		}
188
                    		else
189
                    		{
190
                    			$value=quotedPrintDecode(preg_replace('/^ENCODING=QUOTED-PRINTABLE:/i','',$tmpvalue.$value));
191
                    		}
192
                    	}                    	//$value=quotedPrintDecode($tmpvalue.$value);
193
                    	if (! $insidealarm && ! $tmpkey) $this->add_to_array($type, $key, $value); // add to array
194
                        break;
195
                }
196
            }
197
        }
198
199
        //var_dump($this->cal);
200
        return $this->cal;
201
    }
202
203
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
204
    /**
205
     * Add to $this->ical array one value and key.
206
     *
207
     * @param 	string 	$type		Type ('VTODO', 'VEVENT', 'VFREEBUSY', 'VCALENDAR'...)
208
     * @param 	string 	$key		Key	('DTSTART', ...). Note: Field is never 'DTSTART;TZID=...' because ';...' was before removed and added as another property
209
     * @param 	string 	$value		Value
210
     * @return	void
211
     */
212
    function add_to_array($type, $key, $value)
213
    {
214
        // phpcs:enable
215
216
        //print 'type='.$type.' key='.$key.' value='.$value.'<br>'."\n";
217
218
        if (empty($key))
219
        {
220
            $key = $this->last_key;
221
            switch ($type)
222
            {
223
                case 'VEVENT': $value = $this->cal[$type][$this->event_count][$key].$value;break;
224
                case 'VFREEBUSY': $value = $this->cal[$type][$this->freebusy_count][$key].$value;break;
225
                case 'VTODO': $value = $this->cal[$type][$this->todo_count][$key].$value;break;
226
            }
227
        }
228
229
        if (($key == "DTSTAMP") || ($key == "LAST-MODIFIED") || ($key == "CREATED")) $value = $this->ical_date_to_unix($value);
230
        //if ($key == "RRULE" ) $value = $this->ical_rrule($value);
231
232
        if (stristr($key,"DTSTART") || stristr($key,"DTEND") || stristr($key,"DTSTART;VALUE=DATE") || stristr($key,"DTEND;VALUE=DATE"))
233
        {
234
        	if (stristr($key,"DTSTART;VALUE=DATE") || stristr($key,"DTEND;VALUE=DATE"))
235
        	{
236
        		list($key,$value) = array($key,$value);
237
        	}
238
        	else
239
        	{
240
        		list($key,$value) = $this->ical_dt_date($key,$value);
241
        	}
242
        }
243
244
        switch ($type)
245
        {
246
            case "VTODO":
247
                $this->cal[$type][$this->todo_count][$key] = $value;
248
                break;
249
250
            case "VEVENT":
251
                $this->cal[$type][$this->event_count][$key] = $value;
252
                break;
253
254
            case "VFREEBUSY":
255
                $this->cal[$type][$this->freebusy_count][$key] = $value;
256
                break;
257
258
            default:
259
                $this->cal[$type][$key] = $value;
260
                break;
261
        }
262
        $this->last_key = $key;
263
    }
264
265
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
266
    /**
267
     * Parse text "XXXX:value text some with : " and return array($key = "XXXX", $value="value");
268
     *
269
     * @param 	string 	$text	Text
270
     * @return 	array
271
     */
272
    function retun_key_value($text)
273
    {
274
        // phpcs:enable
275
        /*
276
        preg_match("/([^:]+)[:]([\w\W]+)/", $text, $matches);
277
278
        if (empty($matches))
279
        {
280
            return array(false,$text);
281
        }
282
        else
283
        {
284
            $matches = array_splice($matches, 1, 2);
285
            return $matches;
286
        }*/
287
        return explode(':',$text,2);
288
    }
289
290
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
291
    /**
292
     * Parse RRULE  return array
293
     *
294
     * @param 	string 	$value	string
295
     * @return 	array
296
     */
297
    function ical_rrule($value)
298
    {
299
        // phpcs:enable
300
        $result = array();
301
        $rrule = explode(';',$value);
302
        foreach ($rrule as $line)
303
        {
304
            $rcontent = explode('=', $line);
305
            $result[$rcontent[0]] = $rcontent[1];
306
        }
307
        return $result;
308
    }
309
310
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
311
    /**
312
     * Return Unix time from ical date time fomrat (YYYYMMDD[T]HHMMSS[Z] or YYYYMMDD[T]HHMMSS)
313
     *
314
     * @param 	string		$ical_date		String date
315
     * @return 	int
316
     */
317
    function ical_date_to_unix($ical_date)
318
    {
319
        // phpcs:enable
320
        $ical_date = str_replace('T', '', $ical_date);
321
        $ical_date = str_replace('Z', '', $ical_date);
322
323
        $ntime=0;
324
        // TIME LIMITED EVENT
325
        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))
326
            $ntime=dol_mktime($date[4], $date[5], $date[6], $date[2],$date[3], $date[1], true);
327
328
        //if (empty($date[4])) print 'Error bad date: '.$ical_date.' - date1='.$date[1];
329
        //print dol_print_date($ntime,'dayhour');exit;
330
        return $ntime;      // ntime is a GTM time
0 ignored issues
show
Bug Best Practice introduced by
The expression return $ntime also could return the type string which is incompatible with the documented return type integer.
Loading history...
331
    }
332
333
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
334
    /**
335
     * Return unix date from iCal date format
336
     *
337
     * @param 	string 		$key			Key
338
     * @param 	string 		$value			Value
339
     * @return 	array
340
     */
341
    function ical_dt_date($key, $value)
342
    {
343
        // phpcs:enable
344
        $return_value = array();
345
        $value = $this->ical_date_to_unix($value);
346
347
        // Analyse TZID
348
        $temp = explode(";",$key);
349
350
        if (empty($temp[1])) // not TZID
351
        {
352
            $value = str_replace('T', '', $value);
353
            return array($key,$value);
354
        }
355
356
        $key = $temp[0];
357
        $temp = explode("=", $temp[1]);
358
        $return_value[$temp[0]] = $temp[1];
359
        $return_value['unixtime'] = $value;
360
361
        return array($key,$return_value);
362
    }
363
364
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
365
    /**
366
     * Return sorted eventlist as array or false if calenar is empty
367
     *
368
     * @return array
369
     */
370
    function get_sort_event_list()
371
    {
372
        // phpcs:enable
373
        $temp = $this->get_event_list();
374
        if (!empty($temp))
375
        {
376
            usort($temp, array(&$this, "ical_dtstart_compare"));
377
            return $temp;
378
        }
379
        else
380
       {
381
            return false;
382
        }
383
    }
384
385
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
386
    /**
387
     * Compare two unix timestamp
388
     *
389
     * @param 	array 	$a		Operand a
390
     * @param 	array 	$b		Operand b
391
     * @return 	integer
392
     */
393
    function ical_dtstart_compare($a, $b)
394
    {
395
        // phpcs:enable
396
        return strnatcasecmp($a['DTSTART']['unixtime'], $b['DTSTART']['unixtime']);
397
    }
398
399
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
400
    /**
401
     * Return eventlist array (not sort eventlist array)
402
     *
403
     * @return array
404
     */
405
    function get_event_list()
406
    {
407
        // phpcs:enable
408
        return (! empty($this->cal['VEVENT'])?$this->cal['VEVENT']:'');
0 ignored issues
show
Bug Best Practice introduced by
The expression return ! empty($this->ca...his->cal['VEVENT'] : '' also could return the type string which is incompatible with the documented return type array.
Loading history...
409
    }
410
411
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
412
    /**
413
     * Return eventlist array (not sort eventlist array)
414
     *
415
     * @return array
416
     */
417
    function get_freebusy_list()
418
    {
419
        // phpcs:enable
420
        return $this->cal['VFREEBUSY'];
421
    }
422
423
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
424
    /**
425
     * Return to do array (not sort to do array)
426
     *
427
     * @return array
428
     */
429
    function get_todo_list()
430
    {
431
        // phpcs:enable
432
        return $this->cal['VTODO'];
433
    }
434
435
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
436
    /**
437
     * Return base calendar data
438
     *
439
     * @return array
440
     */
441
    function get_calender_data()
442
    {
443
        // phpcs:enable
444
        return $this->cal['VCALENDAR'];
445
    }
446
447
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
448
    /**
449
     * Return array with all data
450
     *
451
     * @return array
452
     */
453
    function get_all_data()
454
    {
455
        // phpcs:enable
456
        return $this->cal;
457
    }
458
}
459