1
0
Fork 0
mirror of https://github.com/YunoHost-Apps/dolibarr_ynh.git synced 2024-09-03 18:35:53 +02:00
dolibarr_ynh/sources/dolibarr/htdocs/comm/action/class/ical.class.php

429 lines
12 KiB
PHP
Raw Normal View History

2015-09-28 22:09:38 +02:00
<?php
/* Copyright (C) 2006 Roman Ozana <ozana@omdesign.cz>
* Copyright (C) 2011 Juanjo Menent <jmenent@2byte.es>
* Copyright (C) 2013-2014 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2012 Regis Houssin <regis.houssin@capnetworks.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* \file htdocs/comm/action/class/ical.class.php
* \ingroup agenda
* \brief File of class to parse ical calendars
*/
require_once DOL_DOCUMENT_ROOT.'/core/lib/xcal.lib.php';
/**
* Class to read/parse ICal calendars
*/
class ICal
{
var $file_text; // Text in file
var $cal; // Array to save iCalendar parse data
var $event_count; // Number of Events
var $todo_count; // Number of Todos
var $freebusy_count; // Number of Freebusy
var $last_key; //Help variable save last key (multiline string)
/**
* Constructor
*/
public function __construct()
{
}
/**
* Read text file, icalender text file
*
* @param string $file File
* @return string
*/
function read_file($file)
{
$this->file = $file;
$file_text='';
$tmparray=file($file);
if (is_array($tmparray))
{
$file_text = join("", $tmparray); //load file
$file_text = preg_replace("/[\r\n]{1,} /","",$file_text);
}
return $file_text; // return all text
}
/**
* Returns the number of calendar events
*
* @return int
*/
function get_event_count()
{
return $this->event_count;
}
/**
* Returns the number of to do
*
* @return int
*/
function get_todo_count()
{
return $this->todo_count;
}
/**
* Translate Calendar
*
* @param string $uri Url
* @return array
*/
function parse($uri)
{
$this->cal = array(); // new empty array
$this->event_count = -1;
// read FILE text
$this->file_text = $this->read_file($uri);
$this->file_text = preg_split("[\n]", $this->file_text);
// is this text vcalendar standart text ? on line 1 is BEGIN:VCALENDAR
if (!stristr($this->file_text[0],'BEGIN:VCALENDAR')) return 'error not VCALENDAR';
$insidealarm=0;
$tmpkey='';$tmpvalue='';
foreach ($this->file_text as $text)
{
$text = trim($text); // trim one line
if (!empty($text))
{
// get Key and Value VCALENDAR:Begin -> Key = VCALENDAR, Value = begin
list($key, $value) = $this->retun_key_value($text);
//var_dump($text.' -> '.$key.' - '.$value);
switch ($text) // search special string
{
case "BEGIN:VTODO":
$this->todo_count = $this->todo_count+1; // new to do begin
$type = "VTODO";
break;
case "BEGIN:VEVENT":
$this->event_count = $this->event_count+1; // new event begin
$type = "VEVENT";
break;
case "BEGIN:VFREEBUSY":
$this->freebusy_count = $this->freebusy_count+1; // new event begin
$type = "VFREEBUSY";
break;
case "BEGIN:VCALENDAR": // all other special string
case "BEGIN:DAYLIGHT":
case "BEGIN:VTIMEZONE":
case "BEGIN:STANDARD":
$type = $value; // save array under value key
break;
case "END:VTODO": // end special text - goto VCALENDAR key
case "END:VEVENT":
case "END:VFREEBUSY":
case "END:VCALENDAR":
case "END:DAYLIGHT":
case "END:VTIMEZONE":
case "END:STANDARD":
$type = "VCALENDAR";
break;
// Manage VALARM that are inside a VEVENT to avoid fields of VALARM to overwrites fields of VEVENT
case "BEGIN:VALARM":
$insidealarm=1;
break;
case "END:VALARM":
$insidealarm=0;
break;
default: // no special string (SUMMARY, DESCRIPTION, ...)
if ($tmpvalue)
{
$tmpvalue .= $text;
if (! preg_match('/=$/',$text)) // No more lines
{
$key=$tmpkey;
$value=quotedPrintDecode(preg_replace('/^ENCODING=QUOTED-PRINTABLE:/i','',$tmpvalue));
$tmpkey='';
$tmpvalue='';
}
}
elseif (preg_match('/^ENCODING=QUOTED-PRINTABLE:/i',$value))
{
if (preg_match('/=$/',$value))
{
$tmpkey=$key;
$tmpvalue=$tmpvalue.preg_replace('/=$/',"",$value); // We must wait to have next line to have complete message
}
else
{
$value=quotedPrintDecode(preg_replace('/^ENCODING=QUOTED-PRINTABLE:/i','',$tmpvalue.$value));
}
} //$value=quotedPrintDecode($tmpvalue.$value);
if (! $insidealarm && ! $tmpkey) $this->add_to_array($type, $key, $value); // add to array
break;
}
}
}
//var_dump($this->cal);
return $this->cal;
}
/**
* Add to $this->ical array one value and key.
*
* @param string $type Type ('VTODO', 'VEVENT', 'VFREEBUSY', 'VCALENDAR'...)
* @param string $key Key ('DTSTART', ...). Note: Field is never 'DTSTART;TZID=...' because ';...' was before removed and added as another property
* @param string $value Value
* @return void
*/
function add_to_array($type, $key, $value)
{
//print 'type='.$type.' key='.$key.' value='.$value.'<br>'."\n";
if ($key == false)
{
$key = $this->last_key;
switch ($type)
{
case 'VEVENT': $value = $this->cal[$type][$this->event_count][$key].$value;break;
case 'VFREEBUSY': $value = $this->cal[$type][$this->freebusy_count][$key].$value;break;
case 'VTODO': $value = $this->cal[$type][$this->todo_count][$key].$value;break;
}
}
if (($key == "DTSTAMP") or ($key == "LAST-MODIFIED") or ($key == "CREATED")) $value = $this->ical_date_to_unix($value);
//if ($key == "RRULE" ) $value = $this->ical_rrule($value);
if (stristr($key,"DTSTART") or stristr($key,"DTEND") or stristr($key,"DTSTART;VALUE=DATE") or stristr($key,"DTEND;VALUE=DATE"))
{
if (stristr($key,"DTSTART;VALUE=DATE") or stristr($key,"DTEND;VALUE=DATE"))
{
list($key,$value) = array($key,$value);
}
else
{
list($key,$value) = $this->ical_dt_date($key,$value);
}
}
switch ($type)
{
case "VTODO":
$this->cal[$type][$this->todo_count][$key] = $value;
break;
case "VEVENT":
$this->cal[$type][$this->event_count][$key] = $value;
break;
case "VFREEBUSY":
$this->cal[$type][$this->freebusy_count][$key] = $value;
break;
default:
$this->cal[$type][$key] = $value;
break;
}
$this->last_key = $key;
}
/**
* Parse text "XXXX:value text some with : " and return array($key = "XXXX", $value="value");
*
* @param string $text Text
* @return array
*/
function retun_key_value($text)
{
/*
preg_match("/([^:]+)[:]([\w\W]+)/", $text, $matches);
if (empty($matches))
{
return array(false,$text);
}
else
{
$matches = array_splice($matches, 1, 2);
return $matches;
}*/
return explode(':',$text,2);
}
/**
* Parse RRULE return array
*
* @param string $value string
* @return array
*/
function ical_rrule($value)
{
$result=array();
$rrule = explode(';',$value);
foreach ($rrule as $line)
{
$rcontent = explode('=', $line);
$result[$rcontent[0]] = $rcontent[1];
}
return $result;
}
/**
* Return Unix time from ical date time fomrat (YYYYMMDD[T]HHMMSS[Z] or YYYYMMDD[T]HHMMSS)
*
* @param string $ical_date String date
* @return int
*/
function ical_date_to_unix($ical_date)
{
$ical_date = str_replace('T', '', $ical_date);
$ical_date = str_replace('Z', '', $ical_date);
$ntime=0;
// TIME LIMITED EVENT
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))
$ntime=dol_mktime($date[4], $date[5], $date[6], $date[2],$date[3], $date[1], true);
//if (empty($date[4])) print 'Error bad date: '.$ical_date.' - date1='.$date[1];
//print dol_print_date($ntime,'dayhour');exit;
return $ntime; // ntime is a GTM time
}
/**
* Return unix date from iCal date format
*
* @param string $key Key
* @param string $value Value
* @return array
*/
function ical_dt_date($key, $value)
{
$return_value=array();
$value = $this->ical_date_to_unix($value);
// Analyse TZID
$temp = explode(";",$key);
if (empty($temp[1])) // not TZID
{
$value = str_replace('T', '', $value);
return array($key,$value);
}
$key = $temp[0];
$temp = explode("=", $temp[1]);
$return_value[$temp[0]] = $temp[1];
$return_value['unixtime'] = $value;
return array($key,$return_value);
}
/**
* Return sorted eventlist as array or false if calenar is empty
*
* @return array
*/
function get_sort_event_list()
{
$temp = $this->get_event_list();
if (!empty($temp))
{
usort($temp, array(&$this, "ical_dtstart_compare"));
return $temp;
}
else
{
return false;
}
}
/**
* Compare two unix timestamp
*
* @param array $a Operand a
* @param array $b Operand b
* @return integer
*/
function ical_dtstart_compare($a, $b)
{
return strnatcasecmp($a['DTSTART']['unixtime'], $b['DTSTART']['unixtime']);
}
/**
* Return eventlist array (not sort eventlist array)
*
* @return array
*/
function get_event_list()
{
return (! empty($this->cal['VEVENT'])?$this->cal['VEVENT']:'');
}
/**
* Return eventlist array (not sort eventlist array)
*
* @return array
*/
function get_freebusy_list()
{
return $this->cal['VFREEBUSY'];
}
/**
* Return to do array (not sort to do array)
*
* @return array
*/
function get_todo_list()
{
return $this->cal['VTODO'];
}
/**
* Return base calendar data
*
* @return array
*/
function get_calender_data()
{
return $this->cal['VCALENDAR'];
}
/**
* Return array with all data
*
* @return array
*/
function get_all_data()
{
return $this->cal;
}
}