From 24f2f5d974d11eb0d2a66cc2bef7c9c451b21001 Mon Sep 17 00:00:00 2001
From: Christoph Haas
Date: Mon, 24 Jun 2013 20:21:09 +0000
Subject: [PATCH] contactimporter:
v1.0: 24.6.2013
- import vcards (1 or more vcards in a file)
- chooseable destination addressbook
---
changelog.txt | 3 +
config.php | 4 +-
js/data/ResponseHandler.js | 30 +-
js/dialogs/ImportPanel.js | 107 ++---
php/download.php | 44 --
php/module.contact.php | 662 ++++++++++++++-------------
php/vcf/Herr test of master jun .vcf | 410 -----------------
php/vcf/test.php | 216 ---------
8 files changed, 382 insertions(+), 1094 deletions(-)
delete mode 100644 php/download.php
delete mode 100644 php/vcf/Herr test of master jun .vcf
delete mode 100644 php/vcf/test.php
diff --git a/changelog.txt b/changelog.txt
index e69de29..502e22f 100644
--- a/changelog.txt
+++ b/changelog.txt
@@ -0,0 +1,3 @@
+v1.0: 24.6.2013
+ - import vcards (1 or more vcards in a file)
+ - chooseable destination addressbook
\ No newline at end of file
diff --git a/config.php b/config.php
index 1804424..f8c526e 100644
--- a/config.php
+++ b/config.php
@@ -1,8 +1,8 @@
- * Copyright (C) 2012-2013 Christoph Haas
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-$basedir = $_GET["basedir"];
-$secid = $_GET["secid"];
-$fileid = $_GET["fileid"];
-$realname = $_GET["realname"];
-
-$secfile = $basedir . "/secid." . $secid;
-$vcffile = $basedir . "/" . $fileid . "." . $secid;
-
-// if the secid file exists -> download!
-if(file_exists($secfile)) {
- @header("Last-Modified: " . @gmdate("D, d M Y H:i:s",time()) . " GMT");
- @header("Content-type: text/vcard");
- header("Content-Length: " . filesize($vcffile));
- header("Content-Disposition: attachment; filename=" . $realname . ".vcf");
-
- //write vcf
- readfile($vcffile);
- unlink($secfile);
- unlink($vcffile);
-}
-
-?>
\ No newline at end of file
diff --git a/php/module.contact.php b/php/module.contact.php
index f408355..6802750 100644
--- a/php/module.contact.php
+++ b/php/module.contact.php
@@ -26,7 +26,7 @@ require_once('mapi/mapitags.php' );
class ContactModule extends Module {
- private $DEBUG = true; // enable error_log debugging
+ private $DEBUG = false; // enable error_log debugging
/**
* @constructor
@@ -57,18 +57,12 @@ class ContactModule extends Module {
error_log("exec: " . $actionType);
}
switch($actionType) {
- case "export":
- $result = $this->exportCalendar($actionType, $actionData);
+ case "load":
+ $result = $this->loadContacts($actionType, $actionData);
break;
case "import":
$result = $this->importContacts($actionType, $actionData);
break;
- case "addattachment":
- $result = $this->addAttachment($actionType, $actionData);
- break;
- case "attachmentpath":
- $result = $this->getAttachmentPath($actionType, $actionData);
- break;
default:
$this->handleUnknownActionType($actionType);
}
@@ -109,219 +103,375 @@ class ContactModule extends Module {
return $pass;
}
- /**
- * Generates the secid file (used to verify the download path)
- * @param $secid the secid, a random security token
- */
- private function createSecIDFile($secid) {
- $lockFile = TMP_PATH . "/secid." . $secid;
- $fh = fopen($lockFile, 'w') or die("can't open secid file");
- $stringData = date(DATE_RFC822);
- fwrite($fh, $stringData);
- fclose($fh);
- }
-
- /**
- * Generates the secid file (used to verify the download path)
- * @param $time a timestamp
- * @param $incl_time true if date should include time
- * @ return date object
- */
- private function getIcalDate($time, $incl_time = true) {
- return $incl_time ? date('Ymd\THis', $time) : date('Ymd', $time);
- }
-
/**
* Add an attachment to the give contact
* @param $actionType
* @param $actionData
*/
- private function addAttachment($actionType, $actionData) {
+ private function importContacts($actionType, $actionData) {
+
+ // Get uploaded vcf path
+ $vcffile = false;
+ if(isset($actionData["vcf_filepath"])) {
+ $vcffile = $actionData["vcf_filepath"];
+ }
-
-
// Get store id
$storeid = false;
if(isset($actionData["storeid"])) {
$storeid = $actionData["storeid"];
}
-
- // Get message entryid
- $entryid = false;
- if(isset($actionData["entryid"])) {
- $entryid = $actionData["entryid"];
+
+ // Get folder entryid
+ $folderid = false;
+ if(isset($actionData["folderid"])) {
+ $folderid = $actionData["folderid"];
}
- $tmpimage = $actionData["tmpfile"];
- $contactPicture = file_get_contents ($tmpimage);
+ // Get uids
+ $uids = array();
+ if(isset($actionData["uids"])) {
+ $uids = $actionData["uids"];
+ }
- error_log($tmpdata);
+ $response = array();
+ $error = false;
+ $error_msg = "";
-
- error_log("opening store");
- $store = $GLOBALS["mapisession"]->openMessageStore(hex2bin($storeid));
-
- error_log("opening message");
- // Open a message from the store
+ // parse the vcf file a last time...
try {
- $message = mapi_msgstore_openentry($store, hex2bin($entryid));
- } catch (MAPIException $e) {
- $e->setHandled();
- error_log($e->getCode());
- error_log(mapi_last_hresult());
- }
+ $vcard = new vCard($vcffile, false, array('Collapse' => false)); // Parse it!
+ } catch (Exception $e) {
+ $error = true;
+ $error_msg = $e->getMessage();
+ }
- error_log("opening attachment");
- // Open attachment number 0
- $attach = mapi_message_createattach($message);
+ $contacts = array();
- // Set properties of the attachment
- $properties = array(
- //PR_ATTACH_SIZE => strlen($contactPicture),
- PR_ATTACH_LONG_FILENAME => 'ContactPicture.jpg',
- PR_ATTACHMENT_HIDDEN => false,
- PR_DISPLAY_NAME => 'ContactPicture.jpg',
- PR_ATTACH_METHOD => ATTACH_BY_VALUE,
- PR_ATTACH_MIME_TAG => 'image/jpeg',
- PR_ATTACHMENT_CONTACTPHOTO => true,
- PR_ATTACH_DATA_BIN => "",
- PR_ATTACHMENT_FLAGS => 1,
- PR_ATTACH_EXTENSION_A => '.jpg',
- PR_ATTACH_NUM => 1
- );
+ if(!$error && count($vcard) > 0) {
+ $vCard = $vcard;
+ if (count($vCard) == 1) {
+ $vCard = array($vcard);
+ }
+
+ $contacts = $this->parseContactsToArray($vCard);
+ $store = $GLOBALS["mapisession"]->openMessageStore(hex2bin($storeid));
+ $folder = mapi_msgstore_openentry($store, hex2bin($folderid));
+
+ $importall = false;
+ if(count($uids) == count($contacts)) {
+ $importall = true;
+ }
+
+ $propValuesMAPI = array();
+ $properties = $this->getProperties();
+ $properties = $this->replaceStringPropertyTags($store, $properties);
+ $count = 0;
+
+ // iterate through all contacts and import them :)
+ 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...
+ foreach($contact as $key => $value) {
+ if($key !== "internal_fields") {
+ $propValuesMAPI[$properties[$key]] = $value;
+ }
+ }
+
+ $propValuesMAPI[$properties["message_class"]] = "IPM.Contact";
+ $propValuesMAPI[$properties["icon_index"]] = "512";
+ $message = mapi_folder_createmessage($folder);
+
+
+ if(isset($contact["internal_fields"]["x_photo_path"])) {
+ $propValuesMAPI[$properties["picture"]] = 1; // contact has an image
- error_log("setting props");
- mapi_setprops($attach, $properties);
+ // import the photo
+ $contactPicture = file_get_contents($contact["internal_fields"]["x_photo_path"]);
+ $attach = mapi_message_createattach($message);
- // Stream the file to the PR_ATTACH_DATA_BIN property
- error_log("streaming file");
- $stream = mapi_openproperty($attach, PR_ATTACH_DATA_BIN, IID_IStream, 0, MAPI_CREATE | MAPI_MODIFY);
- $handle = fopen($tmpimage, "r");
- while (!feof($handle)) {
- $contents = fread($handle, BLOCK_SIZE);
- mapi_stream_write($stream, $contents);
- }
-
- // Commit the stream and save changes
- mapi_stream_commit($stream);
-
- error_log("saving attachment");
- mapi_savechanges($attach);
-
- if (mapi_last_hresult() > 0) {
- error_log("Error saving attach to contact: " . get_mapi_error_name());
- }
-
- error_log("saving message");
- mapi_savechanges($message);
-
- if (mapi_last_hresult() > 0) {
- error_log("Error saving contact: " . get_mapi_error_name());
- }
-
- // Open attachment number 0
- error_log("final tests attachment");
- $testattach = mapi_message_openattach ($message, 0);
- error_log(print_r(mapi_attach_getprops($testattach),true));
+ // Set properties of the attachment
+ $propValuesIMG = array(
+ PR_ATTACH_SIZE => strlen($contactPicture),
+ PR_ATTACH_LONG_FILENAME => 'ContactPicture.jpg',
+ PR_ATTACHMENT_HIDDEN => false,
+ PR_DISPLAY_NAME => 'ContactPicture.jpg',
+ PR_ATTACH_METHOD => ATTACH_BY_VALUE,
+ PR_ATTACH_MIME_TAG => 'image/jpeg',
+ PR_ATTACHMENT_CONTACTPHOTO => true,
+ PR_ATTACH_DATA_BIN => $contactPicture,
+ PR_ATTACHMENT_FLAGS => 1,
+ PR_ATTACH_EXTENSION_A => '.jpg',
+ PR_ATTACH_NUM => 1
+ );
+
+ mapi_setprops($attach, $propValuesIMG);
+ mapi_savechanges($attach);
+ if($this->DEBUG) {
+ error_log("Contactpicture imported!");
+ }
+
+ if (mapi_last_hresult() > 0) {
+ error_log("Error saving attach to contact: " . get_mapi_error_name());
+ }
+ }
+
+ mapi_setprops($message, $propValuesMAPI);
+ mapi_savechanges($message);
+ if($this->DEBUG) {
+ error_log("New contact added: \"" . $propValuesMAPI[$properties["display_name"]] . "\".\n");
+ }
+ $count++;
+ }
+ }
-
- $response['status'] = true;
- $response['storeid'] = $storeid;
- $response['entryid'] = $entryid;
+ $response['status'] = true;
+ $response['count'] = $count;
+ $response['message'] = "";
+
+ } else {
+ $response['status'] = false;
+ $response['count'] = 0;
+ $response['message'] = $error ? $error_msg : "VCF file empty!";
+ }
$this->addActionData($actionType, $response);
$GLOBALS["bus"]->addData($this->getResponseData());
}
+
+ private function replaceStringPropertyTags($store, $properties) {
+ $newProperties = array();
- /**
- * The main export function, creates the ics file for download
- * @param $actionType
- * @param $actionData
- */
- private function exportContacts($actionType, $actionData) {
- $secid = $this->randomstring();
- $this->createSecIDFile($secid);
- $tmpname = stripslashes($actionData["calendar"] . ".ics." . $this->randomstring(8));
- $filename = TMP_PATH . "/" . $tmpname . "." . $secid;
-
- if(!is_writable(TMP_PATH . "/")) {
- error_log("could not write to export tmp directory!");
- }
-
- $tz = date("e"); // use php timezone (maybe set up in php.ini, date.timezone)
-
- if($this->DEBUG) {
- error_log("PHP Timezone: " . $tz);
- }
-
- $config = array(
- "language" => substr($GLOBALS["settings"]->get("zarafa/v1/main/language"),0,2),
- "directory" => TMP_PATH . "/",
- "filename" => $tmpname . "." . $secid,
- "unique_id" => "zarafa-export-plugin",
- "TZID" => $tz
- );
-
- $v = new vcalendar($config);
- $v->setProperty("method", "PUBLISH"); // required of some calendar software
- $v->setProperty("x-wr-calname", $actionData["calendar"]); // required of some calendar software
- $v->setProperty("X-WR-CALDESC", "Exported Zarafa Calendar"); // required of some calendar software
- $v->setProperty("X-WR-TIMEZONE", $tz);
+ $ids = array("name"=>array(), "id"=>array(), "guid"=>array(), "type"=>array()); // this array stores all the information needed to retrieve a named property
+ $num = 0;
- $xprops = array("X-LIC-LOCATION" => $tz); // required of some calendar software
- iCalUtilityFunctions::createTimezone($v, $tz, $xprops); // create timezone object in calendar
-
-
- foreach($actionData["data"] as $event) {
- $event["props"]["description"] = $this->loadEventDescription($event);
- $event["props"]["attendees"] = $this->loadAttendees($event);
-
- $vevent = & $v->newComponent("vevent"); // create a new event object
- $this->addEvent($vevent, $event["props"]);
+ // caching
+ $guids = array();
+
+ foreach($properties as $name => $val) {
+ if(is_string($val)) {
+ $split = explode(":", $val);
+
+ if(count($split) != 3) { // invalid string, ignore
+ trigger_error(sprintf("Invalid property: %s \"%s\"",$name,$val), E_USER_NOTICE);
+ continue;
+ }
+
+ if(substr($split[2], 0, 2) == "0x") {
+ $id = hexdec(substr($split[2], 2));
+ } else {
+ $id = $split[2];
+ }
+
+ // have we used this guid before?
+ if (!defined($split[1])) {
+ if (!array_key_exists($split[1], $guids)) {
+ $guids[$split[1]] = makeguid($split[1]);
+ }
+ $guid = $guids[$split[1]];
+ } else {
+ $guid = constant($split[1]);
+ }
+
+ // temp store info about named prop, so we have to call mapi_getidsfromnames just one time
+ $ids["name"][$num] = $name;
+ $ids["id"][$num] = $id;
+ $ids["guid"][$num] = $guid;
+ $ids["type"][$num] = $split[0];
+ $num++;
+ } else {
+ // not a named property
+ $newProperties[$name] = $val;
+ }
}
-
- $v->saveCalendar();
-
- $response['status'] = true;
- $response['fileid'] = $tmpname; // number of entries that will be exported
- $response['basedir'] = TMP_PATH;
- $response['secid'] = $secid;
- $response['realname'] = $actionData["calendar"];
- $this->addActionData($actionType, $response);
- $GLOBALS["bus"]->addData($this->getResponseData());
-
- if($this->DEBUG) {
- error_log("export done, bus data written!");
+
+ if (count($ids["id"]) == 0) {
+ return $newProperties;
}
+
+ // get the ids
+ $named = mapi_getidsfromnames($store, $ids["id"], $ids["guid"]);
+ foreach($named as $num => $prop) {
+ $newProperties[$ids["name"][$num]] = mapi_prop_tag(constant($ids["type"][$num]), mapi_prop_id($prop));
+ }
+
+ return $newProperties;
}
/**
- * The main import function, parses the uploaded vcf file
+ * A simple Property map initialization
+ *
+ * @return [array] the propertyarray
+ */
+ private function getProperties() {
+ $properties = array();
+
+ $properties["subject"] = PR_SUBJECT;
+ $properties["icon_index"] = PR_ICON_INDEX;
+ $properties["message_class"] = PR_MESSAGE_CLASS;
+ $properties["display_name"] = PR_DISPLAY_NAME;
+ $properties["given_name"] = PR_GIVEN_NAME;
+ $properties["middle_name"] = PR_MIDDLE_NAME;
+ $properties["surname"] = PR_SURNAME;
+ $properties["home_telephone_number"] = PR_HOME_TELEPHONE_NUMBER;
+ $properties["cellular_telephone_number"] = PR_CELLULAR_TELEPHONE_NUMBER;
+ $properties["office_telephone_number"] = PR_OFFICE_TELEPHONE_NUMBER;
+ $properties["business_fax_number"] = PR_BUSINESS_FAX_NUMBER;
+ $properties["company_name"] = PR_COMPANY_NAME;
+ $properties["title"] = PR_TITLE;
+ $properties["department_name"] = PR_DEPARTMENT_NAME;
+ $properties["office_location"] = PR_OFFICE_LOCATION;
+ $properties["profession"] = PR_PROFESSION;
+ $properties["manager_name"] = PR_MANAGER_NAME;
+ $properties["assistant"] = PR_ASSISTANT;
+ $properties["nickname"] = PR_NICKNAME;
+ $properties["display_name_prefix"] = PR_DISPLAY_NAME_PREFIX;
+ $properties["spouse_name"] = PR_SPOUSE_NAME;
+ $properties["generation"] = PR_GENERATION;
+ $properties["birthday"] = PR_BIRTHDAY;
+ $properties["wedding_anniversary"] = PR_WEDDING_ANNIVERSARY;
+ $properties["sensitivity"] = PR_SENSITIVITY;
+ $properties["fileas"] = "PT_STRING8:PSETID_Address:0x8005";
+ $properties["fileas_selection"] = "PT_LONG:PSETID_Address:0x8006";
+ $properties["email_address_1"] = "PT_STRING8:PSETID_Address:0x8083";
+ $properties["email_address_display_name_1"] = "PT_STRING8:PSETID_Address:0x8080";
+ $properties["email_address_display_name_email_1"] = "PT_STRING8:PSETID_Address:0x8084";
+ $properties["email_address_type_1"] = "PT_STRING8:PSETID_Address:0x8082";
+ $properties["email_address_2"] = "PT_STRING8:PSETID_Address:0x8093";
+ $properties["email_address_display_name_2"] = "PT_STRING8:PSETID_Address:0x8090";
+ $properties["email_address_display_name_email_2"] = "PT_STRING8:PSETID_Address:0x8094";
+ $properties["email_address_type_2"] = "PT_STRING8:PSETID_Address:0x8092";
+ $properties["email_address_3"] = "PT_STRING8:PSETID_Address:0x80a3";
+ $properties["email_address_display_name_3"] = "PT_STRING8:PSETID_Address:0x80a0";
+ $properties["email_address_display_name_email_3"] = "PT_STRING8:PSETID_Address:0x80a4";
+ $properties["email_address_type_3"] = "PT_STRING8:PSETID_Address:0x80a2";
+ $properties["home_address"] = "PT_STRING8:PSETID_Address:0x801a";
+ $properties["business_address"] = "PT_STRING8:PSETID_Address:0x801b";
+ $properties["other_address"] = "PT_STRING8:PSETID_Address:0x801c";
+ $properties["mailing_address"] = "PT_LONG:PSETID_Address:0x8022";
+ $properties["im"] = "PT_STRING8:PSETID_Address:0x8062";
+ $properties["webpage"] = "PT_STRING8:PSETID_Address:0x802b";
+ $properties["business_home_page"] = PR_BUSINESS_HOME_PAGE;
+ $properties["email_address_entryid_1"] = "PT_BINARY:PSETID_Address:0x8085";
+ $properties["email_address_entryid_2"] = "PT_BINARY:PSETID_Address:0x8095";
+ $properties["email_address_entryid_3"] = "PT_BINARY:PSETID_Address:0x80a5";
+ $properties["address_book_mv"] = "PT_MV_LONG:PSETID_Address:0x8028";
+ $properties["address_book_long"] = "PT_LONG:PSETID_Address:0x8029";
+ $properties["oneoff_members"] = "PT_MV_BINARY:PSETID_Address:0x8054";
+ $properties["members"] = "PT_MV_BINARY:PSETID_Address:0x8055";
+ $properties["private"] = "PT_BOOLEAN:PSETID_Common:0x8506";
+ $properties["contacts"] = "PT_MV_STRING8:PSETID_Common:0x853a";
+ $properties["contacts_string"] = "PT_STRING8:PSETID_Common:0x8586";
+ $properties["categories"] = "PT_MV_STRING8:PS_PUBLIC_STRINGS:Keywords";
+ $properties["last_modification_time"] = PR_LAST_MODIFICATION_TIME;
+
+ // Detailed contacts properties
+ // Properties for phone numbers
+ $properties["assistant_telephone_number"] = PR_ASSISTANT_TELEPHONE_NUMBER;
+ $properties["business2_telephone_number"] = PR_BUSINESS2_TELEPHONE_NUMBER;
+ $properties["callback_telephone_number"] = PR_CALLBACK_TELEPHONE_NUMBER;
+ $properties["car_telephone_number"] = PR_CAR_TELEPHONE_NUMBER;
+ $properties["company_telephone_number"] = PR_COMPANY_MAIN_PHONE_NUMBER;
+ $properties["home2_telephone_number"] = PR_HOME2_TELEPHONE_NUMBER;
+ $properties["home_fax_number"] = PR_HOME_FAX_NUMBER;
+ $properties["isdn_number"] = PR_ISDN_NUMBER;
+ $properties["other_telephone_number"] = PR_OTHER_TELEPHONE_NUMBER;
+ $properties["pager_telephone_number"] = PR_PAGER_TELEPHONE_NUMBER;
+ $properties["primary_fax_number"] = PR_PRIMARY_FAX_NUMBER;
+ $properties["primary_telephone_number"] = PR_PRIMARY_TELEPHONE_NUMBER;
+ $properties["radio_telephone_number"] = PR_RADIO_TELEPHONE_NUMBER;
+ $properties["telex_telephone_number"] = PR_TELEX_NUMBER;
+ $properties["ttytdd_telephone_number"] = PR_TTYTDD_PHONE_NUMBER;
+ $properties["business_telephone_number"] =PR_BUSINESS_TELEPHONE_NUMBER;
+
+ // Additional fax properties
+ $properties["fax_1_address_type"] = "PT_STRING8:PSETID_Address:0x80B2";
+ $properties["fax_1_email_address"] = "PT_STRING8:PSETID_Address:0x80B3";
+ $properties["fax_1_original_display_name"] = "PT_STRING8:PSETID_Address:0x80B4";
+ $properties["fax_1_original_entryid"] = "PT_BINARY:PSETID_Address:0x80B5";
+ $properties["fax_2_address_type"] = "PT_STRING8:PSETID_Address:0x80C2";
+ $properties["fax_2_email_address"] = "PT_STRING8:PSETID_Address:0x80C3";
+ $properties["fax_2_original_display_name"] = "PT_STRING8:PSETID_Address:0x80C4";
+ $properties["fax_2_original_entryid"] = "PT_BINARY:PSETID_Address:0x80C5";
+ $properties["fax_3_address_type"] = "PT_STRING8:PSETID_Address:0x80D2";
+ $properties["fax_3_email_address"] = "PT_STRING8:PSETID_Address:0x80D3";
+ $properties["fax_3_original_display_name"] = "PT_STRING8:PSETID_Address:0x80D4";
+ $properties["fax_3_original_entryid"] = "PT_BINARY:PSETID_Address:0x80D5";
+
+ // Properties for addresses
+ // Home address
+ $properties["home_address_street"] = PR_HOME_ADDRESS_STREET;
+ $properties["home_address_city"] = PR_HOME_ADDRESS_CITY;
+ $properties["home_address_state"] = PR_HOME_ADDRESS_STATE_OR_PROVINCE;
+ $properties["home_address_postal_code"] = PR_HOME_ADDRESS_POSTAL_CODE;
+ $properties["home_address_country"] = PR_HOME_ADDRESS_COUNTRY;
+ // Other address
+ $properties["other_address_street"] = PR_OTHER_ADDRESS_STREET;
+ $properties["other_address_city"] = PR_OTHER_ADDRESS_CITY;
+ $properties["other_address_state"] = PR_OTHER_ADDRESS_STATE_OR_PROVINCE;
+ $properties["other_address_postal_code"] = PR_OTHER_ADDRESS_POSTAL_CODE;
+ $properties["other_address_country"] = PR_OTHER_ADDRESS_COUNTRY;
+ // Business address
+ $properties["business_address_street"] = "PT_STRING8:PSETID_Address:0x8045";
+ $properties["business_address_city"] = "PT_STRING8:PSETID_Address:0x8046";
+ $properties["business_address_state"] = "PT_STRING8:PSETID_Address:0x8047";
+ $properties["business_address_postal_code"] = "PT_STRING8:PSETID_Address:0x8048";
+ $properties["business_address_country"] = "PT_STRING8:PSETID_Address:0x8049";
+ // Mailing address
+ $properties["country"] = PR_COUNTRY;
+ $properties["city"] = PR_LOCALITY;
+ $properties["postal_address"] = PR_POSTAL_ADDRESS;
+ $properties["postal_code"] = PR_POSTAL_CODE;
+ $properties["state"] = PR_STATE_OR_PROVINCE;
+ $properties["street"] = PR_STREET_ADDRESS;
+ // Special Date such as birthday n anniversary appoitment's entryid is store
+ $properties["birthday_eventid"] = "PT_BINARY:PSETID_Address:0x804D";
+ $properties["anniversary_eventid"] = "PT_BINARY:PSETID_Address:0x804E";
+
+ $properties["notes"] = PR_BODY;
+
+ // hasimage
+ $properties["picture"] = "PT_BOOLEAN:{00062004-0000-0000-C000-000000000046}:0x8015";
+
+ return $properties;
+ }
+
+ /**
+ * Function that parses the uploaded vcf file and posts it via json
* @param $actionType
* @param $actionData
*/
- private function importContacts($actionType, $actionData) {
- if($this->DEBUG) {
- error_log("PHP Timezone: " . $tz);
- }
+ private function loadContacts($actionType, $actionData) {
+ $error = false;
+ $error_msg = "";
if(is_readable ($actionData["vcf_filepath"])) {
- $vcard = new vCard($actionData["vcf_filepath"], false, array('Collapse' => false)); // Parse it!
- error_log(print_r($vcard, true));
- if(count($vcard) == 0) {
+ try {
+ $vcard = new vCard($actionData["vcf_filepath"], false, array('Collapse' => false)); // Parse it!
+ } catch (Exception $e) {
+ $error = true;
+ $error_msg = $e->getMessage();
+ }
+ if($error) {
$response['status'] = false;
- $response['message']= "No contacts in vcf file";
+ $response['message']= $error_msg;
} else {
- $vCard = $vcard;
- if (count($vCard) == 1) {
- $vCard = array($vcard);
+ if(count($vcard) == 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)
+ );
}
-
- $response['status'] = true;
- $response['parsed_file']= $actionData["vcf_filepath"];
- $response['parsed'] = array (
- 'contacts' => $this->parseContactsToArray($vCard)
- );
}
} else {
$response['status'] = false;
@@ -346,12 +496,17 @@ class ContactModule extends Module {
*/
private function parseContactsToArray($contacts, $csv = false) {
$carr = array();
+
if(!$csv) {
foreach ($contacts as $Index => $vCard) {
$properties = array();
$properties["display_name"] = $vCard -> FN[0];
$properties["fileas"] = $vCard -> FN[0];
+ //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'];
@@ -461,7 +616,7 @@ class ContactModule extends Module {
$properties["birthday"] = strtotime($vCard -> BDAY[0]);
}
if ($vCard -> NOTE) {
- $properties["body"] = $vCard -> NOTE[0];
+ $properties["notes"] = $vCard -> NOTE[0];
}
if ($vCard -> PHOTO) {
if(!is_writable(TMP_PATH . "/")) {
@@ -470,7 +625,7 @@ class ContactModule extends Module {
$tmppath = TMP_PATH . "/" . $this->randomstring(15);
try {
if($vCard -> SaveFile('photo', 0, $tmppath)) {
- $properties["x_photo_path"] = $tmppath;
+ $properties["internal_fields"]["x_photo_path"] = $tmppath;
} else {
if($this->DEBUG) {
error_log("remote imagefetching not implemented");
@@ -516,145 +671,6 @@ class ContactModule extends Module {
return $out;
}
-
- /**
- * Store the file to a temporary directory, prepare it for oc upload
- * @param $actionType
- * @param $actionData
- * @private
- */
- private function getAttachmentPath($actionType, $actionData) {
- // Get store id
- $storeid = false;
- if(isset($actionData["store"])) {
- $storeid = $actionData["store"];
- }
-
- // Get message entryid
- $entryid = false;
- if(isset($actionData["entryid"])) {
- $entryid = $actionData["entryid"];
- }
-
- // Check which type isset
- $openType = "attachment";
-
- // Get number of attachment which should be opened.
- $attachNum = false;
- if(isset($actionData["attachNum"])) {
- $attachNum = $actionData["attachNum"];
- }
-
- // Check if storeid and entryid isset
- if($storeid && $entryid) {
- // Open the store
- $store = $GLOBALS["mapisession"]->openMessageStore(hex2bin($storeid));
-
- if($store) {
- // Open the message
- $message = mapi_msgstore_openentry($store, hex2bin($entryid));
-
- if($message) {
- $attachment = false;
-
- // Check if attachNum isset
- if($attachNum) {
- // Loop through the attachNums, message in message in message ...
- for($i = 0; $i < (count($attachNum) - 1); $i++)
- {
- // Open the attachment
- $tempattach = mapi_message_openattach($message, (int) $attachNum[$i]);
- if($tempattach) {
- // Open the object in the attachment
- $message = mapi_attach_openobj($tempattach);
- }
- }
-
- // Open the attachment
- $attachment = mapi_message_openattach($message, (int) $attachNum[(count($attachNum) - 1)]);
- }
-
- // Check if the attachment is opened
- if($attachment) {
-
- // Get the props of the attachment
- $props = mapi_attach_getprops($attachment, array(PR_ATTACH_LONG_FILENAME, PR_ATTACH_MIME_TAG, PR_DISPLAY_NAME, PR_ATTACH_METHOD));
- // Content Type
- $contentType = "application/octet-stream";
- // Filename
- $filename = "ERROR";
-
- // Set filename
- if(isset($props[PR_ATTACH_LONG_FILENAME])) {
- $filename = $props[PR_ATTACH_LONG_FILENAME];
- } else if(isset($props[PR_ATTACH_FILENAME])) {
- $filename = $props[PR_ATTACH_FILENAME];
- } else if(isset($props[PR_DISPLAY_NAME])) {
- $filename = $props[PR_DISPLAY_NAME];
- }
-
- // Set content type
- if(isset($props[PR_ATTACH_MIME_TAG])) {
- $contentType = $props[PR_ATTACH_MIME_TAG];
- } else {
- // Parse the extension of the filename to get the content type
- if(strrpos($filename, ".") !== false) {
- $extension = strtolower(substr($filename, strrpos($filename, ".")));
- $contentType = "application/octet-stream";
- if (is_readable("mimetypes.dat")){
- $fh = fopen("mimetypes.dat","r");
- $ext_found = false;
- while (!feof($fh) && !$ext_found){
- $line = fgets($fh);
- preg_match("/(\.[a-z0-9]+)[ \t]+([^ \t\n\r]*)/i", $line, $result);
- if ($extension == $result[1]){
- $ext_found = true;
- $contentType = $result[2];
- }
- }
- fclose($fh);
- }
- }
- }
-
-
- $tmpname = tempnam(TMP_PATH, stripslashes($filename));
-
- // Open a stream to get the attachment data
- $stream = mapi_openpropertytostream($attachment, PR_ATTACH_DATA_BIN);
- $stat = mapi_stream_stat($stream);
- // File length = $stat["cb"]
-
- $fhandle = fopen($tmpname,'w');
- $buffer = null;
- for($i = 0; $i < $stat["cb"]; $i += BLOCK_SIZE) {
- // Write stream
- $buffer = mapi_stream_read($stream, BLOCK_SIZE);
- fwrite($fhandle,$buffer,strlen($buffer));
- }
- fclose($fhandle);
-
- $response = array();
- $response['tmpname'] = $tmpname;
- $response['filename'] = $filename;
- $response['status'] = true;
- $this->addActionData($actionType, $response);
- $GLOBALS["bus"]->addData($this->getResponseData());
- }
- }
- } else {
- $response['status'] = false;
- $response['message'] = "Store could not be opened!";
- $this->addActionData($actionType, $response);
- $GLOBALS["bus"]->addData($this->getResponseData());
- }
- } else {
- $response['status'] = false;
- $response['message'] = "Wrong call, store and entryid have to be set!";
- $this->addActionData($actionType, $response);
- $GLOBALS["bus"]->addData($this->getResponseData());
- }
- }
};
?>
diff --git a/php/vcf/Herr test of master jun .vcf b/php/vcf/Herr test of master jun .vcf
deleted file mode 100644
index 7b31eb7..0000000
--- a/php/vcf/Herr test of master jun .vcf
+++ /dev/null
@@ -1,410 +0,0 @@
-BEGIN:VCARD
-VERSION:2.1
-N;LANGUAGE=de:master;test;of;Herr;jun.
-FN:Herr test of master jun.
-ORG:testcomp;Abteilung X
-TITLE:chef
-TEL;WORK;VOICE:123456
-TEL;HOME;VOICE:234567
-TEL;CELL;VOICE:456789
-ADR;WORK:;;test 1;entenh;tirol;789;Albanien
-LABEL;WORK;ENCODING=QUOTED-PRINTABLE:test 1=0D=0A=
-789 entenh tirol=0D=0A=
-Albanien
-ADR;HOME;PREF:;;priv 2;sepplh;vorarlberg;213;Anguilla
-LABEL;HOME;PREF;ENCODING=QUOTED-PRINTABLE:priv 2=0D=0A=
-213 sepplh vorarlberg=0D=0A=
-Anguilla
-ADR;POSTAL:;;other 4;saadsf;addsag;5649;Brasilien
-LABEL;POSTAL;ENCODING=QUOTED-PRINTABLE:other 4=0D=0A=
-saadsf - addsag=0D=0A=
-Brasilien=0D=0A=
-5649
-X-MS-OL-DEFAULT-POSTAL-ADDRESS:1
-URL;WORK:www.google.at
-EMAIL;PREF;INTERNET:email1@at.e
-EMAIL;INTERNET:email2@at.e
-EMAIL;INTERNET:email3@at.e
-PHOTO;TYPE=JPEG;ENCODING=BASE64:
- /9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgK
- CgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/2wBDAQMDAwQDBAgEBAgQCwkL
- EBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBD/wAAR
- CAE6AToDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAA
- AgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkK
- FhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWG
- h4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl
- 5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREA
- AgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYk
- NOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOE
- hYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk
- 5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD5+m0rBwBg5qhNp8yngj8K799K3jOBz2xV
- ebQXc5VP0r4eNdLc/G5Ybm1Rwf2aVRhlPFKIWxgiu0bw+2eV5+lVrjQnTlV/KtFWTOaWHlA5
- B4yjHAqPOOtdFNosgPKVRudMZAcjH4Vqqi2OZp31Mrfk4FOVsMM1K8BVsY/CnR2rEZOarmQJ
- DlQhQ2epweKejBRjNPCAIBxSbCQcHPNDYcutkTW7ljsJrTgwQD6Gs22jKt05rYs7dnAIH4VE
- pFKnIfGApyo61ZRnByD+VTR2DZyVxmriWJYYIrmlNdTojSdhdPZtwLN7DntXfaDMgRZHbqAO
- tcNFbtGQMVv6TdtEQrNgVz1LNaHTh3KnO7PUdFlimY8jriunhhBQYPavMNI1lopwsbcZrvLL
- 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
- XX3YBDZA71mlVz90flVRbQToxZ//2Q==
-
-X-MS-OL-DESIGN;CHARSET=utf-8:Geschäftlich Mobiltelefon Privat
-REV:20130520T141721Z
-END:VCARD
diff --git a/php/vcf/test.php b/php/vcf/test.php
deleted file mode 100644
index ecc8737..0000000
--- a/php/vcf/test.php
+++ /dev/null
@@ -1,216 +0,0 @@
-
-
-
-
-
-
-
-
-'.$vCard -> FN[0].'';
-
- if ($vCard -> PHOTO)
- {
- foreach ($vCard -> PHOTO as $Photo)
- {
- if ($Photo['Encoding'] == 'b')
- {
- echo ' ';
- }
- else
- {
- echo ' ';
- }
-
- /*
- // It can also be saved to a file
- try
- {
- $vCard -> SaveFile('photo', 0, 'test_image.jpg');
- // The parameters are:
- // - name of the file we want to save (photo, logo or sound)
- // - index of the file in case of multiple files (defaults to 0)
- // - target path to save to, including the filenam
- }
- catch (Exception $E)
- {
- // Target path not writable
- }
- */
- }
- }
-
- foreach ($vCard -> N as $Name)
- {
- echo 'Name: '.$Name['FirstName'].' '.$Name['LastName'].' ';
- }
-
- foreach ($vCard -> ORG as $Organization)
- {
- echo 'Organization: '.$Organization['Name'].
- ($Organization['Unit1'] || $Organization['Unit2'] ?
- ' ('.implode(', ', array($Organization['Unit1'], $Organization['Unit2'])).')' :
- ''
- ).' ';
- }
-
- if ($vCard -> TEL)
- {
- echo '
Phone ';
- foreach ($vCard -> TEL as $Tel)
- {
- if (is_scalar($Tel))
- {
- echo $Tel.' ';
- }
- else
- {
- echo $Tel['Value'].' ('.implode(', ', $Tel['Type']).') ';
- }
- }
- echo '
';
- }
-
- if ($vCard -> EMAIL)
- {
- echo '
Email ';
- foreach ($vCard -> EMAIL as $Email)
- {
- if (is_scalar($Email))
- {
- echo $Email;
- }
- else
- {
- echo $Email['Value'].' ('.implode(', ', $Email['Type']).') ';
- }
- }
- echo '';
- }
-
- if ($vCard -> URL)
- {
- echo '
URL ';
- foreach ($vCard -> URL as $URL)
- {
- if (is_scalar($URL))
- {
- echo $URL.' ';
- }
- else
- {
- echo $URL['Value'].' ';
- }
- }
- echo '';
- }
-
- if ($vCard -> IMPP)
- {
- echo '
Instant messaging ';
- foreach ($vCard -> IMPP as $IMPP)
- {
- if (is_scalar($IMPP))
- {
- echo $IMPP.' ';
- }
- else
- {
- echo $IMPP['Value'].' ';
- }
- }
- echo '';
- }
-
- if ($vCard -> ADR)
- {
- foreach ($vCard -> ADR as $Address)
- {
- echo '
Address ('.implode(', ', $Address['Type']).') ';
- echo 'Street address: '.($Address['StreetAddress'] ? $Address['StreetAddress'] : '-').' '.
- 'PO Box: '.($Address['POBox'] ? $Address['POBox'] : '-').' '.
- 'Extended address: '.($Address['ExtendedAddress'] ? $Address['ExtendedAddress'] : '-').' '.
- 'Locality: '.($Address['Locality'] ? $Address['Locality'] : '-').' '.
- 'Region: '.($Address['Region'] ? $Address['Region'] : '-').' '.
- 'ZIP/Post code: '.($Address['PostalCode'] ? $Address['PostalCode'] : '-').' '.
- 'Country: '.($Address['Country'] ? $Address['Country'] : '-').' ';
- }
- echo '';
- }
-
- if ($vCard -> AGENT)
- {
- echo 'Agents ';
- foreach ($vCard -> AGENT as $Agent)
- {
- if (is_scalar($Agent))
- {
- echo ''.$Agent.'
';
- }
- elseif (is_a($Agent, 'vCard'))
- {
- echo '';
- OutputvCard($Agent);
- echo '
';
- }
- }
- }
- }
-
- $vCard = new vCard(
- 'test.vcf', // Path to vCard file
- false, // Raw vCard text, can be used instead of a file
- array( // Option array
- // This lets you get single values for elements that could contain multiple values but have only one value.
- // This defaults to false so every value that could have multiple values is returned as array.
- 'Collapse' => false
- )
- );
-
- if (count($vCard) == 0)
- {
- throw new Exception('vCard test: empty vCard!');
- }
- // if the file contains a single vCard, it is accessible directly.
- elseif (count($vCard) == 1)
- {
- OutputvCard($vCard);
- }
- // if the file contains multiple vCards, they are accessible as elements of an array
- else
- {
- foreach ($vCard as $Index => $vCardPart)
- {
- OutputvCard($vCardPart);
- }
- }
-?>
-
-
\ No newline at end of file