PageRenderTime 45ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/htdocs/comm/action/class/ical.class.php

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