getCompany(); $lines = []; $lines[] = 'BEGIN:VCARD'; $lines[] = 'VERSION:3.0'; // N: Nachname;Vorname;;Präfix(Titel); $lines[] = 'N:'.$this->esc($e->getLastName()).';'.$this->esc($e->getFirstName()).';;' .$this->esc((string) $e->getTitle()).';'; $lines[] = 'FN:'.$this->esc(trim(($e->getTitle() ? $e->getTitle().' ' : '').$e->getFirstName().' '.$e->getLastName())); if ($company) { // ORG:Firma;Abteilung $org = $this->esc($company->getName()); if ($e->getDepartment()) { $org .= ';'.$this->esc($e->getDepartment()); } $lines[] = 'ORG:'.$org; } if ($e->getPosition()) { $lines[] = 'TITLE:'.$this->esc($e->getPosition()); } if ($e->getEmail()) { $lines[] = 'EMAIL;TYPE=WORK:'.$this->esc($e->getEmail()); } if ($e->getEmailPrivate()) { $lines[] = 'EMAIL;TYPE=HOME:'.$this->esc($e->getEmailPrivate()); } if ($e->getPhone()) { $lines[] = 'TEL;TYPE=WORK,VOICE:'.$this->esc($e->getPhone()); } if ($e->getMobile()) { $lines[] = 'TEL;TYPE=CELL:'.$this->esc($e->getMobile()); } if ($e->getPhoneCentral()) { $lines[] = 'TEL;TYPE=WORK:'.$this->esc($e->getPhoneCentral()); } if ($e->getFax()) { $lines[] = 'TEL;TYPE=WORK,FAX:'.$this->esc($e->getFax()); } if ($e->getWebsite()) { $lines[] = 'URL:'.$this->esc($e->getWebsite()); } $this->addAddress($lines, 'WORK', $e->getAddressBusiness() ?? $this->fromLocation($e)); $this->addAddress($lines, 'HOME', $e->getAddressPrivate()); foreach ($e->getContactLinks() as $link) { $lines[] = 'URL:'.$this->esc($link->getUrl()); } if (null !== $e->getPhotoPath()) { $lines[] = 'PHOTO;VALUE=URI:'.$this->urls->generate( 'employee_photo_public', ['id' => (string) $e->getId()], UrlGeneratorInterface::ABSOLUTE_URL, ); } if ($e->getBio()) { $lines[] = 'NOTE:'.$this->esc($e->getBio()); } $lines[] = 'REV:'.$e->getUpdatedAt()->format('Ymd\THis\Z'); $lines[] = 'END:VCARD'; // vCard verlangt CRLF-Zeilenenden return implode("\r\n", $lines)."\r\n"; } /** * @param string[] $lines * @param array|null $a */ private function addAddress(array &$lines, string $type, ?array $a): void { if (null === $a) { return; } $street = trim((string) ($a['street'] ?? '').' '.(string) ($a['houseNumber'] ?? '')); $city = (string) ($a['city'] ?? ''); if ('' === $street && '' === $city) { return; } // ADR: PO;Ext;Straße;Ort;Region;PLZ;Land $lines[] = 'ADR;TYPE='.$type.':;' .$this->esc((string) ($a['addressLine2'] ?? '')).';' .$this->esc($street).';' .$this->esc($city).';' .$this->esc((string) ($a['state'] ?? '')).';' .$this->esc((string) ($a['zip'] ?? '')).';' .$this->esc((string) ($a['country'] ?? '')); } /** * Fallback: Geschäftsadresse aus dem zugeordneten Standort. * * @return array|null */ private function fromLocation(Employee $e): ?array { $l = $e->getLocation(); if (null === $l || (!$l->getStreet() && !$l->getCity())) { return null; } return [ 'street' => (string) $l->getStreet(), 'city' => (string) $l->getCity(), 'zip' => (string) $l->getPostalCode(), 'country' => (string) $l->getCountry(), ]; } /** Escaping gemäß vCard-Spezifikation. */ private function esc(string $value): string { return str_replace( ['\\', "\n", ',', ';'], ['\\\\', '\\n', '\\,', '\\;'], $value, ); } }