ILIAS  release_4-3 Revision
 All Data Structures Namespaces Files Functions Variables Groups Pages
class.ilvCard.php
Go to the documentation of this file.
1 <?php
2 /*
3  +-----------------------------------------------------------------------------+
4  | ILIAS open source |
5  +-----------------------------------------------------------------------------+
6  | Copyright (c) 1998-2001 ILIAS open source, University of Cologne |
7  | |
8  | This program is free software; you can redistribute it and/or |
9  | modify it under the terms of the GNU General Public License |
10  | as published by the Free Software Foundation; either version 2 |
11  | of the License, or (at your option) any later version. |
12  | |
13  | This program is distributed in the hope that it will be useful, |
14  | but WITHOUT ANY WARRANTY; without even the implied warranty of |
15  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16  | GNU General Public License for more details. |
17  | |
18  | You should have received a copy of the GNU General Public License |
19  | along with this program; if not, write to the Free Software |
20  | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
21  +-----------------------------------------------------------------------------+
22 */
23 
37 define ("ADR_TYPE_NONE", 0);
38 define ("ADR_TYPE_DOM", 1);
39 define ("ADR_TYPE_INTL", 2);
40 define ("ADR_TYPE_POSTAL", 4);
41 define ("ADR_TYPE_PARCEL", 8);
42 define ("ADR_TYPE_HOME", 16);
43 define ("ADR_TYPE_WORK", 32);
44 define ("ADR_TYPE_PREF", 64);
45 
51 define ("TEL_TYPE_NONE", 0);
52 define ("TEL_TYPE_HOME", 1);
53 define ("TEL_TYPE_MSG", 2);
54 define ("TEL_TYPE_WORK", 4);
55 define ("TEL_TYPE_PREF", 8);
56 define ("TEL_TYPE_VOICE", 16);
57 define ("TEL_TYPE_FAX", 32);
58 define ("TEL_TYPE_CELL", 64);
59 define ("TEL_TYPE_VIDEO", 128);
60 define ("TEL_TYPE_PAGER", 256);
61 define ("TEL_TYPE_BBS", 512);
62 define ("TEL_TYPE_MODEM", 1024);
63 define ("TEL_TYPE_CAR", 2048);
64 define ("TEL_TYPE_ISDN", 4096);
65 define ("TEL_TYPE_PCS", 8192);
66 
72 define ("EMAIL_TYPE_NONE", 0);
73 define ("EMAIL_TYPE_INTERNET", 1);
74 define ("EMAIL_TYPE_x400", 2);
75 define ("EMAIL_TYPE_PREF", 4);
76 
77 class ilvCard
78 {
84  var $types;
85 
91  var $filename;
92 
98  function ilvCard($version = "3.0")
99  {
100  $this->types = array(
101  "FN" => "",
102  "N" => "",
103  "NICKNAME" => "",
104  "PHOTO" => array(),
105  "BDAY" => "",
106  "ADR" => array(),
107  "LABEL" => array(),
108  "TEL" => array(),
109  "EMAIL" => array(),
110  "MAILER" => "",
111  "TZ" => "",
112  "GEO" => "",
113  "TITLE" => "",
114  "ROLE" => "",
115  "LOGO" => array(),
116  "AGENT" => "",
117  "ORG" => "",
118  "CATEGORIES" => "",
119  "NOTE" => "",
120  "PRODID" => "",
121  "REV" => "",
122  "SORT-STRING" => "",
123  "SOUND" => array(),
124  "UID" => "",
125  "URL" => "",
126  "VERSION" => "3.0",
127  "CLASS" => "",
128  "KEY" => array()
129  );
130  $this->types["VERSION"] = $version;
131  }
132 
142  function encode($string)
143  {
144  return escape(quoted_printable_encode($string));
145  }
146 
157  function fold($string = "", $length = 75)
158  {
159  $folded_string = "";
160  preg_match_all("/(.{1,74})/", $string, $matches);
161  for ($i = 0; $i < count($matches[1]); $i++)
162  {
163  if ($i < (count($matches[1])-1))
164  {
165  $matches[1][$i] .= "\n";
166  }
167  if ($i > 0)
168  {
169  $matches[1][$i] = " " . $matches[1][$i];
170  }
171  $folded_string .= $matches[1][$i];
172  }
173  return $folded_string;
174  }
175 
185  function escape($string)
186  {
187  $string = preg_replace("/(?<!\\\\)(\\\\)([^;,n\\\\])/", "\${1}\${1}\${2}", $string);
188  $string = preg_replace("/(?<!\\\\);/", "\\;", $string);
189  $string = preg_replace("/(?<!\\\\),/", "\\,", $string);
190  $string = preg_replace("/\n/","\\n", $string);
191  return $string;
192  }
193 
204  function &explodeVar($variable, $separator = ",")
205  {
206  $exploded = explode($separator, $variable);
207  foreach ($exploded as $index => $var)
208  {
209  $exploded[$index] = $this->escape($var);
210  }
211  return $exploded;
212  }
213 
222  function buildVCard()
223  {
224  $vcard = "BEGIN:VCARD\n";
225  $vcard .= "VERSION:" . $this->types["VERSION"] . "\n";
226  foreach ($this->types as $type => $var)
227  {
228  switch ($type)
229  {
230  case "FN":
231  if (strcmp($this->types["FN"], "") != 0)
232  {
233  $fn = $this->fold("FN:" . $this->types["FN"]) . "\n";
234  }
235  else
236  {
237  $fn = "";
238  }
239  break;
240  case "N":
241  if (strcmp($this->types["N"], "") != 0)
242  {
243  $n = $this->fold("N:" . $this->types["N"]) . "\n";
244  }
245  else
246  {
247  $n = "";
248  }
249  break;
250  case "NICKNAME":
251  if (strcmp($this->types["NICKNAME"], "") != 0)
252  {
253  $nickname = $this->fold("NICKNAME:" . $this->types["NICKNAME"]) . "\n";
254  }
255  else
256  {
257  $nickname = "";
258  }
259  break;
260  case "PHOTO":
261  if (strcmp($this->types["PHOTO"]["VALUE"], "") != 0)
262  {
263  $photo = $this->fold("PHOTO;VALUE=uri:" . $this->types["PHOTO"]["VALUE"]) . "\n";
264  }
265  elseif (strcmp($this->types["PHOTO"]["ENCODING"], "") != 0)
266  {
267  $photo = "PHOTO;ENCODING=" . $this->types["PHOTO"]["ENCODING"];
268  if (strcmp($this->types["PHOTO"]["TYPE"], "") != 0)
269  {
270  $photo .= ";TYPE=" . $this->types["PHOTO"]["TYPE"];
271  }
272  $photo .= ":" . $this->types["PHOTO"]["PHOTO"];
273  $photo = $this->fold($photo) . "\n";
274  }
275  else
276  {
277  $photo = "";
278  }
279  break;
280  case "BDAY":
281  if (strcmp($this->types["BDAY"], "") != 0)
282  {
283  $bday = $this->fold("BDAY:" . $this->types["BDAY"]) . "\n";
284  }
285  else
286  {
287  $bday = "";
288  }
289  break;
290  case "ADR":
291  if (count($this->types["ADR"]))
292  {
293  $addresses = "";
294  foreach ($this->types["ADR"] as $key => $address)
295  {
296  $test = "";
297  foreach ($address as $str)
298  {
299  $test .= $str;
300  }
301  if (strcmp($test, "") != 0)
302  {
303  $adr = "ADR";
304  $adr_types = array();
305  if ($address["TYPE"] > 0)
306  {
307  if (($address["TYPE"] & ADR_TYPE_DOM) > 0)
308  {
309  array_push($adr_types, "dom");
310  }
311  if (($address["TYPE"] & ADR_TYPE_INTL) > 0)
312  {
313  array_push($adr_types, "intl");
314  }
315  if (($address["TYPE"] & ADR_TYPE_POSTAL) > 0)
316  {
317  array_push($adr_types, "postal");
318  }
319  if (($address["TYPE"] & ADR_TYPE_PARCEL) > 0)
320  {
321  array_push($adr_types, "parcel");
322  }
323  if (($address["TYPE"] & ADR_TYPE_HOME) > 0)
324  {
325  array_push($adr_types, "home");
326  }
327  if (($address["TYPE"] & ADR_TYPE_WORK) > 0)
328  {
329  array_push($adr_types, "work");
330  }
331  if (($address["TYPE"] & ADR_TYPE_PREF) > 0)
332  {
333  array_push($adr_types, "pref");
334  }
335  $adr .= ";TYPE=" . join(",", $adr_types);
336  }
337  $adr .= ":" . $address["POBOX"] . ";" . $address["EXTENDED_ADDRESS"] .
338  ";" . $address["STREET_ADDRESS"] . ";" . $address["LOCALITY"] .
339  ";" . $address["REGION"] . ";" . $address["POSTAL_CODE"] .
340  ";" . $address["COUNTRY"];
341  $adr = $this->fold($adr) . "\n";
342  $addresses .= $adr;
343  }
344  }
345  $adr = $addresses;
346  }
347  else
348  {
349  $adr = "";
350  }
351  break;
352  case "LABEL":
353  if (strcmp($this->types["LABEL"]["LABEL"], "") != 0)
354  {
355  $label = "LABEL";
356  $adr_types = array();
357  if ($this->types["LABEL"]["TYPE"] > 0)
358  {
359  if (($this->types["LABEL"]["TYPE"] & ADR_TYPE_DOM) > 0)
360  {
361  array_push($adr_types, "dom");
362  }
363  if (($this->types["LABEL"]["TYPE"] & ADR_TYPE_INTL) > 0)
364  {
365  array_push($adr_types, "intl");
366  }
367  if (($this->types["LABEL"]["TYPE"] & ADR_TYPE_POSTAL) > 0)
368  {
369  array_push($adr_types, "postal");
370  }
371  if (($this->types["LABEL"]["TYPE"] & ADR_TYPE_PARCEL) > 0)
372  {
373  array_push($adr_types, "parcel");
374  }
375  if (($this->types["LABEL"]["TYPE"] & ADR_TYPE_HOME) > 0)
376  {
377  array_push($adr_types, "home");
378  }
379  if (($this->types["LABEL"]["TYPE"] & ADR_TYPE_WORK) > 0)
380  {
381  array_push($adr_types, "work");
382  }
383  if (($this->types["LABEL"]["TYPE"] & ADR_TYPE_PREF) > 0)
384  {
385  array_push($adr_types, "pref");
386  }
387  $label .= ";TYPE=" . join(",", $adr_types);
388  }
389  $label .= ":" . $this->types["LABEL"]["LABEL"];
390  $label = $this->fold($label) . "\n";
391  }
392  else
393  {
394  $label = "";
395  }
396  break;
397  case "TEL":
398  if (count($this->types["TEL"]))
399  {
400  $phonenumbers = "";
401  foreach ($this->types["TEL"] as $key => $phone)
402  {
403  if (strcmp($phone["TEL"], "") != 0)
404  {
405  $tel = "TEL";
406  $tel_types = array();
407  if ($phone["TYPE"] > 0)
408  {
409  if (($phone["TYPE"] & TEL_TYPE_HOME) > 0)
410  {
411  array_push($tel_types, "home");
412  }
413  if (($phone["TYPE"] & TEL_TYPE_MSG) > 0)
414  {
415  array_push($tel_types, "msg");
416  }
417  if (($phone["TYPE"] & TEL_TYPE_WORK) > 0)
418  {
419  array_push($tel_types, "work");
420  }
421  if (($phone["TYPE"] & TEL_TYPE_PREF) > 0)
422  {
423  array_push($tel_types, "pref");
424  }
425  if (($phone["TYPE"] & TEL_TYPE_VOICE) > 0)
426  {
427  array_push($tel_types, "voice");
428  }
429  if (($phone["TYPE"] & TEL_TYPE_FAX) > 0)
430  {
431  array_push($tel_types, "fax");
432  }
433  if (($phone["TYPE"] & TEL_TYPE_CELL) > 0)
434  {
435  array_push($tel_types, "cell");
436  }
437  if (($phone["TYPE"] & TEL_TYPE_VIDEO) > 0)
438  {
439  array_push($tel_types, "video");
440  }
441  if (($phone["TYPE"] & TEL_TYPE_PAGER) > 0)
442  {
443  array_push($tel_types, "pager");
444  }
445  if (($phone["TYPE"] & TEL_TYPE_BBS) > 0)
446  {
447  array_push($tel_types, "bbs");
448  }
449  if (($phone["TYPE"] & TEL_TYPE_MODEM) > 0)
450  {
451  array_push($tel_types, "modem");
452  }
453  if (($phone["TYPE"] & TEL_TYPE_CAR) > 0)
454  {
455  array_push($tel_types, "car");
456  }
457  if (($phone["TYPE"] & TEL_TYPE_ISDN) > 0)
458  {
459  array_push($tel_types, "isdn");
460  }
461  if (($phone["TYPE"] & TEL_TYPE_PCS) > 0)
462  {
463  array_push($tel_types, "pcs");
464  }
465  $tel .= ";TYPE=" . join(",", $tel_types);
466  }
467  $tel .= ":" . $phone["TEL"];
468  $tel = $this->fold($tel) . "\n";
469  $phonenumbers .= $tel;
470  }
471  }
472  $tel = $phonenumbers;
473  }
474  else
475  {
476  $tel = "";
477  }
478  break;
479  case "EMAIL":
480  if (count($this->types["EMAIL"]))
481  {
482  $emails = "";
483  foreach ($this->types["EMAIL"] as $key => $mail)
484  {
485  if (strcmp($mail["EMAIL"], "") != 0)
486  {
487  $email = "EMAIL";
488  $adr_types = array();
489  if ($mail["TYPE"] > 0)
490  {
491  if (($mail["TYPE"] & EMAIL_TYPE_INTERNET) > 0)
492  {
493  array_push($adr_types, "internet");
494  }
495  if (($mail["TYPE"] & EMAIL_TYPE_x400) > 0)
496  {
497  array_push($adr_types, "x400");
498  }
499  if (($mail["TYPE"] & EMAIL_TYPE_PREF) > 0)
500  {
501  array_push($adr_types, "pref");
502  }
503  $email .= ";TYPE=" . join(",", $adr_types);
504  }
505  $email .= ":" . $mail["EMAIL"];
506  $email = $this->fold($email) . "\n";
507  $emails .= $email;
508  }
509  }
510  $email = $emails;
511  }
512  else
513  {
514  $email = "";
515  }
516  break;
517  case "MAILER":
518  if (strcmp($this->types["MAILER"], "") != 0)
519  {
520  $mailer = $this->fold("MAILER:" . $this->types["MAILER"]) . "\n";
521  }
522  else
523  {
524  $mailer = "";
525  }
526  break;
527  case "TZ":
528  if (strcmp($this->types["TZ"], "") != 0)
529  {
530  $tz = $this->fold("TZ:" . $this->types["TZ"]) . "\n";
531  }
532  else
533  {
534  $tz = "";
535  }
536  break;
537  case "GEO":
538  if ((strcmp($this->types["GEO"]["LAT"], "") != 0) and (strcmp($this->types["GEO"]["LON"], "") != 0))
539  {
540  $geo = $this->fold("GEO:" . $this->types["GEO"]["LAT"] . ";" . $this->types["GEO"]["LON"]) . "\n";
541  }
542  else
543  {
544  $geo = "";
545  }
546  break;
547  case "TITLE":
548  if (strcmp($this->types["TITLE"], "") != 0)
549  {
550  $title = $this->fold("TITLE:" . $this->types["TITLE"]) . "\n";
551  }
552  else
553  {
554  $title = "";
555  }
556  break;
557  case "ROLE":
558  if (strcmp($this->types["ROLE"], "") != 0)
559  {
560  $role = $this->fold("ROLE:" . $this->types["ROLE"]) . "\n";
561  }
562  else
563  {
564  $role = "";
565  }
566  break;
567  case "LOGO":
568  if (strcmp($this->types["LOGO"]["VALUE"], "") != 0)
569  {
570  $logo = $this->fold("LOGO;VALUE=uri:" . $this->types["LOGO"]["VALUE"]) . "\n";
571  }
572  elseif (strcmp($this->types["LOGO"]["ENCODING"], "") != 0)
573  {
574  $logo = "LOGO;ENCODING=" . $this->types["LOGO"]["ENCODING"];
575  if (strcmp($this->types["LOGO"]["TYPE"], "") != 0)
576  {
577  $logo .= ";TYPE=" . $this->types["LOGO"]["TYPE"];
578  }
579  $logo .= ":" . $this->types["LOGO"]["LOGO"];
580  $logo = $this->fold($logo) . "\n";
581  }
582  else
583  {
584  $logo = "";
585  }
586  break;
587  case "AGENT":
588  if (strcmp($this->types["AGENT"], "") != 0)
589  {
590  $agent = $this->fold("AGENT:" . $this->types["AGENT"]) . "\n";
591  }
592  else
593  {
594  $agent = "";
595  }
596  break;
597  case "ORG":
598  if (strcmp($this->types["ORG"], "") != 0)
599  {
600  $org = $this->fold("ORG:" . $this->types["ORG"]) . "\n";
601  }
602  else
603  {
604  $org = "";
605  }
606  break;
607  case "CATEGORIES":
608  if (strcmp($this->types["CATEGORIES"], "") != 0)
609  {
610  $categories = $this->fold("CATEGORIES:" . $this->types["CATEGORIES"]) . "\n";
611  }
612  else
613  {
614  $categories = "";
615  }
616  break;
617  case "NOTE":
618  if (strcmp($this->types["NOTE"], "") != 0)
619  {
620  $note = $this->fold("NOTE:" . $this->types["NOTE"]) . "\n";
621  }
622  else
623  {
624  $note = "";
625  }
626  break;
627  case "PRODID":
628  if (strcmp($this->types["PRODID"], "") != 0)
629  {
630  $prodid = $this->fold("PRODID:" . $this->types["PRODID"]) . "\n";
631  }
632  else
633  {
634  $prodid = "";
635  }
636  break;
637  case "REV":
638  if (strcmp($this->types["REV"], "") != 0)
639  {
640  $rev = $this->fold("REV:" . $this->types["REV"]) . "\n";
641  }
642  else
643  {
644  $rev = "";
645  }
646  break;
647  case "SORT-STRING":
648  if (strcmp($this->types["SORT-STRING"], "") != 0)
649  {
650  $sortstring = $this->fold("SORT-STRING:" . $this->types["SORT-STRING"]) . "\n";
651  }
652  else
653  {
654  $sortstring = "";
655  }
656  break;
657  case "SOUND":
658  if (strcmp($this->types["SOUND"]["VALUE"], "") != 0)
659  {
660  $sound = $this->fold("SOUND;VALUE=uri:" . $this->types["SOUND"]["VALUE"]) . "\n";
661  }
662  elseif (strcmp($this->types["SOUND"]["ENCODING"], "") != 0)
663  {
664  $sound = "SOUND;ENCODING=" . $this->types["SOUND"]["ENCODING"];
665  if (strcmp($this->types["SOUND"]["TYPE"], "") != 0)
666  {
667  $sound .= ";TYPE=" . $this->types["SOUND"]["TYPE"];
668  }
669  $sound .= ":" . $this->types["SOUND"]["SOUND"];
670  $sound = $this->fold($sound) . "\n";
671  }
672  else
673  {
674  $sound = "";
675  }
676  break;
677  case "UID":
678  if (strcmp($this->types["UID"]["UID"], "") != 0)
679  {
680  $uid = "UID";
681  if (strcmp($this->types["UID"]["TYPE"], "") != 0)
682  {
683  $uid .= ";TYPE=" . $this->types["UID"]["TYPE"];
684  }
685  $uid .= ":" . $this->types["UID"]["UID"];
686  $uid = $this->fold($uid) . "\n";
687  }
688  else
689  {
690  $uid = "";
691  }
692  break;
693  case "URL":
694  if (strcmp($this->types["URL"], "") != 0)
695  {
696  $url = $this->fold("URL:" . $this->types["URL"]) . "\n";
697  }
698  else
699  {
700  $url = "";
701  }
702  break;
703  case "KEY":
704  if (strcmp($this->types["KEY"]["KEY"], "") != 0)
705  {
706  $key = "KEY";
707  if (strcmp($this->types["KEY"]["TYPE"], "") != 0)
708  {
709  $key .= ";TYPE=" . $this->types["KEY"]["TYPE"];
710  }
711  if (strcmp($this->types["KEY"]["ENCODING"], "") != 0)
712  {
713  $key .= ";ENCODING=" . $this->types["KEY"]["ENCODING"];
714  }
715  $key .= ":" . $this->types["KEY"]["KEY"];
716  $key = $this->fold($key) . "\n";
717  }
718  else
719  {
720  $key = "";
721  }
722  break;
723  case "CLASS":
724  if (strcmp($this->types["CLASS"], "") != 0)
725  {
726  $class = $this->fold("CLASS:" . $this->types["CLASS"]) . "\n";
727  }
728  else
729  {
730  $class = "";
731  }
732  break;
733  }
734  }
735  $vcard .= $fn.$n.$nickname.$photo.$bday.$adr.$label.$tel.$email.$mailer.
736  $tz.$geo.$title.$role.$logo.$agent.$org.$categories.$note.$prodid.
737  $rev.$sortstring.$sound.$uid.$url.$class.$key;
738  $vcard .= "END:vCard\n";
739  return $vcard;
740  }
741 
753  function quoted_printable_encode($input, $line_max = 76) {
754  $hex = array('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F');
755  $lines = preg_split("/(?:\r\n|\r|\n)/", $input);
756  $eol = "\r\n";
757  $linebreak = "=0D=0A";
758  $escape = "=";
759  $output = "";
760 
761  for ($j=0;$j<count($lines);$j++) {
762  $line = $lines[$j];
763  $linlen = strlen($line);
764  $newline = "";
765  for($i = 0; $i < $linlen; $i++) {
766  $c = substr($line, $i, 1);
767  $dec = ord($c);
768  if ( ($dec == 32) && ($i == ($linlen - 1)) ) { // convert space at eol only
769  $c = "=20";
770  } elseif ( ($dec == 61) || ($dec < 32 ) || ($dec > 126) ) { // always encode "\t", which is *not* required
771  $h2 = floor($dec/16); $h1 = floor($dec%16);
772  $c = $escape.$hex["$h2"].$hex["$h1"];
773  }
774  if ( (strlen($newline) + strlen($c)) >= $line_max ) { // CRLF is not counted
775  $output .= $newline.$escape.$eol; // soft line break; " =\r\n" is okay
776  $newline = " ";
777  }
778  $newline .= $c;
779  } // end of for
780  $output .= $newline;
781  if ($j<count($lines)-1) $output .= $linebreak;
782  }
783  return trim($output);
784  }
785 
786 // Identification Types
787 //
788 // These types are used in the vCard profile to capture information
789 // associated with the identification and naming of the person or
790 // resource associated with the vCard.
791 
806  function setFormattedName($formatted_name)
807  {
808  $this->types["FN"] = $this->escape($formatted_name);
809  }
810 
840  function setName($family_name, $given_name = "", $additional_names = "", $honorific_prefixes = "", $honorific_suffixes = "")
841  {
842  $familynames =& $this->explodeVar($family_name);
843  $givennames =& $this->explodeVar($given_name);
844  $addnames =& $this->explodeVar($additional_names);
845  $prefixes =& $this->explodeVar($honorific_prefixes);
846  $suffixes =& $this->explodeVar($honorific_suffixes);
847 
848  $this->types["N"] =
849  join(",", $familynames) .
850  ";" .
851  join(",", $givennames) .
852  ";" .
853  join(",", $addnames) .
854  ";" .
855  join(",", $prefixes) .
856  ";" .
857  join(",", $suffixes);
858 
859  $this->filename = "$given_name" . "_" . "$family_name" . ".vcf";
860  if (strcmp($this->types["FN"], "") == 0)
861  {
862  $fn = trim("$honorific_prefixes $given_name $additional_names $family_name $honorific_suffixes");
863  $fn = preg_replace("/\s{2,10}/", " ", $fn);
864  $this->setFormattedName($fn);
865  }
866  }
867 
888  function setNickname($nickname)
889  {
890  $nicknames =& $this->explodeVar($nickname);
891  $this->types["NICKNAME"] = join(",", $nicknames);
892  }
893 
929  function setPhoto($photo, $type = "")
930  {
931  $value = "";
932  $encoding = "";
933  if (preg_match("/^http/", $photo))
934  {
935  $value = $this->encode($photo);
936  }
937  else
938  {
939  $encoding = "b";
940  $photo = base64_encode($photo);
941  }
942  $this->types["PHOTO"] = array(
943  "VALUE" => $value,
944  "TYPE" => $type,
945  "ENCODING" => $encoding,
946  "PHOTO" => $photo
947  );
948  }
949 
970  function setBirthday($year, $month, $day)
971  {
972  if (($year < 1) or ($day < 1) or ($month < 1))
973  {
974  $this->types["BDAY"] = "";
975  }
976  else
977  {
978  $this->types["BDAY"] = sprintf("%04d-%02d-%02d", $year, $month, $day);
979  }
980  }
981 
982 // Delivery Addressing Types
983 //
984 // These types are concerned with information related to the delivery
985 // addressing or label for the vCard object.
986 
1041  function setAddress(
1042  $po_box = "",
1043  $extended_address = "",
1044  $street_address = "",
1045  $locality = "",
1046  $region = "",
1047  $postal_code = "",
1048  $country = "",
1049  $type = ADR_TYPE_NONE
1050  )
1051  {
1052  if ($type == ADR_TYPE_NONE)
1053  {
1055  }
1056  $po_box = join(",", $this->explodeVar($po_box));
1057  $extended_address = join(",", $this->explodeVar($extended_address));
1058  $street_address = join(",", $this->explodeVar($street_address));
1059  $locality = join(",", $this->explodeVar($locality));
1060  $region = join(",", $this->explodeVar($region));
1061  $postal_code = join(",", $this->explodeVar($postal_code));
1062  $country = join(",", $this->explodeVar($country));
1063  array_push($this->types["ADR"], array(
1064  "POBOX" => $po_box,
1065  "EXTENDED_ADDRESS" => $extended_address,
1066  "STREET_ADDRESS" => $street_address,
1067  "LOCALITY" => $locality,
1068  "REGION" => $region,
1069  "POSTAL_CODE" => $postal_code,
1070  "COUNTRY" => $country,
1071  "TYPE" => $type
1072  ));
1073  }
1074 
1111  function setLabel($label = "", $type = ADR_TYPE_NONE)
1112  {
1113  if ($type == ADR_TYPE_NONE)
1114  {
1116  }
1117  $this->types["LABEL"] = array(
1118  "LABEL" => $this->escape($label),
1119  "TYPE" => $type
1120  );
1121  }
1122 
1123 // Telecommunications Addressing Types
1124 //
1125 // These types are concerned with information associated with the
1126 // telecommunications addressing of the object the vCard represents.
1127 
1170  function setPhone($number = "", $type = TEL_TYPE_VOICE)
1171  {
1172  array_push($this->types["TEL"], array(
1173  "TEL" => $this->escape($number),
1174  "TYPE" => $type
1175  ));
1176  }
1177 
1204  function setEmail($address = "", $type = EMAIL_TYPE_INTERNET)
1205  {
1206  array_push($this->types["EMAIL"], array(
1207  "EMAIL" => $this->escape($address),
1208  "TYPE" => $type
1209  ));
1210  }
1211 
1232  function setMailer($name = "")
1233  {
1234  $this->types["MAILER"] = $this->escape($name);
1235  }
1236 
1237 // Geographical Types
1238 //
1239 // These types are concerned with information associated with
1240 // geographical positions or regions associated with the object the
1241 // vCard represents.
1242 
1260  function setTimezone($zone = "")
1261  {
1262  $this->types["TZ"] = $this->escape($zone);
1263  }
1264 
1299  function setPosition($latitude = "", $longitude = "")
1300  {
1301  $this->types["GEO"] = array(
1302  "LAT" => $latitude,
1303  "LON" => $longitude
1304  );
1305  }
1306 
1307 // Organizational Types
1308 //
1309 // These types are concerned with information associated with
1310 // characteristics of the organization or organizational units of the
1311 // object the vCard represents.
1312 
1329  function setTitle($title = "")
1330  {
1331  $this->types["TITLE"] = $this->escape($title);
1332  }
1333 
1354  function setRole($role = "")
1355  {
1356  $this->types["ROLE"] = $this->escape($role);
1357  }
1358 
1392  function setLogo($logo, $type = "")
1393  {
1394  $value = "";
1395  $encoding = "";
1396  if (preg_match("/^http/", $logo))
1397  {
1398  $value = $this->encode($logo);
1399  }
1400  else
1401  {
1402  $encoding = "b";
1403  $logo = base64_encode($logo);
1404  }
1405  $this->types["LOGO"] = array(
1406  "VALUE" => $value,
1407  "TYPE" => $type,
1408  "ENCODING" => $encoding,
1409  "LOGO" => $logo
1410  );
1411  }
1412 
1440  function setAgent($agent = "")
1441  {
1442  $this->types["AGENT"] = $this->escape($agent);
1443  }
1444 
1466  function setOrganization($organization = "")
1467  {
1468  $organization = join(";", $this->explodeVar($organization, ";"));
1469  $this->types["ORG"] = $organization;
1470  }
1471 
1472 // Explanatory Types
1473 //
1474 // These types are concerned with additional explanations, such as that
1475 // related to informational notes or revisions specific to the vCard.
1476 
1494  function setCategories($categories)
1495  {
1496  $categories = join(",", $this->explodeVar($categories));
1497  $this->types["CATEGORIES"] = $categories;
1498  }
1499 
1519  function setNote($note = "")
1520  {
1521  $this->types["NOTE"] = $this->escape($note);
1522  }
1523 
1543  function setProductId($product_id = "")
1544  {
1545  $this->types["PRODID"] = $this->escape($product_id);
1546  }
1547 
1569  function setRevision($revision_date = "")
1570  {
1571  $this->types["REV"] = $this->escape($revision_date);
1572  }
1573 
1617  function setSortString($string = "")
1618  {
1619  $this->types["SORT-STRING"] = $this->escape($string);
1620  }
1621 
1657  function setSound($sound = "", $type = "")
1658  {
1659  $value = "";
1660  $encoding = "";
1661  if (preg_match("/^http/", $sound))
1662  {
1663  $value = $this->encode($sound);
1664  }
1665  else
1666  {
1667  $encoding = "b";
1668  $sound = base64_encode($sound);
1669  }
1670  $this->types["SOUND"] = array(
1671  "VALUE" => $value,
1672  "TYPE" => $type,
1673  "ENCODING" => $encoding,
1674  "SOUND" => $sound
1675  );
1676  }
1677 
1704  function setUID($uid = "", $type = "")
1705  {
1706  $this->types["UID"] = array(
1707  "UID" => $this->escape($uid),
1708  "TYPE" => $type
1709  );
1710  }
1711 
1728  function setURL($uri = "")
1729  {
1730  $this->types["URL"] = $this->escape($uri);
1731  }
1732 
1749  function setVersion($version = "3.0")
1750  {
1751  $this->types["VERSION"] = $version;
1752  }
1753 
1754 // Security Types
1755 //
1756 // These types are concerned with the security of communication pathways
1757 // or access to the vCard.
1758 
1782  function setClassification($classification = "")
1783  {
1784  $this->types["CLASS"] = $this->escape($classification);
1785  }
1786 
1831  function setKey($key = "", $type = "")
1832  {
1833  $encoding = "b";
1834  $key = base64_encode($key);
1835  $this->types["KEY"] = array(
1836  "KEY" => $key,
1837  "TYPE" => $type,
1838  "ENCODING" => $encoding
1839  );
1840  }
1841 
1842  function getFilename()
1843  {
1844  if (strcmp($this->filename, "") == 0)
1845  {
1846  return "vcard.vcf";
1847  }
1848  else
1849  {
1850  return $this->filename;
1851  }
1852  }
1853 
1854  function getMimetype()
1855  {
1856  return "text/x-vcard";
1857  }
1858 }
1859 
1860 ?>