PluginProbe
Booking Manager – Sync WP Booking Calendar – Import Events, Export Bookings to ICS Calendar / 2.0
Booking Manager – Sync WP Booking Calendar – Import Events, Export Bookings to ICS Calendar v2.0
2.1.21 2.1.20 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.1.9 trunk 1.1 2.0 2.0.1 2.0.10.2 2.0.11 2.0.12 2.0.13 2.0.14 2.0.15 2.0.16 2.0.17 2.0.18 2.0.2 2.0.20 2.0.21 2.0.22 All 55 releases
booking-manager / assets / libs / icalendar / includes / ical.php

ical.php in Booking Manager – Sync WP Booking Calendar – Import Events, Export Bookings to ICS Calendar 2.0, at assets/libs/icalendar/includes/ical.php

841 lines 20.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Zap Calendar ical Helper Class
4 *
5 * @copyright Copyright (C) 2006 - 2016 by Dan Cogliano
6 * @license GNU General Public License version 2 or later; see LICENSE.txt
7 */
8
9 // no direct access
10 defined('_ZAPCAL') or die( 'Restricted access' );
11
12 /**
13 * Object for storing an unfolded iCalendar line
14 *
15 * The ZCiCalDataNode class contains data from an unfolded iCalendar line
16 *
17 */
18
19 class ZCiCalDataNode {
20 /**
21 * The name of the node
22 *
23 * @var string
24 */
25 var $name = "";
26
27 /**
28 * Node parameters (before the colon ":")
29 *
30 * @var array
31 */
32 var $parameter=array();
33
34 /**
35 * Node values (after the colon ":")
36 *
37 * @var array
38 */
39 var $value=array();
40
41 /**
42 * Create an object from an unfolded iCalendar line
43 *
44 * @param string $line An unfolded iCalendar line
45 *
46 * @return void
47 *
48 */
49 function ZCiCalDataNode( $line ) {
50 //echo "ZCiCalDataNode($line)<br/>\n";
51 //separate line into parameters and value
52 // look for colon separating name or parameter and value
53 // first change any escaped colons temporarily to make it easier
54 $tline = str_replace("\\:", "`~", $line);
55 // see if first colon is inside a quoted string
56 $i = 0;
57 $datafind = false;
58 $inquotes = false;
59 while(!$datafind && ($i < strlen($tline))) {
60 //echo "$i: " . $tline{$i} . ", ord() = " . ord($tline{$i}) . "<br>\n";
61 if(!$inquotes && $tline{$i} == ':')
62 $datafind=true;
63 else{
64 $i += 1;
65 if(substr($tline,$i,1) == '"')
66 $inquotes = !$inquotes;
67 }
68 }
69 if($datafind){
70 $value = str_replace("`~","\\:",substr($line,$i+1));
71 // fix escaped characters (don't see double quotes in spec but Apple apparently uses it in iCal)
72 $value = str_replace(array('\\N' , '\\n', '\\"' ), array("\n", "\n" , '"'), $value);
73 $tvalue = str_replace("\\,", "`~", $value);
74 //echo "value: " . $tvalue . "<br>\n";
75 $tvalue = explode(",",$tvalue);
76 $value = str_replace("`~","\\,",$tvalue);
77 $this->value = $value;
78 }
79
80 $parameter = trim(substr($line,0,$i));
81
82 $parameter = str_replace("\\;", "`~", $parameter);
83 $parameters = explode(";", $parameter);
84 $parameters = str_replace("`~", "\\;", $parameters);
85 $this->name = array_shift($parameters);
86 foreach($parameters as $parameter){
87 $pos = strpos($parameter,"=");
88 if($pos > 0){
89 $param = substr($parameter,0,$pos);
90 $paramvalue = substr($parameter,$pos+1);
91 $tvalue = str_replace("\\,", "`~", $paramvalue);
92 //$tvalue = explode(",",$tvalue);
93 $paramvalue = str_replace("`~","\\,",$tvalue);
94 $this->parameter[strtolower($param)] = $paramvalue;
95 //$this->paramvalue[] = $paramvalue;
96 }
97 }
98 }
99
100 /**
101 * getName()
102 *
103 * Return the name of the object
104 *
105 * @return string
106 */
107 function getName(){
108 return $this->name;
109 }
110
111 /**
112 * Get $ith parameter from array
113 * @param int $i
114 *
115 * @return var
116 */
117 function getParameter($i){
118 return $this->parameter[$i];
119 }
120
121 /**
122 * Get parameter array
123 *
124 * @return array
125 */
126 function getParameters(){
127 return $this->parameter;
128 }
129
130 /**
131 * Get comma separated values
132 *
133 * @return string
134 */
135 function getValues(){
136 return implode(",",$this->value);
137 }
138 }
139
140 /**
141 * Object for storing a list of unfolded iCalendar lines (ZCiCalDataNode objects)
142 *
143 */
144
145 class ZCiCalNode {
146 var $name="";
147 var $parentnode=null;
148 var $child= array();
149 var $data= array();
150 var $next=null;
151 var $prev=null;
152
153 /**
154 * Create ZCiCalNode
155 *
156 * @param string $_name Name of node
157 *
158 * @param object $_parent Parent node for this node
159 *
160 * @param bool $first Is this the first child for this parent?
161 */
162 function ZCiCalNode( $_name, & $_parent, $first = false) {
163 $this->name = $_name;
164 $this->parentnode = $_parent;
165 if($_parent != null){
166 if(count($this->parentnode->child) > 0) {
167 if($first)
168 {
169 $first = & $this->parentnode->child[0];
170 $first->prev = & $this;
171 $this->next = & $first;
172 }
173 else
174 {
175 $prev =& $this->parentnode->child[count($this->parentnode->child)-1];
176 $prev->next =& $this;
177 $this->prev =& $prev;
178 }
179 }
180 if($first)
181 {
182 array_unshift($this->parentnode->child, $this);
183 }
184 else
185 {
186 $this->parentnode->child[] =& $this;
187 }
188 }
189 /*
190 echo "creating " . $this->getName();
191 if($_parent != null)
192 echo " child of " . $_parent->getName() . "/" . count($this->parentnode->child);
193 echo "<br/>";
194 */
195 }
196
197 /**
198 * Return the name of the object
199 *
200 * @return string
201 */
202 function getName() {
203 return $this->name;
204 }
205
206 /**
207 * Add node to list
208 *
209 * @param object $node
210 *
211 */
212 function addNode($node) {
213 $this->data[$node->getName()] = $node;
214 }
215
216 /**
217 * Get Attribute
218 *
219 * @param int $i array id of attribute to get
220 *
221 * @return string
222 */
223 function getAttrib($i) {
224 return $this->attrib[$i];
225 }
226
227 /**
228 * Set Attribute
229 *
230 * @param string $value value of attribute to set
231 *
232 */
233 function setAttrib($value) {
234 $this->attrib[] = $value;
235 }
236
237 /**
238 * Get the parent object of this object
239 *
240 * @return object parent of this object
241 */
242 function &getParent() {
243 return $this->parentnode;
244 }
245
246 /**
247 * Get the first child of this object
248 *
249 * @return object The first child
250 */
251 function &getFirstChild(){
252 static $nullguard = null;
253 if(count($this->child) > 0) {
254 //echo "moving from " . $this->getName() . " to " . $this->child[0]->getName() . "<br/>";
255 return $this->child[0];
256 }
257 else
258 return $nullguard;
259 }
260
261 /**
262 * Print object tree in HTML for debugging purposes
263 *
264 * @param object $node select part of tree to print, or leave blank for full tree
265 *
266 * @param int $level Level of recursion (usually leave this blank)
267 *
268 * @return string - HTML formatted display of object tree
269 */
270 function printTree(& $node=null, $level=1){
271 $level += 1;
272 $html = "";
273 if($node == null)
274 $node = $this->parentnode;
275 if($level > 5)
276 {
277 die("levels nested too deep<br/>\n");
278 //return;
279 }
280 for($i = 0 ; $i < $level; $i ++)
281 $html .= "+";
282 $html .= $node->getName() . "<br/>\n";
283 foreach ($node->child as $c){
284 $html .= $node->printTree($c,$level);
285 }
286 $level -= 1;
287 return $html;
288 }
289
290 /**
291 * export tree to icalendar format
292 *
293 * @param object $node Top level node to export
294 *
295 * @param int $level Level of recursion (usually leave this blank)
296 *
297 * @return string iCalendar formatted output
298 */
299 function export(& $node=null, $level=0){
300 $txtstr = "";
301 if($node == null)
302 $node = $this;
303 if($level > 5)
304 {
305 //die("levels nested too deep<br/>\n");
306 throw new Exception("levels nested too deep");
307 }
308 $txtstr .= "BEGIN:" . $node->getName() . "\r\n";
309 foreach ($node->data as $d){
310 $p = "";
311 $params = @$d->getParameters();
312 if(count($params) > 0)
313 {
314 foreach($params as $key => $value){
315 $p .= ";" . strtoupper($key) . "=" . $value;
316 }
317 }
318 $values = $d->getValues();
319 // don't think we need this, Sunbird does not like it in the EXDATE field
320 //$values = str_replace(",", "\\,", $values);
321
322 $line = $d->getName() . $p . ":" . $values;
323 $line = str_replace(array("<br>","<BR>","<br/>","<BR/"),"\\n",$line);
324 $line = str_replace(array("\r\n","\n\r","\n","\r"),'\n',$line);
325 //$line = str_replace(array(',',';','\\'), array('\\,','\\;','\\\\'),$line);
326 //$line =strip_tags($line);
327 $linecount = 0;
328 while (strlen($line) > 0) {
329 $linewidth = ($linecount == 0? 75 : 74);
330 $linesize = (strlen($line) > $linewidth? $linewidth: strlen($line));
331 if($linecount > 0)
332 $txtstr .= " ";
333 $txtstr .= substr($line,0,$linesize) . "\r\n";
334 $linecount += 1;
335 $line = substr($line,$linewidth);
336 }
337 //echo $line . "\n";
338 }
339 foreach ($node->child as $c){
340 $txtstr .= $node->export($c,$level + 1);
341 }
342 $txtstr .= "END:" . $node->getName() . "\r\n";
343 return $txtstr;
344 }
345
346 }
347
348 /**
349 *
350 * The main iCalendar object containing ZCiCalDataNodes and ZCiCalNodes.
351 *
352 */
353 class ZCiCal {
354 var $tree=null;
355 var $curnode=null;
356
357 /**
358 * The main iCalendar object containing ZCiCalDataNodes and ZCiCalNodes.
359 *
360 * use maxevents and startevent to read events in multiple passes (to save memory)
361 *
362 * @param string $data icalendar feed string (empty if creating new feed)
363 *
364 * @param int $maxevents maximum # of events to read
365 *
366 * @param int $startevent starting event to read
367 *
368 * @return void
369 *
370 *
371 */
372 function ZCiCal ($data = "", $maxevents = 1000000, $startevent = 0) {
373
374 if($data != ""){
375 // unfold lines
376 // first change all eol chars to "\n"
377 $data = str_replace(array("\r\n", "\n\r", "\n", "\r"), "\n", $data);
378 // now unfold lines
379 //$data = str_replace(array("\n ", "\n "),"!?", $data);
380 $data = str_replace(array("\n ", "\n "),"", $data);
381 // replace special iCal chars
382 $data = str_replace(array("\\\\","\,"),array("\\",","), $data);
383
384 // parse each line
385 $lines = explode("\n", $data);
386
387 //echo $data;
388 //exit;
389 $linecount = 0;
390 $eventcount = 0;
391 $eventpos = 0;
392 foreach($lines as $line) {
393 //$line = str_replace("!?", "\n", $line); // add nl back into descriptions
394 // echo ($linecount + 1) . ": " . $line . "<br/>";
395 if(substr($line,0,6) == "BEGIN:") {
396 // start new object
397 $name = substr($line,6);
398 if($name == "VEVENT")
399 {
400 if($eventcount < $maxevents && $eventpos >= $startevent)
401 {
402 $this->curnode = new ZCiCalNode($name, $this->curnode);
403 if($this->tree == null)
404 $this->tree = $this->curnode;
405 }
406 }
407 else
408 {
409 $this->curnode = new ZCiCalNode($name, $this->curnode);
410 if($this->tree == null)
411 $this->tree = $this->curnode;
412 }
413 //echo "new node: " . $this->curnode->name . "<br/>\n";
414 /*
415 if($this->curnode->getParent() != null)
416 echo "parent of " . $this->curnode->getName() . " is " . $this->curnode->getParent()->getName() . "<br/>";
417 else
418 echo "parent of " . $this->curnode->getName() . " is null<br/>";
419 */
420 }
421 else if(substr($line,0,4) == "END:") {
422 $name = substr($line,4);
423 if($name == "VEVENT")
424 {
425 if($eventcount < $maxevents && $eventpos >= $startevent)
426 {
427 $eventcount++;
428 if($this->curnode->getName() != $name) {
429 //panic, mismatch in iCal structure
430 //die("Can't read iCal file structure, expecting " . $this->curnode->getName() . " but reading $name instead");
431 throw new Exception("Can't read iCal file structure, expecting " . $this->curnode->getName() . " but reading $name instead");
432 }
433 if($this->curnode->getParent() != null) {
434 //echo "moving up from " . $this->curnode->getName() ;
435 $this->curnode = & $this->curnode->getParent();
436 //echo " to " . $this->curnode->getName() . "<br/>";
437 //echo $this->curnode->getName() . " has " . count($this->curnode->child) . " children<br/>";
438 }
439 }
440 $eventpos++;
441 }
442 else
443 {
444 if($this->curnode->getName() != $name) {
445 //panic, mismatch in iCal structure
446 //die("Can't read iCal file structure, expecting " . $this->curnode->getName() . " but reading $name instead");
447 throw new Exception("Can't read iCal file structure, expecting " . $this->curnode->getName() . " but reading $name instead");
448 }
449 if($this->curnode->getParent() != null) {
450 //echo "moving up from " . $this->curnode->getName() ;
451 $this->curnode = & $this->curnode->getParent();
452 //echo " to " . $this->curnode->getName() . "<br/>";
453 //echo $this->curnode->getName() . " has " . count($this->curnode->child) . " children<br/>";
454 }
455 }
456 }
457 else {
458 $datanode = new ZCiCalDataNode($line);
459 if($this->curnode->getName() == "VEVENT")
460 {
461 if($eventcount < $maxevents && $eventpos >= $startevent)
462 {
463 if($datanode->getName() == "EXDATE")
464 {
465 if(!array_key_exists($datanode->getName(),$this->curnode->data))
466 {
467 $this->curnode->data[$datanode->getName()] = $datanode;
468 }
469 else
470 {
471 $this->curnode->data[$datanode->getName()]->value[] = $datanode->value[0];
472 }
473 }
474 else
475 {
476 $this->curnode->data[$datanode->getName()] = $datanode;
477 }
478 }
479 }
480 else
481 {
482 if($datanode->getName() == "EXDATE")
483 {
484 if(!array_key_exists($datanode->getName(),$this->curnode->data))
485 {
486 $this->curnode->data[$datanode->getName()] = $datanode;
487 }
488 else
489 {
490 $this->curnode->data[$datanode->getName()]->value[] = $datanode->value[0];
491 }
492 }
493 else
494 {
495 $this->curnode->data[$datanode->getName()] = $datanode;
496 }
497 }
498 }
499 $linecount++;
500 }
501 }
502 else {
503 $name = "VCALENDAR";
504 $this->curnode = new ZCiCalNode($name, $this->curnode);
505 $this->tree = $this->curnode;
506 $datanode = new ZCiCalDataNode("VERSION:2.0");
507 $this->curnode->data[$datanode->getName()] = $datanode;
508
509 $datanode = new ZCiCalDataNode("PRODID:-//ZContent.net//Zap Calendar 1.0//EN");
510 $this->curnode->data[$datanode->getName()] = $datanode;
511 $datanode = new ZCiCalDataNode("CALSCALE:GREGORIAN");
512 $this->curnode->data[$datanode->getName()] = $datanode;
513 $datanode = new ZCiCalDataNode("METHOD:PUBLISH");
514 $this->curnode->data[$datanode->getName()] = $datanode;
515 }
516 }
517
518 /**
519 * CountEvents()
520 *
521 * Return the # of VEVENTs in the object
522 *
523 * @return int
524 */
525
526 function countEvents() {
527 $count = 0;
528 if(isset($this->tree->child)){
529 foreach($this->tree->child as $child){
530 if($child->getName() == "VEVENT")
531 $count++;
532 }
533 }
534 return $count;
535 }
536
537 /**
538 * CountVenues()
539 *
540 * Return the # of VVENUEs in the object
541 *
542 * @return int
543 */
544
545 function countVenues() {
546 $count = 0;
547 if(isset($this->tree->child)){
548 foreach($this->tree->child as $child){
549 if($child->getName() == "VVENUE")
550 $count++;
551 }
552 }
553 return $count;
554 }
555
556 /**
557 * Export object to string
558 *
559 * This function exports all objects to an iCalendar string
560 *
561 * @return string an iCalendar formatted string
562 */
563
564 function export() {
565 return $this->tree->export($this->tree);
566 }
567
568 /**
569 * Get first event in object list
570 * Use getNextEvent() to navigate through list
571 *
572 * @return object The first event, or null
573 */
574 function &getFirstEvent() {
575 static $nullguard = null;
576 if ($this->countEvents() > 0){
577 $child = $this->tree->child[0];
578 $event=false;
579 while(!$event && $child != null){
580 if($child->getName() == "VEVENT")
581 $event = true;
582 else
583 $child = $child->next;
584 }
585 return $child;
586 }
587 else
588 return $nullguard;
589 }
590
591 /**
592 * Get next event in object list
593 *
594 * @param object $event The current event object
595 *
596 * @return object Returns the next event or null if past last event
597 */
598 function &getNextEvent($event){
599 do{
600 $event = $event->next;
601 } while($event != null && $event->getName() != "VEVENT");
602 return $event;
603 }
604
605 /**
606 * Get first venue in object list
607 * Use getNextVenue() to navigate through list
608 *
609 * @return object The first venue, or null
610 */
611 function &getFirstVenue() {
612 static $nullguard = null;
613 if ($this->countVenues() > 0){
614 $child = $this->tree->child[0];
615 $event=false;
616 while(!$event && $child != null){
617 if($child->getName() == "VVENUE")
618 $event = true;
619 else
620 $child = $child->next;
621 }
622 return $child;
623 }
624 else
625 return $nullguard;
626 }
627
628 /**
629 * Get next venue in object list
630 *
631 * @param object $venue The current venue object
632 *
633 * @return object Returns the next venue or null if past last venue
634 */
635 function &getNextVenue($venue){
636 do{
637 $venue = $venue->next;
638 } while($venue != null && $venue->getName() != "VVENUE");
639 return $venue;
640 }
641
642 /**
643 * Get first child in object list
644 * Use getNextSibling() and getPreviousSibling() to navigate through list
645 *
646 * @param object $thisnode The parent object
647 *
648 * @return object The child object
649 */
650 function &getFirstChild(& $thisnode){
651 $nullvalue = null;
652 if(count($thisnode->child) > 0) {
653 //echo "moving from " . $thisnode->getName() . " to " . $thisnode->child[0]->getName() . "<br/>";
654 return $thisnode->child[0];
655 }
656 else
657 return $nullvalue;
658 }
659
660 /**
661 * Get next sibling in object list
662 *
663 * @param object $thisnode The current object
664 *
665 * @return object Returns the next sibling
666 */
667 function &getNextSibling(& $thisnode){
668 return $thisnode->next;
669 }
670
671 /**
672 * Get previous sibling in object list
673 *
674 * @param object $thisnode The current object
675 *
676 * @return object Returns the previous sibling
677 */
678 function &getPrevSibling(& $thisnode){
679 return $thisnode->prev;
680 }
681
682 /**
683 * Read date/time in iCal formatted string
684 *
685 * @param string iCal formated date/time string
686 *
687 * @return int Unix timestamp
688 */
689
690 function toUnixDateTime($datetime){
691 $year = substr($datetime,0,4);
692 $month = substr($datetime,4,2);
693 $day = substr($datetime,6,2);
694 $hour = 0;
695 $minute = 0;
696 $second = 0;
697 if(strlen($datetime) > 8 && $datetime{8} == "T") {
698 $hour = substr($datetime,9,2);
699 $minute = substr($datetime,11,2);
700 $second = substr($datetime,13,2);
701 }
702 $d1 = mktime($hour, $minute, $second, $month, $day, $year);
703
704 }
705
706 /**
707 * fromUnixDateTime()
708 *
709 * Take Unix timestamp and format to iCal date/time string
710 *
711 * @param int $datetime Unix timestamp, leave blank for current date/time
712 *
713 * @return string formatted iCal date/time string
714 */
715
716 static function fromUnixDateTime($datetime = null){
717 date_default_timezone_set('UTC');
718 if($datetime == null)
719 $datetime = time();
720 return date("Ymd\THis",$datetime);
721 }
722
723
724 /**
725 * fromUnixDate()
726 *
727 * Take Unix timestamp and format to iCal date string
728 *
729 * @param int $datetime Unix timestamp, leave blank for current date/time
730 *
731 * @return string formatted iCal date string
732 */
733
734 static function fromUnixDate($datetime = null){
735 date_default_timezone_set('UTC');
736 if($datetime == null)
737 $datetime = time();
738 return date("Ymd",$datetime);
739 }
740
741 /**
742 * Format into iCal time format from SQL date or SQL date-time format
743 *
744 * @param string $datetime SQL date or SQL date-time string
745 *
746 * @return string iCal formatted string
747 */
748 static function fromSqlDateTime($datetime = ""){
749 if($datetime == "")
750 $datetime = ZDateHelper::toSqlDateTime();
751 if(strlen($datetime) > 10)
752 return sprintf('%04d%02d%02dT%02d%02d%02d',substr($datetime,0,4),substr($datetime,5,2),substr($datetime,8,2),
753 substr($datetime,11,2),substr($datetime,14,2),substr($datetime,17,2));
754 else
755 return sprintf('%04d%02d%02d',substr($datetime,0,4),substr($datetime,5,2),substr($datetime,8,2));
756 }
757
758 /**
759 * Format iCal time format to either SQL date or SQL date-time format
760 *
761 * @param string $datetime icalendar formatted date or date-time
762 *
763 * @return string SQL date or SQL date-time string
764 */
765 static function toSqlDateTime($datetime = ""){
766 if($datetime == "")
767 return ZDateHelper::toSqlDateTime();
768 if(strlen($datetime) > 10)
769 return sprintf('%04d-%02d-%02d %02d:%02d:%02d',substr($datetime,0,4),substr($datetime,5,2),substr($datetime,8,2),
770 substr($datetime,11,2),substr($datetime,14,2),substr($datetime,17,2));
771 else
772 return sprintf('%04d-%02d-%02d',substr($datetime,0,4),substr($datetime,5,2),substr($datetime,8,2));
773 }
774
775 /**
776 * Pull timezone data from node and put in array
777 *
778 * Returning array contains the following array keys: tzoffsetfrom, tzoffsetto, tzname, dtstart, rrule
779 *
780 * @param array $node timezone object
781 *
782 * @return array
783 */
784 static function getTZValues($node){
785 $tzvalues = array();
786
787 $tnode = @$node->data['TZOFFSETFROM'];
788 if($tnode != null){
789 $tzvalues["tzoffsetfrom"] = $tnode->getValues();
790 }
791
792 $tnode = @$node->data['TZOFFSETTO'];
793 if($tnode != null){
794 $tzvalues["tzoffsetto"] = $tnode->getValues();
795 }
796
797 $tnode = @$node->data['TZNAME'];
798 if($tnode != null){
799 $tzvalues["tzname"] = $tnode->getValues();
800 }
801 else
802 $tzvalues["tzname"] = "";
803
804 $tnode = @$node->data['DTSTART'];
805 if($tnode != null){
806 $tzvalues["dtstart"] = ZDateHelper::fromiCaltoUnixDateTime($tnode->getValues());
807 }
808
809 $tnode = @$node->data['RRULE'];
810 if($tnode != null){
811 $tzvalues["rrule"] = $tnode->getValues();
812 //echo "rule: " . $tzvalues["rrule"] . "<br/>\n";
813 }
814 else{
815 // no rule specified, let's create one from based on the date
816 $date = getdate($tzvalues["dtstart"]);
817 $month = $date["mon"];
818 $day = $date["mday"];
819 $tzvalues["rrule"] = "FREQ=YEARLY;INTERVAL=1;BYMONTH=$month;BYMONTHDAY=$day";
820 }
821
822 return $tzvalues;
823 }
824
825 /**
826 * Escape slashes, commas and semicolons in strings
827 *
828 * @param string $content
829 *
830 * @return escaped string
831 */
832 static function formatContent($content)
833 {
834 $content = str_replace(array('\\' , ',' , ';' ), array('\\\\' , '\\,' , '\\;' ),$content);
835 return $content;
836 }
837
838 }
839
840 ?>
841