PHPGangsta - Der praktische PHP Blog

PHP Blog von PHPGangsta


Archive for the ‘vcf’ tag

Adress- und Kontaktdaten als VCard exportieren

with 13 comments

VCards sind kleine Dateien, die Personen- und Adressbuch-Daten enthalten. Diese Dateien kann man wunderbar an Emails dranhängen, oder aber als Export + Import zwischen verschiedenen Programmen (Outlook, Thunderbird, Mac OS X Addressbook etc) nutzen. Als Premium-Mitglied bei Xing kann man alle seine Kontakte dort auch exportieren und in die oben genannten Applikationen oder auch in sein Handy importieren.

Wie sieht eine VCard aus? Ungefähr so:

BEGIN:VCARD
VERSION:3.0
N:Kliewe;Michael
FN:Michael Kliewe
ADR;TYPE=HOME,WORK:;;Am Stadtgarten 8a;Oelde;;59302
EMAIL;TYPE=HOME;TYPE=WORK:emailadresse@domain.de
EMAIL;TYPE=PREF:wichtige@emailaddresse.de
END:VCARD

Man sieht, das Format ist schon recht alt (1998), heutzutage würde man wahrscheinlich XML wählen. Aber es ist nun mal DER Standard, wir wollen die Adressdaten aus unserer Applikation als VCard exportieren. Dazu gibt es bereits einige vorgefertigte Klassen (Contact_Vcard_Build, PHP vCard Class 2.0, class vcard), die ich aber hier nicht nutzen möchte, da sie entweder das ältere 2.1 Format nutzen oder kein UTF-8 unterstützen. Hier eine einfache Lösung mit wenigen Zeilen Code:

<?php
header("Content-type:text/x-vCard; charset=utf-8");
header("Content-Disposition: attachment; filename=vcardexport.vcf");

$first = "Michael";
$last = "Kliewe";
$email = "emailadresse@domain.de";
?>
BEGIN:VCARD
VERSION:2.1
N:<?php echo($last); ?>;<?php echo($first); ?>
FN:<?php echo($first); ?> <?php echo($last); ?>
EMAIL;PREF;INTERNET:<?php echo($email); ?>
REV:<?php echo date('Y-m-d H:i:s'); ?>
END:VCARD

Das ist natürlich nur der Anfang und ein erster Test. Aber das Prinzip ist recht einfach: Jede Zeile enthält eine Eigenschaft, wie „Voller Name“, „Email-Adresse“, „Wohnadresse“, „Notizen“, „Urls“, „Fotos“, „Firma“, „Geburtstag“ und so weiter. Key und Value sind durch einen Doppelpunkt getrennt, spezielle Optionen wie beispielsweise das oben sichtbare „PREF“ oder „TYPE“ sind via Semikolon getrennt hinzuzufügen. Weitere Informationen erhält man auf der englischen Wikipedia-Seite (die deutsche ist nicht so umfangreich). Man kann auch mehrere Kontakte in einer vcf-Datei exportieren, und objektorientiert mit dem Zend Framework sieht das ganze dann ungefähr so aus:

public function exportvcardAction()
{
	$this->_helper->layout()->disableLayout();
	$this->_helper->viewRenderer->setNoRender();

	$vcardString = '';
	$contacts = $this->service->getAllContacts();
	foreach ($contacts as $contact) {
		/* @var $contact App_Addressbook_Contact */
		$vcardString .= $contact->getContactAsVcardString() . "\r\n";
	}

	if (count($contacts) == 1) {
		$filename = str_replace(" ", "_", $contacts[0]->getFirstname().' '.$contacts[0]->getSurname());
	} else {
		$filename = 'VCARDS';
	}

	$this->getResponse()->setHeader('Content-Type', 'text/x-vCard; charset=utf-8');
	$this->getResponse()->setHeader('Content-Disposition', 'attachment; filename="'.$filename.'.vcf"');
	$this->getResponse()->setHeader('Content-Length', strlen($vcardString));
	$this->getResponse()->setHeader('Connection', 'close');
	$this->getResponse()->setBody($vcardString);
}

Damit werden nun also alle Kontakte iteriert und die einzelnen VCard-Strings aneinandergehängt. Wir nutzen hier die entsprechenden Funktionen, um das Layout und den ViewRenderer zu deaktiveren und alle Informationen ins Response-Objekt zu schreiben
Die Funktion getContactAsVcardString() habe ich so umgesetzt:

public function getContactAsVcardString()
{
	$data['BEGIN'] = 'VCARD';
	$data['VERSION'] = '3.0';
	$data['PRODID'] = '-//company contact export Version 1//EN';
	$data['REV'] = date('Y-m-d H:i:s');
	$data['TZ'] = date('O');

	$data['FN'] = $this->getDisplayName();
	$data['N'] = $this->getSurname().';'.$this->getFirstname();

	if ($this->getTitle() != '') {
		$data['TITLE'] = $this->getTitle();
	}

	foreach ($this->getMailAddresses() as $mailAddress) {
		$data['EMAIL;TYPE=internet'] = $mailAddress;
	}

	if ($this->getNotice() != '') {
		$data['NOTE'] = $this->getNotice();
	}

	$data['END'] = 'VCARD';

	$exportString = '';
	foreach ($data as $index => $value) {
		$exportString .= $index . ':' . $value . "\r\n";
	}

	return $exportString;
}

Als Ergebnis erhält man eine Datei zum Download mit allen $contacts incl. Details.

Written by Michael Kliewe

März 31st, 2010 at 8:44 am

Posted in PHP

Tagged with , , ,