PageRenderTime 48ms CodeModel.GetById 18ms RepoModel.GetById 0ms 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
Possible License(s): LGPL-3.0, LGPL-2.1, GPL-3.0, MIT
  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. * \file htdocs/comm/action/class/ical.class.php
  22. * \ingroup agenda
  23. * \brief File of class to parse ical calendars
  24. */
  25. /**
  26. * Class to parse ICal calendars
  27. */
  28. class ICal
  29. {
  30. var $file_text; // Text in file
  31. var $cal; // Array to save iCalendar parse data
  32. var $event_count; // Number of Events
  33. var $todo_count; // Number of Todos
  34. var $freebusy_count; // Number of Freebusy
  35. var $last_key; //Help variable save last key (multiline string)
  36. /**
  37. * Constructor
  38. */
  39. public function __construct()
  40. {
  41. }
  42. /**
  43. * Read text file, icalender text file
  44. *
  45. * @param string $file File
  46. * @return string
  47. */
  48. function read_file($file)
  49. {
  50. $this->file = $file;
  51. $file_text = join("", file($file)); //load file
  52. $file_text = preg_replace("/[\r\n]{1,} ([:;])/","\\1",$file_text);
  53. return $file_text; // return all text
  54. }
  55. /**
  56. * Returns the number of calendar events
  57. *
  58. * @return int
  59. */
  60. function get_event_count()
  61. {
  62. return $this->event_count;
  63. }
  64. /**
  65. * Returns the number of to do
  66. *
  67. * @return int
  68. */
  69. function get_todo_count()
  70. {
  71. return $this->todo_count;
  72. }
  73. /**
  74. * Translate Calendar
  75. *
  76. * @param string $uri Url
  77. * @return array
  78. */
  79. function parse($uri)
  80. {
  81. $this->cal = array(); // new empty array
  82. $this->event_count = -1;
  83. // read FILE text
  84. $this->file_text = $this->read_file($uri);
  85. $this->file_text = preg_split("[\n]", $this->file_text);
  86. // is this text vcalendar standart text ? on line 1 is BEGIN:VCALENDAR
  87. if (!stristr($this->file_text[0],'BEGIN:VCALENDAR')) return 'error not VCALENDAR';
  88. $insidealarm=0;
  89. foreach ($this->file_text as $text)
  90. {
  91. $text = trim($text); // trim one line
  92. if (!empty($text))
  93. {
  94. // get Key and Value VCALENDAR:Begin -> Key = VCALENDAR, Value = begin
  95. list($key, $value) = $this->retun_key_value($text);
  96. switch ($text) // search special string
  97. {
  98. case "BEGIN:VTODO":
  99. $this->todo_count = $this->todo_count+1; // new to do begin
  100. $type = "VTODO";
  101. break;
  102. case "BEGIN:VEVENT":
  103. $this->event_count = $this->event_count+1; // new event begin
  104. $type = "VEVENT";
  105. break;
  106. case "BEGIN:VFREEBUSY":
  107. $this->freebusy_count = $this->freebusy_count+1; // new event begin
  108. $type = "VFREEBUSY";
  109. break;
  110. case "BEGIN:VCALENDAR": // all other special string
  111. case "BEGIN:DAYLIGHT":
  112. case "BEGIN:VTIMEZONE":
  113. case "BEGIN:STANDARD":
  114. $type = $value; // save tu array under value key
  115. break;
  116. case "END:VTODO": // end special text - goto VCALENDAR key
  117. case "END:VEVENT":
  118. case "END:VFREEBUSY":
  119. case "END:VCALENDAR":
  120. case "END:DAYLIGHT":
  121. case "END:VTIMEZONE":
  122. case "END:STANDARD":
  123. $type = "VCALENDAR";
  124. break;
  125. // Manage VALARM that are inside a VEVENT to avoid fields of VALARM to overwrites fields of VEVENT
  126. case "BEGIN:VALARM":
  127. $insidealarm=1;
  128. break;
  129. case "END:VALARM":
  130. $insidealarm=0;
  131. break;
  132. default: // no special string
  133. if (! $insidealarm) $this->add_to_array($type, $key, $value); // add to array
  134. break;
  135. }
  136. }
  137. }
  138. return $this->cal;
  139. }
  140. /**
  141. * Add to $this->ical array one value and key.
  142. *
  143. * @param string $type Type ('VTODO', 'VEVENT', 'VFREEBUSY', 'VCALENDAR'...)
  144. * @param string $key Key ('DTSTART', ...). Note: Field is never 'DTSTART;TZID=...' because ';...' was before removed and added as another property
  145. * @param string $value Value
  146. * @return void
  147. */
  148. function add_to_array($type, $key, $value)
  149. {
  150. //print 'type='.$type.' key='.$key.' value='.$value.'<br>'."\n";
  151. if ($key == false)
  152. {
  153. $key = $this->last_key;
  154. switch ($type)
  155. {
  156. case 'VEVENT': $value = $this->cal[$type][$this->event_count][$key].$value;break;
  157. case 'VFREEBUSY': $value = $this->cal[$type][$this->freebusy_count][$key].$value;break;
  158. case 'VTODO': $value = $this->cal[$type][$this->todo_count][$key].$value;break;
  159. }
  160. }
  161. if (($key == "DTSTAMP") or ($key == "LAST-MODIFIED") or ($key == "CREATED")) $value = $this->ical_date_to_unix($value);
  162. if ($key == "RRULE" ) $value = $this->ical_rrule($value);
  163. if (stristr($key,"DTSTART") or stristr($key,"DTEND") or stristr($key,"DTSTART;VALUE=DATE") or stristr($key,"DTEND;VALUE=DATE"))
  164. {
  165. if (stristr($key,"DTSTART;VALUE=DATE") or stristr($key,"DTEND;VALUE=DATE"))
  166. {
  167. list($key,$value) = array($key,$value);
  168. }
  169. else
  170. {
  171. list($key,$value) = $this->ical_dt_date($key,$value);
  172. }
  173. }
  174. switch ($type)
  175. {
  176. case "VTODO":
  177. $this->cal[$type][$this->todo_count][$key] = $value;
  178. break;
  179. case "VEVENT":
  180. $this->cal[$type][$this->event_count][$key] = $value;
  181. break;
  182. case "VFREEBUSY":
  183. $this->cal[$type][$this->freebusy_count][$key] = $value;
  184. break;
  185. default:
  186. $this->cal[$type][$key] = $value;
  187. break;
  188. }
  189. $this->last_key = $key;
  190. }
  191. /**
  192. * Parse text "XXXX:value text some with : " and return array($key = "XXXX", $value="value");
  193. *
  194. * @param string $text Text
  195. * @return array
  196. */
  197. function retun_key_value($text)
  198. {
  199. preg_match("/([^:]+)[:]([\w\W]+)/", $text, $matches);
  200. if (empty($matches))
  201. {
  202. return array(false,$text);
  203. }
  204. else
  205. {
  206. $matches = array_splice($matches, 1, 2);
  207. return $matches;
  208. }
  209. }
  210. /**
  211. * Parse RRULE return array
  212. *
  213. * @param string $value string
  214. * @return array
  215. */
  216. function ical_rrule($value)
  217. {
  218. $rrule = explode(';',$value);
  219. foreach ($rrule as $line)
  220. {
  221. $rcontent = explode('=', $line);
  222. $result[$rcontent[0]] = $rcontent[1];
  223. }
  224. return $result;
  225. }
  226. /**
  227. * Return Unix time from ical date time fomrat (YYYYMMDD[T]HHMMSS[Z] or YYYYMMDD[T]HHMMSS)
  228. *
  229. * @param string $ical_date String date
  230. * @return timestamp
  231. */
  232. function ical_date_to_unix($ical_date)
  233. {
  234. $ical_date = str_replace('T', '', $ical_date);
  235. $ical_date = str_replace('Z', '', $ical_date);
  236. $ntime=0;
  237. // TIME LIMITED EVENT
  238. 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))
  239. $ntime=dol_mktime($date[4], $date[5], $date[6], $date[2],$date[3], $date[1], true);
  240. //if (empty($date[4])) print 'Error bad date: '.$ical_date.' - date1='.$date[1];
  241. //print dol_print_date($ntime,'dayhour');exit;
  242. return $ntime; // ntime is a GTM time
  243. }
  244. /**
  245. * Return unix date from iCal date format
  246. *
  247. * @param string $key Key
  248. * @param string $value Value
  249. * @return array
  250. */
  251. function ical_dt_date($key, $value)
  252. {
  253. $value = $this->ical_date_to_unix($value);
  254. // Analyse TZID
  255. $temp = explode(";",$key);
  256. if (empty($temp[1])) // not TZID
  257. {
  258. $value = str_replace('T', '', $value);
  259. return array($key,$value);
  260. }
  261. // adding $value and $tzid
  262. $key = $temp[0];
  263. $temp = explode("=", $temp[1]);
  264. $return_value[$temp[0]] = $temp[1];
  265. $return_value['unixtime'] = $value;
  266. return array($key,$return_value);
  267. }
  268. /**
  269. * Return sorted eventlist as array or false if calenar is empty
  270. *
  271. * @return array
  272. */
  273. function get_sort_event_list()
  274. {
  275. $temp = $this->get_event_list();
  276. if (!empty($temp))
  277. {
  278. usort($temp, array(&$this, "ical_dtstart_compare"));
  279. return $temp;
  280. } else
  281. {
  282. return false;
  283. }
  284. }
  285. /**
  286. * Compare two unix timestamp
  287. *
  288. * @param array $a Operand a
  289. * @param array $b Operand b
  290. * @return integer
  291. */
  292. function ical_dtstart_compare($a, $b)
  293. {
  294. return strnatcasecmp($a['DTSTART']['unixtime'], $b['DTSTART']['unixtime']);
  295. }
  296. /**
  297. * Return eventlist array (not sort eventlist array)
  298. *
  299. * @return array
  300. */
  301. function get_event_list()
  302. {
  303. return (! empty($this->cal['VEVENT'])?$this->cal['VEVENT']:'');
  304. }
  305. /**
  306. * Return eventlist array (not sort eventlist array)
  307. *
  308. * @return array
  309. */
  310. function get_freebusy_list()
  311. {
  312. return $this->cal['VFREEBUSY'];
  313. }
  314. /**
  315. * Return to do array (not sort to do array)
  316. *
  317. * @return array
  318. */
  319. function get_todo_list()
  320. {
  321. return $this->cal['VTODO'];
  322. }
  323. /**
  324. * Return base calendar data
  325. *
  326. * @return array
  327. */
  328. function get_calender_data()
  329. {
  330. return $this->cal['VCALENDAR'];
  331. }
  332. /**
  333. * Return array with all data
  334. *
  335. * @return array
  336. */
  337. function get_all_data()
  338. {
  339. return $this->cal;
  340. }
  341. }
  342. ?>