ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
VCard.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
21namespace ILIAS\User\Profile;
22
27class VCard
28{
29 // Address values for the ADR type
30 public const ADR_TYPE_NONE = 0;
31 public const ADR_TYPE_DOM = 1;
32 public const ADR_TYPE_INTL = 2;
33 public const ADR_TYPE_POSTAL = 4;
34 public const ADR_TYPE_PARCEL = 8;
35 public const ADR_TYPE_HOME = 16;
36 public const ADR_TYPE_WORK = 32;
37 public const ADR_TYPE_PREF = 64;
38
39 // Communication values for the TEL type
40 public const TEL_TYPE_NONE = 0;
41 public const TEL_TYPE_HOME = 1;
42 public const TEL_TYPE_MSG = 2;
43 public const TEL_TYPE_WORK = 4;
44 public const TEL_TYPE_PREF = 8;
45 public const TEL_TYPE_VOICE = 16;
46 public const TEL_TYPE_FAX = 32;
47 public const TEL_TYPE_CELL = 64;
48 public const TEL_TYPE_VIDEO = 128;
49 public const TEL_TYPE_PAGER = 256;
50 public const TEL_TYPE_BBS = 512;
51 public const TEL_TYPE_MODEM = 1024;
52 public const TEL_TYPE_CAR = 2048;
53 public const TEL_TYPE_ISDN = 4096;
54 public const TEL_TYPE_PCS = 8192;
55
56 // Communication values for the EMAIL type
57 public const EMAIL_TYPE_NONE = 0;
58 public const EMAIL_TYPE_INTERNET = 1;
59 public const EMAIL_TYPE_x400 = 2;
60 public const EMAIL_TYPE_PREF = 4;
61
66 public array $types;
67
68 // The filename of the vCard used when saving the vCard
69 public string $filename;
70
71 public function __construct(string $version = '3.0')
72 {
73 $this->types = [
74 'FN' => '',
75 'N' => '',
76 'NICKNAME' => '',
77 'PHOTO' => [],
78 'BDAY' => '',
79 'ADR' => [],
80 'LABEL' => [],
81 'TEL' => [],
82 'EMAIL' => [],
83 'MAILER' => '',
84 'TZ' => '',
85 'GEO' => '',
86 'TITLE' => '',
87 'ROLE' => '',
88 'LOGO' => [],
89 'AGENT' => '',
90 'ORG' => '',
91 'CATEGORIES' => '',
92 'NOTE' => '',
93 'PRODID' => '',
94 'REV' => '',
95 'SORT-STRING' => '',
96 'SOUND' => [],
97 'UID' => '',
98 'URL' => '',
99 'CLASS' => '',
100 'KEY' => []
101 ];
102 $this->types['VERSION'] = $version;
103 }
104
108 public function encode(string $string): string
109 {
110 return $this->escape(quoted_printable_encode($string));
111 }
112
116 public function fold(string $string = ''): string
117 {
118 $folded_string = '';
119 preg_match_all('/(.{1,74})/', $string, $matches);
120 for ($i = 0, $iMax = count($matches[1]); $i < $iMax; $i++) {
121 if ($i < (count($matches[1]) - 1)) {
122 $matches[1][$i] .= "\n";
123 }
124 if ($i > 0) {
125 $matches[1][$i] = ' ' . $matches[1][$i];
126 }
127 $folded_string .= $matches[1][$i];
128 }
129 return $folded_string;
130 }
131
135 public function escape(string $string): string
136 {
137 $string = preg_replace('/(?<!\\\\)(\\\\)([^;,n\\\\])/', '\${1}\${1}\${2}', $string);
138 $string = preg_replace('/(?<!\\\\);/', '\\;', $string);
139 $string = preg_replace('/(?<!\\\\),/', '\\,', $string);
140 $string = preg_replace('/\n/', '\\n', $string);
141 return $string;
142 }
143
148 public function explodeVar(string $variable, string $separator = ','): array
149 {
150 $exploded = explode($separator, $variable);
151 foreach ($exploded as $index => $var) {
152 $exploded[$index] = $this->escape($var);
153 }
154 return $exploded;
155 }
156
160 public function buildVCard(): string
161 {
162 $fn = $n = $nickname = $photo = $bday = $adr = $label = $tel = $email = $mailer =
163 $tz = $geo = $title = $role = $logo = $agent = $org = $categories = $note = $prodid =
164 $rev = $sortstring = $sound = $uid = $url = $class = $key = 0;
165
166 $vcard = "BEGIN:VCARD\n";
167 $vcard .= 'VERSION:' . $this->types['VERSION'] . "\n";
168 foreach ($this->types as $type => $var) {
169 \ilLoggerFactory::getLogger('user')->debug(print_r($this->types, true));
170
171 switch ($type) {
172 case 'FN':
173 if (strcmp($this->types['FN'], '') != 0) {
174 $fn = $this->fold('FN:' . $this->types['FN']) . "\n";
175 } else {
176 $fn = '';
177 }
178 break;
179 case 'N':
180 if (strcmp($this->types['N'], '') != 0) {
181 $n = $this->fold('N:' . $this->types['N']) . "\n";
182 } else {
183 $n = '';
184 }
185 break;
186 case 'NICKNAME':
187 if (strcmp($this->types['NICKNAME'], '') != 0) {
188 $nickname = $this->fold('NICKNAME:' . $this->types['NICKNAME']) . "\n";
189 } else {
190 $nickname = '';
191 }
192 break;
193 case 'PHOTO':
194 $photo = '';
195 if (isset($this->types['PHOTO'])) {
196 if (strcmp(($this->types['PHOTO']['VALUE'] ?? ''), '') != 0) {
197 $photo = $this->fold('PHOTO;VALUE=uri:' . $this->types['PHOTO']['VALUE']) . "\n";
198 } elseif (strcmp(($this->types['PHOTO']['ENCODING'] ?? ''), '') != 0) {
199 $photo = 'PHOTO;ENCODING=' . $this->types['PHOTO']['ENCODING'];
200 if (strcmp($this->types['PHOTO']['TYPE'], '') != 0) {
201 $photo .= ';TYPE=' . $this->types['PHOTO']['TYPE'];
202 }
203 $photo .= ':' . $this->types['PHOTO']['PHOTO'];
204 $photo = $this->fold($photo) . "\n";
205 }
206 }
207 break;
208 case 'BDAY':
209 if (strcmp($this->types['BDAY'], '') != 0) {
210 $bday = $this->fold('BDAY:' . $this->types['BDAY']) . "\n";
211 } else {
212 $bday = '';
213 }
214 break;
215 case 'ADR':
216 if (count($this->types['ADR'])) {
217 $addresses = '';
218 foreach ($this->types['ADR'] as $key => $address) {
219 $test = implode('', $address);
220 if (strcmp($test, '') != 0) {
221 $adr = 'ADR';
222 $adr_types = [];
223 if ($address['TYPE'] > 0) {
224 if (($address['TYPE'] & ADR_TYPE_DOM) > 0) {
225 $adr_types[] = 'dom';
226 }
227 if (($address['TYPE'] & ADR_TYPE_INTL) > 0) {
228 $adr_types[] = 'intl';
229 }
230 if (($address['TYPE'] & ADR_TYPE_POSTAL) > 0) {
231 $adr_types[] = 'postal';
232 }
233 if (($address['TYPE'] & ADR_TYPE_PARCEL) > 0) {
234 $adr_types[] = 'parcel';
235 }
236 if (($address['TYPE'] & ADR_TYPE_HOME) > 0) {
237 $adr_types[] = 'home';
238 }
239 if (($address['TYPE'] & ADR_TYPE_WORK) > 0) {
240 $adr_types[] = 'work';
241 }
242 if (($address['TYPE'] & ADR_TYPE_PREF) > 0) {
243 $adr_types[] = 'pref';
244 }
245 $adr .= ';TYPE=' . implode(',', $adr_types);
246 }
247 $adr .= ':' . $address['POBOX'] . ';' . $address['EXTENDED_ADDRESS'] .
248 ';' . $address['STREET_ADDRESS'] . ';' . $address['LOCALITY'] .
249 ';' . $address['REGION'] . ';' . $address['POSTAL_CODE'] .
250 ';' . $address['COUNTRY'];
251 $adr = $this->fold($adr) . "\n";
252 $addresses .= $adr;
253 }
254 }
255 $adr = $addresses;
256 } else {
257 $adr = '';
258 }
259 break;
260 case 'LABEL':
261 $label = '';
262 if (isset($this->types['LABEL'])) {
263 if (strcmp(($this->types['LABEL']['LABEL'] ?? ''), '') != 0) {
264 $label = 'LABEL';
265 $adr_types = [];
266 if ($this->types['LABEL']['TYPE'] > 0) {
267 if (($this->types['LABEL']['TYPE'] & self::ADR_TYPE_DOM) > 0) {
268 $adr_types[] = 'dom';
269 }
270 if (($this->types['LABEL']['TYPE'] & self::ADR_TYPE_INTL) > 0) {
271 $adr_types[] = 'intl';
272 }
273 if (($this->types['LABEL']['TYPE'] & self::ADR_TYPE_POSTAL) > 0) {
274 $adr_types[] = 'postal';
275 }
276 if (($this->types['LABEL']['TYPE'] & self::ADR_TYPE_PARCEL) > 0) {
277 $adr_types[] = 'parcel';
278 }
279 if (($this->types['LABEL']['TYPE'] & self::ADR_TYPE_HOME) > 0) {
280 $adr_types[] = 'home';
281 }
282 if (($this->types['LABEL']['TYPE'] & self::ADR_TYPE_WORK) > 0) {
283 $adr_types[] = 'work';
284 }
285 if (($this->types['LABEL']['TYPE'] & self::ADR_TYPE_PREF) > 0) {
286 $adr_types[] = 'pref';
287 }
288 $label .= ';TYPE=' . implode(',', $adr_types);
289 }
290 $label .= ':' . $this->types['LABEL']['LABEL'];
291 $label = $this->fold($label) . "\n";
292 }
293 }
294 break;
295 case 'TEL':
296 if (count($this->types['TEL'])) {
297 $phonenumbers = '';
298 foreach ($this->types['TEL'] as $key => $phone) {
299 if (strcmp($phone['TEL'], '') != 0) {
300 $tel = 'TEL';
301 $tel_types = [];
302 if ($phone['TYPE'] > 0) {
303 if (($phone['TYPE'] & self::TEL_TYPE_HOME) > 0) {
304 $tel_types[] = 'home';
305 }
306 if (($phone['TYPE'] & self::TEL_TYPE_MSG) > 0) {
307 $tel_types[] = 'msg';
308 }
309 if (($phone['TYPE'] & self::TEL_TYPE_WORK) > 0) {
310 $tel_types[] = 'work';
311 }
312 if (($phone['TYPE'] & self::TEL_TYPE_PREF) > 0) {
313 $tel_types[] = 'pref';
314 }
315 if (($phone['TYPE'] & self::TEL_TYPE_VOICE) > 0) {
316 $tel_types[] = 'voice';
317 }
318 if (($phone['TYPE'] & self::TEL_TYPE_FAX) > 0) {
319 $tel_types[] = 'fax';
320 }
321 if (($phone['TYPE'] & self::TEL_TYPE_CELL) > 0) {
322 $tel_types[] = 'cell';
323 }
324 if (($phone['TYPE'] & self::TEL_TYPE_VIDEO) > 0) {
325 $tel_types[] = 'video';
326 }
327 if (($phone['TYPE'] & self::TEL_TYPE_PAGER) > 0) {
328 $tel_types[] = 'pager';
329 }
330 if (($phone['TYPE'] & self::TEL_TYPE_BBS) > 0) {
331 $tel_types[] = 'bbs';
332 }
333 if (($phone['TYPE'] & self::TEL_TYPE_MODEM) > 0) {
334 $tel_types[] = 'modem';
335 }
336 if (($phone['TYPE'] & self::TEL_TYPE_CAR) > 0) {
337 $tel_types[] = 'car';
338 }
339 if (($phone['TYPE'] & self::TEL_TYPE_ISDN) > 0) {
340 $tel_types[] = 'isdn';
341 }
342 if (($phone['TYPE'] & self::TEL_TYPE_PCS) > 0) {
343 $tel_types[] = 'pcs';
344 }
345 $tel .= ';TYPE=' . implode(',', $tel_types);
346 }
347 $tel .= ':' . $phone['TEL'];
348 $tel = $this->fold($tel) . "\n";
349 $phonenumbers .= $tel;
350 }
351 }
352 $tel = $phonenumbers;
353 } else {
354 $tel = '';
355 }
356 break;
357 case 'EMAIL':
358 if (count($this->types['EMAIL'])) {
359 $emails = '';
360 foreach ($this->types['EMAIL'] as $key => $mail) {
361 if (strcmp($mail['EMAIL'], '') != 0) {
362 $email = 'EMAIL';
363 $adr_types = [];
364 if ($mail['TYPE'] > 0) {
365 if (($mail['TYPE'] & self::EMAIL_TYPE_INTERNET) > 0) {
366 $adr_types[] = 'internet';
367 }
368 if (($mail['TYPE'] & self::EMAIL_TYPE_x400) > 0) {
369 $adr_types[] = 'x400';
370 }
371 if (($mail['TYPE'] & self::EMAIL_TYPE_PREF) > 0) {
372 $adr_types[] = 'pref';
373 }
374 $email .= ';TYPE=' . implode(',', $adr_types);
375 }
376 $email .= ':' . $mail['EMAIL'];
377 $email = $this->fold($email) . "\n";
378 $emails .= $email;
379 }
380 }
381 $email = $emails;
382 } else {
383 $email = '';
384 }
385 break;
386 case 'MAILER':
387 if (strcmp(($this->types['MAILER'] ?? ''), '') != 0) {
388 $mailer = $this->fold('MAILER:' . $this->types['MAILER']) . "\n";
389 } else {
390 $mailer = '';
391 }
392 break;
393 case 'TZ':
394 if (strcmp(($this->types['TZ'] ?? ''), '') != 0) {
395 $tz = $this->fold('TZ:' . $this->types['TZ']) . "\n";
396 } else {
397 $tz = '';
398 }
399 break;
400 case 'GEO':
401 if (isset($this->types['GEO']) and
402 (strcmp(($this->types['GEO']['LAT'] ?? ''), '') != 0) and
403 (strcmp(($this->types['GEO']['LON'] ?? ''), '') != 0)) {
404 $geo = $this->fold(
405 'GEO:' . $this->types['GEO']['LAT'] . ';' . $this->types['GEO']['LON']
406 ) . "\n";
407 } else {
408 $geo = '';
409 }
410 break;
411 case 'TITLE':
412 if (strcmp(($this->types['TITLE'] ?? ''), '') != 0) {
413 $title = $this->fold('TITLE:' . $this->types['TITLE']) . "\n";
414 } else {
415 $title = '';
416 }
417 break;
418 case 'ROLE':
419 if (strcmp(($this->types['ROLE'] ?? ''), '') != 0) {
420 $role = $this->fold('ROLE:' . $this->types['ROLE']) . "\n";
421 } else {
422 $role = '';
423 }
424 break;
425 case 'LOGO':
426 $logo = '';
427 if (isset($this->types['LOGO'])) {
428 if (strcmp(($this->types['LOGO']['VALUE'] ?? ''), '') != 0) {
429 $logo = $this->fold('LOGO;VALUE=uri:' . $this->types['LOGO']['VALUE']) . "\n";
430 } elseif (strcmp(($this->types['LOGO']['ENCODING'] ?? ''), '') != 0) {
431 $logo = 'LOGO;ENCODING=' . $this->types['LOGO']['ENCODING'];
432 if (strcmp($this->types['LOGO']['TYPE'], '') != 0) {
433 $logo .= ';TYPE=' . $this->types['LOGO']['TYPE'];
434 }
435 $logo .= ':' . $this->types['LOGO']['LOGO'];
436 $logo = $this->fold($logo) . "\n";
437 }
438 }
439 break;
440 case 'AGENT':
441 if (strcmp(($this->types['AGENT'] ?? ''), '') != 0) {
442 $agent = $this->fold('AGENT:' . $this->types['AGENT']) . "\n";
443 } else {
444 $agent = '';
445 }
446 break;
447 case 'ORG':
448 if (strcmp(($this->types['ORG'] ?? ''), '') != 0) {
449 $org = $this->fold('ORG:' . $this->types['ORG']) . "\n";
450 } else {
451 $org = '';
452 }
453 break;
454 case 'CATEGORIES':
455 if (strcmp(($this->types['CATEGORIES'] ?? ''), '') != 0) {
456 $categories = $this->fold('CATEGORIES:' . $this->types['CATEGORIES']) . "\n";
457 } else {
458 $categories = '';
459 }
460 break;
461 case 'NOTE':
462 if (strcmp(($this->types['NOTE'] ?? ''), '') != 0) {
463 $note = $this->fold('NOTE:' . $this->types['NOTE']) . "\n";
464 } else {
465 $note = '';
466 }
467 break;
468 case 'PRODID':
469 if (strcmp(($this->types['PRODID'] ?? ''), '') != 0) {
470 $prodid = $this->fold('PRODID:' . $this->types['PRODID']) . "\n";
471 } else {
472 $prodid = '';
473 }
474 break;
475 case 'REV':
476 if (strcmp(($this->types['REV'] ?? ''), '') != 0) {
477 $rev = $this->fold('REV:' . $this->types['REV']) . "\n";
478 } else {
479 $rev = '';
480 }
481 break;
482 case 'SORT-STRING':
483 if (strcmp(($this->types['SORT-STRING'] ?? ''), '') != 0) {
484 $sortstring = $this->fold('SORT-STRING:' . $this->types['SORT-STRING']) . "\n";
485 } else {
486 $sortstring = '';
487 }
488 break;
489 case 'SOUND':
490 $sound = '';
491 if (isset($this->types['SOUND'])) {
492 if (strcmp(($this->types['SOUND']['VALUE'] ?? ''), '') != 0) {
493 $sound = $this->fold('SOUND;VALUE=uri:' . $this->types['SOUND']['VALUE']) . "\n";
494 } elseif (strcmp(($this->types['SOUND']['ENCODING'] ?? ''), '') != 0) {
495 $sound = 'SOUND;ENCODING=' . $this->types['SOUND']['ENCODING'];
496 if (strcmp($this->types['SOUND']['TYPE'], '') != 0) {
497 $sound .= ';TYPE=' . $this->types['SOUND']['TYPE'];
498 }
499 $sound .= ':' . $this->types['SOUND']['SOUND'];
500 $sound = $this->fold($sound) . "\n";
501 }
502 }
503 break;
504 case 'UID':
505 $uid = '';
506 if (isset($this->types['UID'])) {
507 if (strcmp(($this->types['UID']['UID'] ?? ''), '') != 0) {
508 $uid = 'UID';
509 if (strcmp($this->types['UID']['TYPE'], '') != 0) {
510 $uid .= ';TYPE=' . $this->types['UID']['TYPE'];
511 }
512 $uid .= ':' . $this->types['UID']['UID'];
513 $uid = $this->fold($uid) . "\n";
514 }
515 }
516 break;
517 case 'URL':
518 if (strcmp(($this->types['URL'] ?? ''), '') != 0) {
519 $url = $this->fold('URL:' . $this->types['URL']) . "\n";
520 } else {
521 $url = '';
522 }
523 break;
524 case 'KEY':
525 $key = '';
526 if (isset($this->types['KEY'])) {
527 if (strcmp(($this->types['KEY']['KEY'] ?? ''), '') != 0) {
528 $key = 'KEY';
529 if (strcmp($this->types['KEY']['TYPE'], '') != 0) {
530 $key .= ';TYPE=' . $this->types['KEY']['TYPE'];
531 }
532 if (strcmp($this->types['KEY']['ENCODING'], '') != 0) {
533 $key .= ';ENCODING=' . $this->types['KEY']['ENCODING'];
534 }
535 $key .= ':' . $this->types['KEY']['KEY'];
536 $key = $this->fold($key) . "\n";
537 }
538 }
539 break;
540 case 'CLASS':
541 if (strcmp(($this->types['CLASS'] ?? ''), '') != 0) {
542 $class = $this->fold('CLASS:' . $this->types['CLASS']) . "\n";
543 } else {
544 $class = '';
545 }
546 break;
547 }
548 }
549 $vcard .= $fn . $n . $nickname . $photo . $bday . $adr . $label . $tel . $email . $mailer .
550 $tz . $geo . $title . $role . $logo . $agent . $org . $categories . $note . $prodid .
551 $rev . $sortstring . $sound . $uid . $url . $class . $key;
552 $vcard .= "END:vCard\n";
553 return $vcard;
554 }
555
559 public function quoted_printable_encode(string $input, int $line_max = 76): string
560 {
561 $hex = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'];
562 $lines = preg_split('/(\r\n|\r|\n)/', $input);
563 $eol = "\r\n";
564 $linebreak = '=0D=0A';
565 $escape = '=';
566 $output = '';
567
568 for ($j = 0, $jMax = count($lines); $j < $jMax; $j++) {
569 $line = $lines[$j];
570 $linlen = strlen($line);
571 $newline = '';
572 for ($i = 0; $i < $linlen; $i++) {
573 $c = substr($line, $i, 1);
574 $dec = ord($c);
575 if (($dec == 32) && ($i == ($linlen - 1))) { // convert space at eol only
576 $c = '=20';
577 } elseif (($dec == 61) || ($dec < 32) || ($dec > 126)) { // always encode '\t', which is *not* required
578 $h2 = floor($dec / 16);
579 $h1 = floor($dec % 16);
580 $c = $escape . $hex[(string) $h2] . $hex[(string) $h1];
581 }
582 if ((strlen($newline) + strlen($c)) >= $line_max) { // CRLF is not counted
583 $output .= $newline . $escape . $eol; // soft line break; ' =\r\n' is okay
584 $newline = ' ';
585 }
586 $newline .= $c;
587 } // end of for
588 $output .= $newline;
589 if ($j < count($lines) - 1) {
590 $output .= $linebreak;
591 }
592 }
593 return trim($output);
594 }
595
596 // Identification Types
597 // These types are used in the vCard profile to capture information
598 // associated with the identification and naming of the person or
599 // resource associated with the vCard.
600
609 public function setFormattedName(string $formatted_name): void
610 {
611 $this->types['FN'] = $this->escape($formatted_name);
612 }
613
636 public function setName(
637 string $family_name,
638 string $given_name = '',
639 string $additional_names = '',
640 string $honorific_prefixes = '',
641 string $honorific_suffixes = ''
642 ): void {
643 $familynames = $this->explodeVar($family_name);
644 $givennames = $this->explodeVar($given_name);
645 $addnames = $this->explodeVar($additional_names);
646 $prefixes = $this->explodeVar($honorific_prefixes);
647 $suffixes = $this->explodeVar($honorific_suffixes);
648
649 $this->types['N'] =
650 implode(',', $familynames) .
651 ';' .
652 implode(',', $givennames) .
653 ';' .
654 implode(',', $addnames) .
655 ';' .
656 implode(',', $prefixes) .
657 ';' .
658 implode(',', $suffixes);
659
660 $this->filename = $given_name . '_' . $family_name . '.vcf';
661 if (strcmp($this->types['FN'], '') === 0) {
662 $fn = trim("$honorific_prefixes $given_name $additional_names $family_name $honorific_suffixes");
663 $fn = preg_replace('/\s{2,10}/', ' ', $fn);
664 $this->setFormattedName($fn);
665 }
666 }
667
681 public function setNickname(string $nickname): void
682 {
683 $nicknames = $this->explodeVar($nickname);
684 $this->types['NICKNAME'] = implode(',', $nicknames);
685 }
686
713 public function setPhoto(
714 string $photo,
715 string $type = ''
716 ): void {
717 $value = '';
718 $encoding = '';
719 if (preg_match('/^http/', $photo)) {
720 $value = $this->encode($photo);
721 } else {
722 $encoding = 'b';
723 $photo = base64_encode($photo);
724 }
725 $this->types['PHOTO'] = [
726 'VALUE' => $value,
727 'TYPE' => $type,
728 'ENCODING' => $encoding,
729 'PHOTO' => $photo
730 ];
731 }
732
747 public function setBirthday(int $year, int $month, int $day): void
748 {
749 if (($year < 1) or ($day < 1) or ($month < 1)) {
750 $this->types['BDAY'] = '';
751 } else {
752 $this->types['BDAY'] = sprintf('%04d-%02d-%02d', $year, $month, $day);
753 }
754 }
755
756 // Delivery Addressing Types
757 // These types are concerned with information related to the delivery
758 // addressing or label for the vCard object.
759
807 public function setAddress(
808 string $po_box = '',
809 string $extended_address = '',
810 string $street_address = '',
811 string $locality = '',
812 string $region = '',
813 string $postal_code = '',
814 string $country = '',
815 int $type = self::ADR_TYPE_NONE
816 ): void {
817 if ($type === self::ADR_TYPE_NONE) {
818 $type = self::ADR_TYPE_INTL + self::ADR_TYPE_POSTAL + self::ADR_TYPE_PARCEL + self::ADR_TYPE_WORK;
819 }
820 $po_box = implode(',', $this->explodeVar($po_box));
821 $extended_address = implode(',', $this->explodeVar($extended_address));
822 $street_address = implode(',', $this->explodeVar($street_address));
823 $locality = implode(',', $this->explodeVar($locality));
824 $region = implode(',', $this->explodeVar($region));
825 $postal_code = implode(',', $this->explodeVar($postal_code));
826 $country = implode(',', $this->explodeVar($country));
827 $this->types['ADR'][] = [
828 'POBOX' => $po_box,
829 'EXTENDED_ADDRESS' => $extended_address,
830 'STREET_ADDRESS' => $street_address,
831 'LOCALITY' => $locality,
832 'REGION' => $region,
833 'POSTAL_CODE' => $postal_code,
834 'COUNTRY' => $country,
835 'TYPE' => $type
836 ];
837 }
838
869 public function setLabel(
870 string $label = '',
871 int $type = self::ADR_TYPE_NONE
872 ): void {
873 if ($type == self::ADR_TYPE_NONE) {
874 $type = self::ADR_TYPE_INTL + self::ADR_TYPE_POSTAL + self::ADR_TYPE_PARCEL + self::ADR_TYPE_WORK;
875 }
876 $this->types['LABEL'] = [
877 'LABEL' => $this->escape($label),
878 'TYPE' => $type
879 ];
880 }
881
882 // Telecommunications Addressing Types
883 // These types are concerned with information associated with the
884 // telecommunications addressing of the object the vCard represents.
885
921 public function setPhone(
922 string $number = '',
923 int $type = self::TEL_TYPE_VOICE
924 ): void {
925 $this->types['TEL'][] = [
926 'TEL' => $this->escape($number),
927 'TYPE' => $type
928 ];
929 }
930
951 public function setEmail(
952 string $address = '',
953 int $type = self::EMAIL_TYPE_INTERNET
954 ): void {
955 $this->types['EMAIL'][] = [
956 'EMAIL' => $this->escape($address),
957 'TYPE' => $type
958 ];
959 }
960
975 public function setMailer(string $name = ''): void
976 {
977 $this->types['MAILER'] = $this->escape($name);
978 }
979
980 // Geographical Types
981 // These types are concerned with information associated with
982 // geographical positions or regions associated with the object the
983 // vCard represents.
984
996 public function setTimezone(string $zone = ''): void
997 {
998 $this->types['TZ'] = $this->escape($zone);
999 }
1000
1027 public function setPosition(string $latitude = '', string $longitude = ''): void
1028 {
1029 $this->types['GEO'] = [
1030 'LAT' => $latitude,
1031 'LON' => $longitude
1032 ];
1033 }
1034
1035 // Organizational Types
1036 // These types are concerned with information associated with
1037 // characteristics of the organization or organizational units of the
1038 // object the vCard represents.
1039
1050 public function setTitle(string $title = ''): void
1051 {
1052 $this->types['TITLE'] = $this->escape($title);
1053 }
1054
1069 public function setRole(string $role = ''): void
1070 {
1071 $this->types['ROLE'] = $this->escape($role);
1072 }
1073
1099 public function setLogo(string $logo, string $type = ''): void
1100 {
1101 $value = '';
1102 $encoding = '';
1103 if (preg_match('/^http/', $logo)) {
1104 $value = $this->encode($logo);
1105 } else {
1106 $encoding = 'b';
1107 $logo = base64_encode($logo);
1108 }
1109 $this->types['LOGO'] = [
1110 'VALUE' => $value,
1111 'TYPE' => $type,
1112 'ENCODING' => $encoding,
1113 'LOGO' => $logo
1114 ];
1115 }
1116
1137 public function setAgent(string $agent = ''): void
1138 {
1139 $this->types['AGENT'] = $this->escape($agent);
1140 }
1141
1156 public function setOrganization(string $organization = ''): void
1157 {
1158 $organization = implode(';', $this->explodeVar($organization, ';'));
1159 $this->types['ORG'] = $organization;
1160 }
1161
1162 // Explanatory Types
1163 // These types are concerned with additional explanations, such as that
1164 // related to informational notes or revisions specific to the vCard.
1165
1177 public function setCategories(string $categories): void
1178 {
1179 $categories = implode(',', $this->explodeVar($categories));
1180 $this->types['CATEGORIES'] = $categories;
1181 }
1182
1195 public function setNote(string $note = ''): void
1196 {
1197 $this->types['NOTE'] = $this->escape($note);
1198 }
1199
1212 public function setProductId(string $product_id = ''): void
1213 {
1214 $this->types['PRODID'] = $this->escape($product_id);
1215 }
1216
1231 public function setRevision(string $revision_date = ''): void
1232 {
1233 $this->types['REV'] = $this->escape($revision_date);
1234 }
1235
1268 public function setSortString(string $string = ''): void
1269 {
1270 $this->types['SORT-STRING'] = $this->escape($string);
1271 }
1272
1299 public function setSound(string $sound = '', string $type = ''): void
1300 {
1301 $value = '';
1302 $encoding = '';
1303 if (preg_match('/^http/', $sound)) {
1304 $value = $this->encode($sound);
1305 } else {
1306 $encoding = 'b';
1307 $sound = base64_encode($sound);
1308 }
1309 $this->types['SOUND'] = [
1310 'VALUE' => $value,
1311 'TYPE' => $type,
1312 'ENCODING' => $encoding,
1313 'SOUND' => $sound
1314 ];
1315 }
1316
1335 public function setUID(string $uid = '', string $type = ''): void
1336 {
1337 $this->types['UID'] = [
1338 'UID' => $this->escape($uid),
1339 'TYPE' => $type
1340 ];
1341 }
1342
1353 public function setURL(string $uri = ''): void
1354 {
1355 $this->types['URL'] = $this->escape($uri);
1356 }
1357
1368 public function setVersion(string $version = '3.0'): void
1369 {
1370 $this->types['VERSION'] = $version;
1371 }
1372
1373 // Security Types
1374 // These types are concerned with the security of communication pathways
1375 // or access to the vCard.
1376
1393 public function setClassification(string $classification = ''): void
1394 {
1395 $this->types['CLASS'] = $this->escape($classification);
1396 }
1397
1434 public function setKey(string $key = '', string $type = ''): void
1435 {
1436 $encoding = 'b';
1437 $key = base64_encode($key);
1438 $this->types['KEY'] = [
1439 'KEY' => $key,
1440 'TYPE' => $type,
1441 'ENCODING' => $encoding
1442 ];
1443 }
1444
1445 public function getFilename(): string
1446 {
1447 if (strcmp($this->filename, '') == 0) {
1448 return 'vcard.vcf';
1449 } else {
1450 return $this->filename;
1451 }
1452 }
1453
1454 public function getMimetype(): string
1455 {
1456 return 'text/x-vcard';
1457 }
1458}
$version
Definition: plugin.php:24
$classification
$filename
Definition: buildRTE.php:78
RFC 2426 vCard MIME Directory Profile 3.0 class.
Definition: VCard.php:28
setLabel(string $label='', int $type=self::ADR_TYPE_NONE)
Sets the value for the vCard LABEL type.
Definition: VCard.php:869
setRevision(string $revision_date='')
Sets the value for the vCard REV type.
Definition: VCard.php:1231
fold(string $string='')
Fold a string according to RFC 2425.
Definition: VCard.php:116
setMailer(string $name='')
Sets the value for the vCard MAILER type.
Definition: VCard.php:975
setPosition(string $latitude='', string $longitude='')
Sets the value for the vCard GEO type.
Definition: VCard.php:1027
setOrganization(string $organization='')
Sets the value for the vCard ORG type.
Definition: VCard.php:1156
setSound(string $sound='', string $type='')
Sets the value for the vCard SOUND type.
Definition: VCard.php:1299
escape(string $string)
Escapes a string according to RFC 2426.
Definition: VCard.php:135
quoted_printable_encode(string $input, int $line_max=76)
Creates a quoted printable encoded string according to RFC 2045.
Definition: VCard.php:559
setProductId(string $product_id='')
Sets the value for the vCard PRODID type.
Definition: VCard.php:1212
setAddress(string $po_box='', string $extended_address='', string $street_address='', string $locality='', string $region='', string $postal_code='', string $country='', int $type=self::ADR_TYPE_NONE)
Sets the value for the vCard ADR type.
Definition: VCard.php:807
setPhoto(string $photo, string $type='')
Sets the value for the vCard PHOTO type.
Definition: VCard.php:713
setUID(string $uid='', string $type='')
Sets the value for the vCard UID type.
Definition: VCard.php:1335
setBirthday(int $year, int $month, int $day)
Sets the value for the vCard BDAY type.
Definition: VCard.php:747
encode(string $string)
Encode data with 'b' type encoding according to RFC 2045.
Definition: VCard.php:108
setKey(string $key='', string $type='')
Sets the value for the vCard KEY type.
Definition: VCard.php:1434
setNote(string $note='')
Sets the value for the vCard NOTE type.
Definition: VCard.php:1195
setRole(string $role='')
Sets the value for the vCard ROLE type.
Definition: VCard.php:1069
setTimezone(string $zone='')
Sets the value for the vCard TZ type.
Definition: VCard.php:996
setNickname(string $nickname)
Sets the value for the vCard NICKNAME type.
Definition: VCard.php:681
setURL(string $uri='')
Sets the value for the vCard URL type.
Definition: VCard.php:1353
setPhone(string $number='', int $type=self::TEL_TYPE_VOICE)
Sets the value for the vCard TEL type.
Definition: VCard.php:921
setTitle(string $title='')
Sets the value for the vCard TITLE type.
Definition: VCard.php:1050
setName(string $family_name, string $given_name='', string $additional_names='', string $honorific_prefixes='', string $honorific_suffixes='')
Sets the value for the vCard N type.
Definition: VCard.php:636
setClassification(string $classification='')
Sets the value for the vCard CLASS type.
Definition: VCard.php:1393
buildVCard()
Builds a vCard string out of the attributes of this object.
Definition: VCard.php:160
setLogo(string $logo, string $type='')
Sets the value for the vCard LOGO type.
Definition: VCard.php:1099
__construct(string $version='3.0')
Definition: VCard.php:71
setVersion(string $version='3.0')
Sets the value for the vCard VERSION type.
Definition: VCard.php:1368
setAgent(string $agent='')
Sets the value for the vCard AGENT type.
Definition: VCard.php:1137
setEmail(string $address='', int $type=self::EMAIL_TYPE_INTERNET)
Sets the value for the vCard EMAIL type.
Definition: VCard.php:951
setCategories(string $categories)
Sets the value for the vCard CATEGORIES type.
Definition: VCard.php:1177
explodeVar(string $variable, string $separator=',')
Splits a variable into an array using a separator and escapes every value.
Definition: VCard.php:148
setFormattedName(string $formatted_name)
Sets the value for the vCard FN type.
Definition: VCard.php:609
setSortString(string $string='')
Sets the value for the vCard SORT-STRING type.
Definition: VCard.php:1268
static getLogger(string $a_component_id)
Get component logger.
$c
Definition: deliver.php:25
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
if(!file_exists('../ilias.ini.php'))
$url
Definition: shib_logout.php:68