using new vcard parser

This commit is contained in:
2016-06-13 13:41:52 +02:00
parent 2118320a5d
commit 7fd75b3efd
9 changed files with 191 additions and 885 deletions

View File

@@ -21,9 +21,11 @@
*
*/
include_once('vcf/class.vCard.php');
require_once('mapi/mapitags.php' );
include_once('vendor/autoload.php');
use JeroenDesloovere\VCard\VCard;
use JeroenDesloovere\VCard\VCardParser;
class ContactModule extends Module {
private $DEBUG = false; // enable error_log debugging
@@ -142,8 +144,9 @@ class ContactModule extends Module {
$error_msg = "";
// parse the vcf file a last time...
$parser = null;
try {
$vcard = new vCard($vcffile, false, array('Collapse' => false)); // Parse it!
$parser = VCardParser::parseFromFile($vcffile);
} catch (Exception $e) {
$error = true;
$error_msg = $e->getMessage();
@@ -151,13 +154,8 @@ class ContactModule extends Module {
$contacts = array();
if(!$error && count($vcard) > 0) {
$vCard = $vcard;
if (count($vCard) == 1) {
$vCard = array($vcard);
}
$contacts = $this->parseContactsToArray($vCard);
if(!$error && iterator_count($parser) > 0) {
$contacts = $this->parseContactsToArray($parser);
$store = $GLOBALS["mapisession"]->openMessageStore(hex2bin($storeid));
$folder = mapi_msgstore_openentry($store, hex2bin($folderid));
@@ -172,7 +170,7 @@ class ContactModule extends Module {
$count = 0;
// iterate through all contacts and import them :)
foreach($contacts as $contact) {
foreach($contacts as $contact) {
if (isset($contact["display_name"]) && ($importall || in_array($contact["internal_fields"]["contact_uid"], $uids))) {
// parse the arraykeys
// TODO: this is very slow...
@@ -194,7 +192,7 @@ class ContactModule extends Module {
$contactPicture = file_get_contents($contact["internal_fields"]["x_photo_path"]);
$attach = mapi_message_createattach($message);
// Set properties of the attachment
// Set properties of the attachment
$propValuesIMG = array(
PR_ATTACH_SIZE => strlen($contactPicture),
PR_ATTACH_LONG_FILENAME => 'ContactPicture.jpg',
@@ -224,7 +222,7 @@ class ContactModule extends Module {
mapi_savechanges($message);
if($this->DEBUG) {
error_log("New contact added: \"" . $propValuesMAPI[$properties["display_name"]] . "\".\n");
}
}
$count++;
}
}
@@ -450,8 +448,10 @@ class ContactModule extends Module {
$error_msg = "";
if(is_readable ($actionData["vcf_filepath"])) {
$parser = null;
try {
$vcard = new vCard($actionData["vcf_filepath"], false, array('Collapse' => false)); // Parse it!
$parser = VCardParser::parseFromFile($actionData["vcf_filepath"]);
} catch (Exception $e) {
$error = true;
$error_msg = $e->getMessage();
@@ -460,19 +460,14 @@ class ContactModule extends Module {
$response['status'] = false;
$response['message']= $error_msg;
} else {
if(count($vcard) == 0) {
if(iterator_count($parser) == 0) {
$response['status'] = false;
$response['message']= "No contacts in vcf file";
} else {
$vCard = $vcard;
if (count($vCard) == 1) {
$vCard = array($vcard);
}
$response['status'] = true;
$response['parsed_file']= $actionData["vcf_filepath"];
$response['parsed'] = array (
'contacts' => $this->parseContactsToArray($vCard)
'contacts' => $this->parseContactsToArray($parser)
);
}
}
@@ -503,141 +498,156 @@ class ContactModule extends Module {
if(!$csv) {
foreach ($contacts as $Index => $vCard) {
$properties = array();
$properties["display_name"] = $vCard -> FN[0];
$properties["fileas"] = $vCard -> FN[0];
if (isset($vCard->fullname)) {
$properties["display_name"] = $vCard->fullname;
$properties["fileas"] = $vCard->fullname;
} elseif(!isset($vCard->organization)) {
error_log("Skipping entry! No fullname/organization given.");
continue;
}
//uid - used for front/backend communication
$properties["internal_fields"] = array();
$properties["internal_fields"]["contact_uid"] = base64_encode($Index . $properties["fileas"]);
foreach ($vCard -> N as $Name) {
$properties["given_name"] = $Name['FirstName'];
$properties["middle_name"] = $Name['AdditionalNames'];
$properties["surname"] = $Name['LastName'];
$properties["display_name_prefix"] = $Name['Prefixes'];
}
if ($vCard -> TEL) {
foreach ($vCard -> TEL as $Tel) {
if(!is_scalar($Tel)) {
if(in_array("home", $Tel['Type'])) {
$properties["home_telephone_number"] = $Tel['Value'];
} else if(in_array("cell", $Tel['Type'])) {
$properties["cellular_telephone_number"] = $Tel['Value'];
} else if(in_array("work", $Tel['Type'])) {
$properties["business_telephone_number"] = $Tel['Value'];
} else if(in_array("fax", $Tel['Type'])) {
$properties["business_fax_number"] = $Tel['Value'];
} else if(in_array("pager", $Tel['Type'])) {
$properties["pager_telephone_number"] = $Tel['Value'];
} else if(in_array("isdn", $Tel['Type'])) {
$properties["isdn_number"] = $Tel['Value'];
} else if(in_array("car", $Tel['Type'])) {
$properties["car_telephone_number"] = $Tel['Value'];
} else if(in_array("modem", $Tel['Type'])) {
$properties["ttytdd_telephone_number"] = $Tel['Value'];
}
$properties["given_name"] = $vCard->firstname;
$properties["middle_name"] = $vCard->additional;
$properties["surname"] = $vCard->lastname;
$properties["display_name_prefix"] = $vCard->prefix;
if (isset($vCard->phone) && count($vCard->phone) > 0) {
foreach ($vCard->phone as $type => $number) {
$number = $number[0]; // we only can store one number
if($this->startswith(strtolower($type), "home") || strtolower($type) === "default") {
$properties["home_telephone_number"] = $number;
} else if($this->startswith(strtolower($type), "cell")) {
$properties["cellular_telephone_number"] = $number;
} else if($this->startswith(strtolower($type), "work")) {
$properties["business_telephone_number"] = $number;
} else if($this->startswith(strtolower($type), "fax")) {
$properties["business_fax_number"] = $number;
} else if($this->startswith(strtolower($type), "pager")) {
$properties["pager_telephone_number"] = $number;
} else if($this->startswith(strtolower($type), "isdn")) {
$properties["isdn_number"] = $number;
} else if($this->startswith(strtolower($type), "car")) {
$properties["car_telephone_number"] = $number;
} else if($this->startswith(strtolower($type), "modem")) {
$properties["ttytdd_telephone_number"] = $number;
}
}
}
if ($vCard -> EMAIL) {
$e=0;
foreach ($vCard -> EMAIL as $Email) {
$fileas = $Email['Value'];
if (isset($vCard->email) && count($vCard->email) > 0) {
$emailcount = 0;
foreach ($vCard->email as $type => $email) {
$email = $email[0]; // we only can store one mail address
$fileas = $email;
if(isset($properties["fileas"]) && !empty($properties["fileas"])) {
$fileas = $properties["fileas"];
$fileas = $properties["fileas"]; // set to real name
}
if(!is_scalar($Email)) {
switch($e) {
case 0:
$properties["email_address_1"] = $Email['Value'];
$properties["email_address_display_name_1"] = $fileas . " (" . $Email['Value'] . ")";
break;
case 1:
$properties["email_address_2"] = $Email['Value'];
$properties["email_address_display_name_2"] = $fileas . " (" . $Email['Value'] . ")";
break;
case 2:
$properties["email_address_3"] = $Email['Value'];
$properties["email_address_display_name_3"] = $fileas . " (" . $Email['Value'] . ")";
break;
default: break;
// we only have storage for 3 mail addresses!
switch($emailcount) {
case 0:
$properties["email_address_1"] = $email;
$properties["email_address_display_name_1"] = $fileas . " (" . $email . ")";
break;
case 1:
$properties["email_address_2"] = $email;
$properties["email_address_display_name_2"] = $fileas . " (" . $email . ")";
break;
case 2:
$properties["email_address_3"] = $email;
$properties["email_address_display_name_3"] = $fileas . " (" . $email . ")";
break;
default: break;
}
$emailcount++;
}
}
if (isset($vCard->organization)) {
$properties["company_name"] = $vCard->organization;
if(empty($properties["display_name"])) {
$properties["display_name"] = $vCard->organization; // if we have no displayname - use the company name as displayname
$properties["fileas"] = $vCard->organization;
}
}
if (isset($vCard->title)) {
$properties["title"] = $vCard->title;
}
if (isset($vCard->url) && count($vCard->url) > 0) {
foreach ($vCard->url as $type => $url) {
$url = $url[0]; // only 1 webaddress per type
$properties["webpage"] = $url;
break; // we can only store on url
}
}
if (isset($vCard->address) && count($vCard->address) > 0) {
foreach ($vCard->address as $type => $address) {
$address = $address[0]; // we only can store one address per type
if($this->startswith(strtolower($type), "work")) {
$properties["business_address_street"] = $address->street;
if(!empty($address->extended)) {
$properties["business_address_street"] .= "\n" . $address->extended;
}
$e++;
$properties["business_address_city"] = $address->city;
$properties["business_address_state"] = $address->region;
$properties["business_address_postal_code"] = $address->zip;
$properties["business_address_country"] = $address->country;
$properties["business_address"] = $this->buildAddressString($properties["business_address_street"], $address->zip, $address->city, $address->region, $address->country);
} else if($this->startswith(strtolower($type), "home")) {
$properties["home_address_street"] = $address->street;
if(!empty($address->extended)) {
$properties["home_address_street"] .= "\n" . $address->extended;
}
$properties["home_address_city"] = $address->city;
$properties["home_address_state"] = $address->region;
$properties["home_address_postal_code"] = $address->zip;
$properties["home_address_country"] = $address->country;
$properties["home_address"] = $this->buildAddressString($properties["home_address_street"], $address->zip, $address->city, $address->region, $address->country);
} else {
$properties["other_address_street"] = $address->street;
if(!empty($address->extended)) {
$properties["other_address_street"] .= "\n" . $address->extended;
}
$properties["other_address_city"] = $address->city;
$properties["other_address_state"] = $address->region;
$properties["other_address_postal_code"] = $address->zip;
$properties["other_address_country"] = $address->country;
$properties["other_address"] = $this->buildAddressString($properties["other_address_street"], $address->zip, $address->city, $address->region, $address->country);
}
}
}
if ($vCard -> ORG) {
foreach ($vCard -> ORG as $Organization) {
$properties["company_name"] = $Organization['Name'];
if(empty($properties["display_name"])) {
$properties["display_name"] = $Organization['Name']; // if we have no displayname - use the company name as displayname
$properties["fileas"] = $Organization['Name'];
}
}
if (isset($vCard->birthday)) {
$properties["birthday"] = $vCard->birthday->getTimestamp();
}
if ($vCard -> TITLE) {
$title = $vCard -> TITLE[0];
$properties["title"] = is_array($title) ? $title["Value"] : $title;
if (isset($vCard->note)) {
$properties["notes"] = $vCard->note;
}
if ($vCard -> URL) {
$url = $vCard -> URL[0]; // only 1 webaddress
$properties["webpage"] = is_array($url) ? $url["Value"] : $url;
}
if ($vCard -> IMPP) {
foreach ($vCard -> IMPP as $IMPP) {
if (!is_scalar($IMPP)) {
$properties["im"] = $IMPP['Value'];
}
}
}
if ($vCard -> ADR) {
foreach ($vCard -> ADR as $Address) {
if(in_array("work", $Address['Type'])) {
$properties["business_address_street"] = $Address['StreetAddress'];
$properties["business_address_city"] = $Address['Locality'];
$properties["business_address_state"] = $Address['Region'];
$properties["business_address_postal_code"] = $Address['PostalCode'];
$properties["business_address_country"] = $Address['Country'];
$properties["business_address"] = $this->buildAddressString($Address['StreetAddress'], $Address['PostalCode'], $Address['Locality'], $Address['Region'], $Address['Country']);
} else if(in_array("home", $Address['Type'])) {
$properties["home_address_street"] = $Address['StreetAddress'];
$properties["home_address_city"] = $Address['Locality'];
$properties["home_address_state"] = $Address['Region'];
$properties["home_address_postal_code"] = $Address['PostalCode'];
$properties["home_address_country"] = $Address['Country'];
$properties["home_address"] = $this->buildAddressString($Address['StreetAddress'], $Address['PostalCode'], $Address['Locality'], $Address['Region'], $Address['Country']);
} else if(in_array("postal", $Address['Type'])||in_array("parcel", $Address['Type'])||in_array("intl", $Address['Type'])||in_array("dom", $Address['Type'])) {
$properties["other_address_street"] = $Address['StreetAddress'];
$properties["other_address_city"] = $Address['Locality'];
$properties["other_address_state"] = $Address['Region'];
$properties["other_address_postal_code"] = $Address['PostalCode'];
$properties["other_address_country"] = $Address['Country'];
$properties["other_address"] = $this->buildAddressString($Address['StreetAddress'], $Address['PostalCode'], $Address['Locality'], $Address['Region'], $Address['Country']);
}
}
}
if ($vCard -> BDAY) {
$properties["birthday"] = strtotime($vCard -> BDAY[0]);
}
if ($vCard -> NOTE) {
$properties["notes"] = $vCard -> NOTE[0];
}
if ($vCard -> PHOTO) {
if (isset($vCard->rawPhoto) || isset($vCard->photo)) {
if(!is_writable(TMP_PATH . "/")) {
error_log("could not write to export tmp directory!: " . $E);
error_log("Can not write to export tmp directory!");
} else {
$tmppath = TMP_PATH . "/" . $this->randomstring(15);
try {
if($vCard -> SaveFile('photo', 0, $tmppath)) {
$properties["internal_fields"]["x_photo_path"] = $tmppath;
} else {
if($this->DEBUG) {
error_log("remote imagefetching not implemented");
}
if(isset($vCard->rawPhoto)) {
if(file_put_contents($tmppath, $vCard->rawPhoto)) {
$properties["internal_fields"]["x_photo_path"] = $tmppath;
}
} elseif(isset($vCard->photo)) {
if($this->startswith(strtolower($vCard->photo), "http://") || $this->startswith(strtolower($vCard->photo), "https://")) { // check if it starts with http
$ctx = stream_context_create(array('http'=>
array(
'timeout' => 3, //3 Seconds timout
)
));
if(file_put_contents($tmppath, file_get_contents($vCard->photo, false, $ctx))) {
$properties["internal_fields"]["x_photo_path"] = $tmppath;
}
} else {
error_log("Invalid photo url: " . $vCard->photo);
}
} catch (Exception $E) {
error_log("Image exception: " . $E);
}
}
}
@@ -815,6 +825,11 @@ class ContactModule extends Module {
$GLOBALS["bus"]->addData($this->getResponseData());
}
}
private function startswith($haystack, $needle) {
$haystack = str_replace("type=", "", $haystack); // remove type from string
return substr($haystack, 0, strlen($needle)) === $needle;
}
};
?>