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);
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);
72 define (
"EMAIL_TYPE_NONE", 0);
73 define (
"EMAIL_TYPE_INTERNET", 1);
74 define (
"EMAIL_TYPE_x400", 2);
75 define (
"EMAIL_TYPE_PREF", 4);
100 $this->types = array(
130 $this->types[
"VERSION"] = $version;
157 function fold($string =
"", $length = 75)
160 preg_match_all(
"/(.{1,74})/", $string, $matches);
161 for ($i = 0; $i < count($matches[1]); $i++)
163 if ($i < (count($matches[1])-1))
165 $matches[1][$i] .=
"\n";
169 $matches[1][$i] =
" " . $matches[1][$i];
171 $folded_string .= $matches[1][$i];
173 return $folded_string;
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);
207 foreach ($exploded as $index => $var)
209 $exploded[$index] = $this->
escape($var);
224 $vcard =
"BEGIN:VCARD\n";
225 $vcard .=
"VERSION:" . $this->types[
"VERSION"] .
"\n";
226 foreach ($this->types as
$type => $var)
231 if (strcmp($this->types[
"FN"],
"") != 0)
233 $fn = $this->
fold(
"FN:" . $this->types[
"FN"]) .
"\n";
241 if (strcmp($this->types[
"N"],
"") != 0)
243 $n = $this->
fold(
"N:" . $this->types[
"N"]) .
"\n";
251 if (strcmp($this->types[
"NICKNAME"],
"") != 0)
253 $nickname = $this->
fold(
"NICKNAME:" . $this->types[
"NICKNAME"]) .
"\n";
261 if (strcmp($this->types[
"PHOTO"][
"VALUE"],
"") != 0)
263 $photo = $this->
fold(
"PHOTO;VALUE=uri:" . $this->types[
"PHOTO"][
"VALUE"]) .
"\n";
265 elseif (strcmp($this->types[
"PHOTO"][
"ENCODING"],
"") != 0)
267 $photo =
"PHOTO;ENCODING=" . $this->types[
"PHOTO"][
"ENCODING"];
268 if (strcmp($this->types[
"PHOTO"][
"TYPE"],
"") != 0)
270 $photo .=
";TYPE=" . $this->types[
"PHOTO"][
"TYPE"];
272 $photo .=
":" . $this->types[
"PHOTO"][
"PHOTO"];
273 $photo = $this->
fold($photo) .
"\n";
281 if (strcmp($this->types[
"BDAY"],
"") != 0)
283 $bday = $this->
fold(
"BDAY:" . $this->types[
"BDAY"]) .
"\n";
291 if (count($this->types[
"ADR"]))
294 foreach ($this->types[
"ADR"] as $key => $address)
297 foreach ($address as $str)
301 if (strcmp(
$test,
"") != 0)
304 $adr_types = array();
305 if ($address[
"TYPE"] > 0)
309 array_push($adr_types,
"dom");
313 array_push($adr_types,
"intl");
317 array_push($adr_types,
"postal");
321 array_push($adr_types,
"parcel");
325 array_push($adr_types,
"home");
329 array_push($adr_types,
"work");
333 array_push($adr_types,
"pref");
335 $adr .=
";TYPE=" . join(
",", $adr_types);
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";
353 if (strcmp($this->types[
"LABEL"][
"LABEL"],
"") != 0)
356 $adr_types = array();
357 if ($this->types[
"LABEL"][
"TYPE"] > 0)
361 array_push($adr_types,
"dom");
365 array_push($adr_types,
"intl");
369 array_push($adr_types,
"postal");
373 array_push($adr_types,
"parcel");
377 array_push($adr_types,
"home");
381 array_push($adr_types,
"work");
385 array_push($adr_types,
"pref");
387 $label .=
";TYPE=" . join(
",", $adr_types);
389 $label .=
":" . $this->types[
"LABEL"][
"LABEL"];
390 $label = $this->
fold($label) .
"\n";
398 if (count($this->types[
"TEL"]))
401 foreach ($this->types[
"TEL"] as $key => $phone)
403 if (strcmp($phone[
"TEL"],
"") != 0)
406 $tel_types = array();
407 if ($phone[
"TYPE"] > 0)
411 array_push($tel_types,
"home");
415 array_push($tel_types,
"msg");
419 array_push($tel_types,
"work");
423 array_push($tel_types,
"pref");
427 array_push($tel_types,
"voice");
431 array_push($tel_types,
"fax");
435 array_push($tel_types,
"cell");
439 array_push($tel_types,
"video");
443 array_push($tel_types,
"pager");
447 array_push($tel_types,
"bbs");
451 array_push($tel_types,
"modem");
455 array_push($tel_types,
"car");
459 array_push($tel_types,
"isdn");
463 array_push($tel_types,
"pcs");
465 $tel .=
";TYPE=" . join(
",", $tel_types);
467 $tel .=
":" . $phone[
"TEL"];
468 $tel = $this->
fold($tel) .
"\n";
469 $phonenumbers .= $tel;
472 $tel = $phonenumbers;
480 if (count($this->types[
"EMAIL"]))
483 foreach ($this->types[
"EMAIL"] as $key => $mail)
485 if (strcmp($mail[
"EMAIL"],
"") != 0)
488 $adr_types = array();
489 if ($mail[
"TYPE"] > 0)
493 array_push($adr_types,
"internet");
497 array_push($adr_types,
"x400");
501 array_push($adr_types,
"pref");
503 $email .=
";TYPE=" . join(
",", $adr_types);
505 $email .=
":" . $mail[
"EMAIL"];
506 $email = $this->
fold($email) .
"\n";
518 if (strcmp($this->types[
"MAILER"],
"") != 0)
520 $mailer = $this->
fold(
"MAILER:" . $this->types[
"MAILER"]) .
"\n";
528 if (strcmp($this->types[
"TZ"],
"") != 0)
530 $tz = $this->
fold(
"TZ:" . $this->types[
"TZ"]) .
"\n";
538 if ((strcmp($this->types[
"GEO"][
"LAT"],
"") != 0) and (strcmp($this->types[
"GEO"][
"LON"],
"") != 0))
540 $geo = $this->
fold(
"GEO:" . $this->types[
"GEO"][
"LAT"] .
";" . $this->types[
"GEO"][
"LON"]) .
"\n";
548 if (strcmp($this->types[
"TITLE"],
"") != 0)
550 $title = $this->
fold(
"TITLE:" . $this->types[
"TITLE"]) .
"\n";
558 if (strcmp($this->types[
"ROLE"],
"") != 0)
560 $role = $this->
fold(
"ROLE:" . $this->types[
"ROLE"]) .
"\n";
568 if (strcmp($this->types[
"LOGO"][
"VALUE"],
"") != 0)
570 $logo = $this->
fold(
"LOGO;VALUE=uri:" . $this->types[
"LOGO"][
"VALUE"]) .
"\n";
572 elseif (strcmp($this->types[
"LOGO"][
"ENCODING"],
"") != 0)
574 $logo =
"LOGO;ENCODING=" . $this->types[
"LOGO"][
"ENCODING"];
575 if (strcmp($this->types[
"LOGO"][
"TYPE"],
"") != 0)
577 $logo .=
";TYPE=" . $this->types[
"LOGO"][
"TYPE"];
579 $logo .=
":" . $this->types[
"LOGO"][
"LOGO"];
580 $logo = $this->
fold($logo) .
"\n";
588 if (strcmp($this->types[
"AGENT"],
"") != 0)
590 $agent = $this->
fold(
"AGENT:" . $this->types[
"AGENT"]) .
"\n";
598 if (strcmp($this->types[
"ORG"],
"") != 0)
600 $org = $this->
fold(
"ORG:" . $this->types[
"ORG"]) .
"\n";
608 if (strcmp($this->types[
"CATEGORIES"],
"") != 0)
610 $categories = $this->
fold(
"CATEGORIES:" . $this->types[
"CATEGORIES"]) .
"\n";
618 if (strcmp($this->types[
"NOTE"],
"") != 0)
620 $note = $this->
fold(
"NOTE:" . $this->types[
"NOTE"]) .
"\n";
628 if (strcmp($this->types[
"PRODID"],
"") != 0)
630 $prodid = $this->
fold(
"PRODID:" . $this->types[
"PRODID"]) .
"\n";
638 if (strcmp($this->types[
"REV"],
"") != 0)
640 $rev = $this->
fold(
"REV:" . $this->types[
"REV"]) .
"\n";
648 if (strcmp($this->types[
"SORT-STRING"],
"") != 0)
650 $sortstring = $this->
fold(
"SORT-STRING:" . $this->types[
"SORT-STRING"]) .
"\n";
658 if (strcmp($this->types[
"SOUND"][
"VALUE"],
"") != 0)
660 $sound = $this->
fold(
"SOUND;VALUE=uri:" . $this->types[
"SOUND"][
"VALUE"]) .
"\n";
662 elseif (strcmp($this->types[
"SOUND"][
"ENCODING"],
"") != 0)
664 $sound =
"SOUND;ENCODING=" . $this->types[
"SOUND"][
"ENCODING"];
665 if (strcmp($this->types[
"SOUND"][
"TYPE"],
"") != 0)
667 $sound .=
";TYPE=" . $this->types[
"SOUND"][
"TYPE"];
669 $sound .=
":" . $this->types[
"SOUND"][
"SOUND"];
670 $sound = $this->
fold($sound) .
"\n";
678 if (strcmp($this->types[
"UID"][
"UID"],
"") != 0)
681 if (strcmp($this->types[
"UID"][
"TYPE"],
"") != 0)
683 $uid .=
";TYPE=" . $this->types[
"UID"][
"TYPE"];
685 $uid .=
":" . $this->types[
"UID"][
"UID"];
686 $uid = $this->
fold($uid) .
"\n";
694 if (strcmp($this->types[
"URL"],
"") != 0)
696 $url = $this->
fold(
"URL:" . $this->types[
"URL"]) .
"\n";
704 if (strcmp($this->types[
"KEY"][
"KEY"],
"") != 0)
707 if (strcmp($this->types[
"KEY"][
"TYPE"],
"") != 0)
709 $key .=
";TYPE=" . $this->types[
"KEY"][
"TYPE"];
711 if (strcmp($this->types[
"KEY"][
"ENCODING"],
"") != 0)
713 $key .=
";ENCODING=" . $this->types[
"KEY"][
"ENCODING"];
715 $key .=
":" . $this->types[
"KEY"][
"KEY"];
716 $key = $this->
fold($key) .
"\n";
724 if (strcmp($this->types[
"CLASS"],
"") != 0)
726 $class = $this->
fold(
"CLASS:" . $this->types[
"CLASS"]) .
"\n";
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";
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);
757 $linebreak =
"=0D=0A";
761 for ($j=0;$j<count($lines);$j++) {
763 $linlen = strlen($line);
765 for($i = 0; $i < $linlen; $i++) {
766 $c = substr($line, $i, 1);
768 if ( ($dec == 32) && ($i == ($linlen - 1)) ) {
770 } elseif ( ($dec == 61) || ($dec < 32 ) || ($dec > 126) ) {
771 $h2 = floor($dec/16); $h1 = floor($dec%16);
772 $c = $escape.$hex[
"$h2"].$hex[
"$h1"];
774 if ( (strlen($newline) + strlen($c)) >= $line_max ) {
775 $output .= $newline.$escape.$eol;
781 if ($j<count($lines)-1) $output .= $linebreak;
783 return trim($output);
808 $this->types[
"FN"] = $this->
escape($formatted_name);
840 function setName($family_name, $given_name =
"", $additional_names =
"", $honorific_prefixes =
"", $honorific_suffixes =
"")
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);
849 join(
",", $familynames) .
851 join(
",", $givennames) .
853 join(
",", $addnames) .
855 join(
",", $prefixes) .
857 join(
",", $suffixes);
859 $this->filename =
"$given_name" .
"_" .
"$family_name" .
".vcf";
860 if (strcmp($this->types[
"FN"],
"") == 0)
862 $fn = trim(
"$honorific_prefixes $given_name $additional_names $family_name $honorific_suffixes");
863 $fn = preg_replace(
"/\s{2,10}/",
" ", $fn);
891 $this->types[
"NICKNAME"] = join(
",", $nicknames);
933 if (preg_match(
"/^http/", $photo))
935 $value = $this->
encode($photo);
940 $photo = base64_encode($photo);
942 $this->types[
"PHOTO"] = array(
945 "ENCODING" => $encoding,
972 if (($year < 1) or ($day < 1) or ($month < 1))
974 $this->types[
"BDAY"] =
"";
978 $this->types[
"BDAY"] = sprintf(
"%04d-%02d-%02d", $year, $month, $day);
1043 $extended_address =
"",
1044 $street_address =
"",
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(
1065 "EXTENDED_ADDRESS" => $extended_address,
1066 "STREET_ADDRESS" => $street_address,
1067 "LOCALITY" => $locality,
1068 "REGION" => $region,
1069 "POSTAL_CODE" => $postal_code,
1070 "COUNTRY" => $country,
1117 $this->types[
"LABEL"] = array(
1118 "LABEL" => $this->
escape($label),
1172 array_push($this->types[
"TEL"], array(
1173 "TEL" => $this->
escape($number),
1206 array_push($this->types[
"EMAIL"], array(
1207 "EMAIL" => $this->
escape($address),
1262 $this->types[
"TZ"] = $this->
escape($zone);
1301 $this->types[
"GEO"] = array(
1356 $this->types[
"ROLE"] = $this->
escape($role);
1396 if (preg_match(
"/^http/", $logo))
1398 $value = $this->
encode($logo);
1403 $logo = base64_encode($logo);
1405 $this->types[
"LOGO"] = array(
1408 "ENCODING" => $encoding,
1442 $this->types[
"AGENT"] = $this->
escape($agent);
1468 $organization = join(
";", $this->
explodeVar($organization,
";"));
1469 $this->types[
"ORG"] = $organization;
1496 $categories = join(
",", $this->
explodeVar($categories));
1497 $this->types[
"CATEGORIES"] = $categories;
1521 $this->types[
"NOTE"] = $this->
escape($note);
1545 $this->types[
"PRODID"] = $this->
escape($product_id);
1571 $this->types[
"REV"] = $this->
escape($revision_date);
1619 $this->types[
"SORT-STRING"] = $this->
escape($string);
1661 if (preg_match(
"/^http/", $sound))
1663 $value = $this->
encode($sound);
1668 $sound = base64_encode($sound);
1670 $this->types[
"SOUND"] = array(
1673 "ENCODING" => $encoding,
1706 $this->types[
"UID"] = array(
1707 "UID" => $this->
escape($uid),
1730 $this->types[
"URL"] = $this->
escape($uri);
1751 $this->types[
"VERSION"] = $version;
1784 $this->types[
"CLASS"] = $this->
escape($classification);
1834 $key = base64_encode($key);
1835 $this->types[
"KEY"] = array(
1838 "ENCODING" => $encoding
1844 if (strcmp($this->filename,
"") == 0)
1856 return "text/x-vcard";