ILIAS  trunk Revision v11.0_alpha-1713-gd8962da2f67
All Data Structures Namespaces Files Functions Variables Enumerations Enumerator Modules Pages
VCard.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
21 namespace ILIAS\User\Profile;
22 
27 class 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 }
setNote(string $note='')
Sets the value for the vCard NOTE type.
Definition: VCard.php:1195
setCategories(string $categories)
Sets the value for the vCard CATEGORIES type.
Definition: VCard.php:1177
encode(string $string)
Encode data with &#39;b&#39; type encoding according to RFC 2045.
Definition: VCard.php:108
setAgent(string $agent='')
Sets the value for the vCard AGENT type.
Definition: VCard.php:1137
setKey(string $key='', string $type='')
Sets the value for the vCard KEY type.
Definition: VCard.php:1434
setPhone(string $number='', int $type=self::TEL_TYPE_VOICE)
Sets the value for the vCard TEL type.
Definition: VCard.php:921
setVersion(string $version='3.0')
Sets the value for the vCard VERSION type.
Definition: VCard.php:1368
static getLogger(string $a_component_id)
Get component logger.
$version
Definition: plugin.php:24
setRole(string $role='')
Sets the value for the vCard ROLE type.
Definition: VCard.php:1069
setBirthday(int $year, int $month, int $day)
Sets the value for the vCard BDAY type.
Definition: VCard.php:747
setRevision(string $revision_date='')
Sets the value for the vCard REV type.
Definition: VCard.php:1231
setPosition(string $latitude='', string $longitude='')
Sets the value for the vCard GEO type.
Definition: VCard.php:1027
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
setSortString(string $string='')
Sets the value for the vCard SORT-STRING type.
Definition: VCard.php:1268
setPhoto(string $photo, string $type='')
Sets the value for the vCard PHOTO type.
Definition: VCard.php:713
setMailer(string $name='')
Sets the value for the vCard MAILER type.
Definition: VCard.php:975
$url
Definition: shib_logout.php:66
$c
Definition: deliver.php:25
setEmail(string $address='', int $type=self::EMAIL_TYPE_INTERNET)
Sets the value for the vCard EMAIL type.
Definition: VCard.php:951
__construct(string $version='3.0')
Definition: VCard.php:71
escape(string $string)
Escapes a string according to RFC 2426.
Definition: VCard.php:135
RFC 2426 vCard MIME Directory Profile 3.0 class.
Definition: VCard.php:27
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
setProductId(string $product_id='')
Sets the value for the vCard PRODID type.
Definition: VCard.php:1212
setClassification(string $classification='')
Sets the value for the vCard CLASS type.
Definition: VCard.php:1393
setFormattedName(string $formatted_name)
Sets the value for the vCard FN type.
Definition: VCard.php:609
setSound(string $sound='', string $type='')
Sets the value for the vCard SOUND type.
Definition: VCard.php:1299
setOrganization(string $organization='')
Sets the value for the vCard ORG type.
Definition: VCard.php:1156
$classification
buildVCard()
Builds a vCard string out of the attributes of this object.
Definition: VCard.php:160
setUID(string $uid='', string $type='')
Sets the value for the vCard UID type.
Definition: VCard.php:1335
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
setLabel(string $label='', int $type=self::ADR_TYPE_NONE)
Sets the value for the vCard LABEL type.
Definition: VCard.php:869
setTitle(string $title='')
Sets the value for the vCard TITLE type.
Definition: VCard.php:1050
setLogo(string $logo, string $type='')
Sets the value for the vCard LOGO type.
Definition: VCard.php:1099
setTimezone(string $zone='')
Sets the value for the vCard TZ type.
Definition: VCard.php:996
fold(string $string='')
Fold a string according to RFC 2425.
Definition: VCard.php:116
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
quoted_printable_encode(string $input, int $line_max=76)
Creates a quoted printable encoded string according to RFC 2045.
Definition: VCard.php:559
explodeVar(string $variable, string $separator=',')
Splits a variable into an array using a separator and escapes every value.
Definition: VCard.php:148