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";
262 if (is_array($this->types[
"PHOTO"]))
264 if (strcmp($this->types[
"PHOTO"][
"VALUE"],
"") != 0)
266 $photo = $this->
fold(
"PHOTO;VALUE=uri:" . $this->types[
"PHOTO"][
"VALUE"]) .
"\n";
268 elseif (strcmp($this->types[
"PHOTO"][
"ENCODING"],
"") != 0)
270 $photo =
"PHOTO;ENCODING=" . $this->types[
"PHOTO"][
"ENCODING"];
271 if (strcmp($this->types[
"PHOTO"][
"TYPE"],
"") != 0)
273 $photo .=
";TYPE=" . $this->types[
"PHOTO"][
"TYPE"];
275 $photo .=
":" . $this->types[
"PHOTO"][
"PHOTO"];
276 $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";
354 if (is_array($this->types[
"LABEL"]))
356 if (strcmp($this->types[
"LABEL"][
"LABEL"],
"") != 0)
359 $adr_types = array();
360 if ($this->types[
"LABEL"][
"TYPE"] > 0)
364 array_push($adr_types,
"dom");
368 array_push($adr_types,
"intl");
372 array_push($adr_types,
"postal");
376 array_push($adr_types,
"parcel");
380 array_push($adr_types,
"home");
384 array_push($adr_types,
"work");
388 array_push($adr_types,
"pref");
390 $label .=
";TYPE=" . join(
",", $adr_types);
392 $label .=
":" . $this->types[
"LABEL"][
"LABEL"];
393 $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 (is_array($this->types[
"GEO"]) and
539 (strcmp($this->types[
"GEO"][
"LAT"],
"") != 0) and
540 (strcmp($this->types[
"GEO"][
"LON"],
"") != 0))
542 $geo = $this->
fold(
"GEO:" . $this->types[
"GEO"][
"LAT"] .
";" . $this->types[
"GEO"][
"LON"]) .
"\n";
550 if (strcmp($this->types[
"TITLE"],
"") != 0)
552 $title = $this->
fold(
"TITLE:" . $this->types[
"TITLE"]) .
"\n";
560 if (strcmp($this->types[
"ROLE"],
"") != 0)
562 $role = $this->
fold(
"ROLE:" . $this->types[
"ROLE"]) .
"\n";
571 if (is_array($this->types[
"LOGO"]))
573 if (strcmp($this->types[
"LOGO"][
"VALUE"],
"") != 0)
575 $logo = $this->
fold(
"LOGO;VALUE=uri:" . $this->types[
"LOGO"][
"VALUE"]) .
"\n";
577 elseif (strcmp($this->types[
"LOGO"][
"ENCODING"],
"") != 0)
579 $logo =
"LOGO;ENCODING=" . $this->types[
"LOGO"][
"ENCODING"];
580 if (strcmp($this->types[
"LOGO"][
"TYPE"],
"") != 0)
582 $logo .=
";TYPE=" . $this->types[
"LOGO"][
"TYPE"];
584 $logo .=
":" . $this->types[
"LOGO"][
"LOGO"];
585 $logo = $this->
fold($logo) .
"\n";
590 if (strcmp($this->types[
"AGENT"],
"") != 0)
592 $agent = $this->
fold(
"AGENT:" . $this->types[
"AGENT"]) .
"\n";
600 if (strcmp($this->types[
"ORG"],
"") != 0)
602 $org = $this->
fold(
"ORG:" . $this->types[
"ORG"]) .
"\n";
610 if (strcmp($this->types[
"CATEGORIES"],
"") != 0)
612 $categories = $this->
fold(
"CATEGORIES:" . $this->types[
"CATEGORIES"]) .
"\n";
620 if (strcmp($this->types[
"NOTE"],
"") != 0)
622 $note = $this->
fold(
"NOTE:" . $this->types[
"NOTE"]) .
"\n";
630 if (strcmp($this->types[
"PRODID"],
"") != 0)
632 $prodid = $this->
fold(
"PRODID:" . $this->types[
"PRODID"]) .
"\n";
640 if (strcmp($this->types[
"REV"],
"") != 0)
642 $rev = $this->
fold(
"REV:" . $this->types[
"REV"]) .
"\n";
650 if (strcmp($this->types[
"SORT-STRING"],
"") != 0)
652 $sortstring = $this->
fold(
"SORT-STRING:" . $this->types[
"SORT-STRING"]) .
"\n";
661 if (is_array($this->types[
"SOUND"]))
663 if (strcmp($this->types[
"SOUND"][
"VALUE"],
"") != 0)
665 $sound = $this->
fold(
"SOUND;VALUE=uri:" . $this->types[
"SOUND"][
"VALUE"]) .
"\n";
667 elseif (strcmp($this->types[
"SOUND"][
"ENCODING"],
"") != 0)
669 $sound =
"SOUND;ENCODING=" . $this->types[
"SOUND"][
"ENCODING"];
670 if (strcmp($this->types[
"SOUND"][
"TYPE"],
"") != 0)
672 $sound .=
";TYPE=" . $this->types[
"SOUND"][
"TYPE"];
674 $sound .=
":" . $this->types[
"SOUND"][
"SOUND"];
675 $sound = $this->
fold($sound) .
"\n";
681 if (is_array($this->types[
"UID"]))
683 if (strcmp($this->types[
"UID"][
"UID"],
"") != 0)
686 if (strcmp($this->types[
"UID"][
"TYPE"],
"") != 0)
688 $uid .=
";TYPE=" . $this->types[
"UID"][
"TYPE"];
690 $uid .=
":" . $this->types[
"UID"][
"UID"];
691 $uid = $this->
fold($uid) .
"\n";
696 if (strcmp($this->types[
"URL"],
"") != 0)
698 $url = $this->
fold(
"URL:" . $this->types[
"URL"]) .
"\n";
707 if (is_array($this->types[
"KEY"]))
709 if (strcmp($this->types[
"KEY"][
"KEY"],
"") != 0)
712 if (strcmp($this->types[
"KEY"][
"TYPE"],
"") != 0)
714 $key .=
";TYPE=" . $this->types[
"KEY"][
"TYPE"];
716 if (strcmp($this->types[
"KEY"][
"ENCODING"],
"") != 0)
718 $key .=
";ENCODING=" . $this->types[
"KEY"][
"ENCODING"];
720 $key .=
":" . $this->types[
"KEY"][
"KEY"];
721 $key = $this->
fold($key) .
"\n";
726 if (strcmp($this->types[
"CLASS"],
"") != 0)
728 $class = $this->
fold(
"CLASS:" . $this->types[
"CLASS"]) .
"\n";
737 $vcard .= $fn.$n.$nickname.$photo.$bday.$adr.$label.$tel.$email.$mailer.
738 $tz.$geo.$title.$role.$logo.$agent.$org.$categories.$note.$prodid.
739 $rev.$sortstring.$sound.$uid.$url.$class.$key;
740 $vcard .=
"END:vCard\n";
756 $hex = array(
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'A',
'B',
'C',
'D',
'E',
'F');
757 $lines = preg_split(
"/(?:\r\n|\r|\n)/", $input);
759 $linebreak =
"=0D=0A";
763 for ($j=0;$j<count($lines);$j++) {
765 $linlen = strlen($line);
767 for($i = 0; $i < $linlen; $i++) {
768 $c = substr($line, $i, 1);
770 if ( ($dec == 32) && ($i == ($linlen - 1)) ) {
772 } elseif ( ($dec == 61) || ($dec < 32 ) || ($dec > 126) ) {
773 $h2 = floor($dec/16); $h1 = floor($dec%16);
774 $c = $escape.$hex[
"$h2"].$hex[
"$h1"];
776 if ( (strlen($newline) + strlen($c)) >= $line_max ) {
777 $output .= $newline.$escape.$eol;
783 if ($j<count($lines)-1) $output .= $linebreak;
785 return trim($output);
810 $this->types[
"FN"] = $this->
escape($formatted_name);
842 function setName($family_name, $given_name =
"", $additional_names =
"", $honorific_prefixes =
"", $honorific_suffixes =
"")
844 $familynames =& $this->
explodeVar($family_name);
845 $givennames =& $this->
explodeVar($given_name);
846 $addnames =& $this->
explodeVar($additional_names);
847 $prefixes =& $this->
explodeVar($honorific_prefixes);
848 $suffixes =& $this->
explodeVar($honorific_suffixes);
851 join(
",", $familynames) .
853 join(
",", $givennames) .
855 join(
",", $addnames) .
857 join(
",", $prefixes) .
859 join(
",", $suffixes);
861 $this->filename =
"$given_name" .
"_" .
"$family_name" .
".vcf";
862 if (strcmp($this->types[
"FN"],
"") == 0)
864 $fn = trim(
"$honorific_prefixes $given_name $additional_names $family_name $honorific_suffixes");
865 $fn = preg_replace(
"/\s{2,10}/",
" ", $fn);
893 $this->types[
"NICKNAME"] = join(
",", $nicknames);
935 if (preg_match(
"/^http/", $photo))
937 $value = $this->
encode($photo);
942 $photo = base64_encode($photo);
944 $this->types[
"PHOTO"] = array(
947 "ENCODING" => $encoding,
974 if (($year < 1) or ($day < 1) or ($month < 1))
976 $this->types[
"BDAY"] =
"";
980 $this->types[
"BDAY"] = sprintf(
"%04d-%02d-%02d", $year, $month, $day);
1045 $extended_address =
"",
1046 $street_address =
"",
1058 $po_box = join(
",", $this->
explodeVar($po_box));
1059 $extended_address = join(
",", $this->
explodeVar($extended_address));
1060 $street_address = join(
",", $this->
explodeVar($street_address));
1061 $locality = join(
",", $this->
explodeVar($locality));
1062 $region = join(
",", $this->
explodeVar($region));
1063 $postal_code = join(
",", $this->
explodeVar($postal_code));
1064 $country = join(
",", $this->
explodeVar($country));
1065 array_push($this->types[
"ADR"], array(
1067 "EXTENDED_ADDRESS" => $extended_address,
1068 "STREET_ADDRESS" => $street_address,
1069 "LOCALITY" => $locality,
1070 "REGION" => $region,
1071 "POSTAL_CODE" => $postal_code,
1072 "COUNTRY" => $country,
1119 $this->types[
"LABEL"] = array(
1120 "LABEL" => $this->
escape($label),
1174 array_push($this->types[
"TEL"], array(
1175 "TEL" => $this->
escape($number),
1208 array_push($this->types[
"EMAIL"], array(
1209 "EMAIL" => $this->
escape($address),
1236 $this->types[
"MAILER"] = $this->
escape($name);
1264 $this->types[
"TZ"] = $this->
escape($zone);
1303 $this->types[
"GEO"] = array(
1333 $this->types[
"TITLE"] = $this->
escape($title);
1358 $this->types[
"ROLE"] = $this->
escape($role);
1398 if (preg_match(
"/^http/", $logo))
1400 $value = $this->
encode($logo);
1405 $logo = base64_encode($logo);
1407 $this->types[
"LOGO"] = array(
1410 "ENCODING" => $encoding,
1444 $this->types[
"AGENT"] = $this->
escape($agent);
1470 $organization = join(
";", $this->
explodeVar($organization,
";"));
1471 $this->types[
"ORG"] = $organization;
1498 $categories = join(
",", $this->
explodeVar($categories));
1499 $this->types[
"CATEGORIES"] = $categories;
1523 $this->types[
"NOTE"] = $this->
escape($note);
1547 $this->types[
"PRODID"] = $this->
escape($product_id);
1573 $this->types[
"REV"] = $this->
escape($revision_date);
1621 $this->types[
"SORT-STRING"] = $this->
escape($string);
1663 if (preg_match(
"/^http/", $sound))
1665 $value = $this->
encode($sound);
1670 $sound = base64_encode($sound);
1672 $this->types[
"SOUND"] = array(
1675 "ENCODING" => $encoding,
1708 $this->types[
"UID"] = array(
1709 "UID" => $this->
escape($uid),
1732 $this->types[
"URL"] = $this->
escape($uri);
1753 $this->types[
"VERSION"] = $version;
1786 $this->types[
"CLASS"] = $this->
escape($classification);
1836 $key = base64_encode($key);
1837 $this->types[
"KEY"] = array(
1840 "ENCODING" => $encoding
1846 if (strcmp($this->filename,
"") == 0)
1858 return "text/x-vcard";