- fixed all day eventsvcf importer pre alpha. Import working but contact pictures are not saved. TODO: rewrite import functionality in php
		
			
				
	
	
		
			661 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			661 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php	
 | |
| /**
 | |
|  * class.calendar.php, zarafa contact to vcf im/exporter
 | |
|  *
 | |
|  * Author: Christoph Haas <christoph.h@sprinternet.at>
 | |
|  * 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
 | |
|  *
 | |
|  */
 | |
|  
 | |
| include_once('vcf/class.vCard.php');
 | |
| require_once('mapi/mapitags.php' );
 | |
|  
 | |
| class ContactModule extends Module {
 | |
| 
 | |
| 	private $DEBUG = true; 	// enable error_log debugging
 | |
| 
 | |
| 	/**
 | |
| 	 * @constructor
 | |
| 	 * @param $id
 | |
| 	 * @param $data
 | |
| 	 */
 | |
| 	public function __construct($id, $data) {
 | |
| 			parent::Module($id, $data);	
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Executes all the actions in the $data variable.
 | |
| 	 * Exception part is used for authentication errors also
 | |
| 	 * @return boolean true on success or false on failure.
 | |
| 	 */
 | |
| 	public function execute() {
 | |
| 		$result = false;
 | |
| 		
 | |
| 		if(!$this->DEBUG) {
 | |
| 			/* disable error printing - otherwise json communication might break... */
 | |
| 			ini_set('display_errors', '0');
 | |
| 		}
 | |
| 		
 | |
| 		foreach($this->data as $actionType => $actionData) {
 | |
| 			if(isset($actionType)) {
 | |
| 				try {
 | |
| 					if($this->DEBUG) {
 | |
| 						error_log("exec: " . $actionType);
 | |
| 					}
 | |
| 					switch($actionType) {
 | |
| 						case "export":
 | |
| 							$result = $this->exportCalendar($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);
 | |
| 					}
 | |
| 
 | |
| 				} catch (MAPIException $e) {
 | |
| 					if($this->DEBUG) {
 | |
| 						error_log("mapi exception: " . $e->getMessage());
 | |
| 					}
 | |
| 				} catch (Exception $e) {
 | |
| 					if($this->DEBUG) {
 | |
| 						error_log("exception: " . $e->getMessage());
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 		
 | |
| 		return $result;
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * Generates a random string with variable length.
 | |
| 	 * @param $length the lenght of the generated string
 | |
| 	 * @return string a random string
 | |
| 	 */
 | |
| 	private function randomstring($length = 6) {
 | |
| 		// $chars - all allowed charakters
 | |
| 		$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
 | |
| 
 | |
| 		srand((double)microtime()*1000000);
 | |
| 		$i = 0;
 | |
| 		$pass = "";
 | |
| 		while ($i < $length) {
 | |
| 			$num = rand() % strlen($chars);
 | |
| 			$tmp = substr($chars, $num, 1);
 | |
| 			$pass = $pass . $tmp;
 | |
| 			$i++;
 | |
| 		}
 | |
| 		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) {
 | |
| 	
 | |
| 		
 | |
| 		
 | |
| 		// Get store id
 | |
| 		$storeid = false;
 | |
| 		if(isset($actionData["storeid"])) {
 | |
| 			$storeid = $actionData["storeid"];
 | |
| 		}
 | |
| 
 | |
| 		// Get message entryid
 | |
| 		$entryid = false;
 | |
| 		if(isset($actionData["entryid"])) {
 | |
| 			$entryid = $actionData["entryid"];
 | |
| 		}
 | |
| 		
 | |
| 		$tmpimage = $actionData["tmpfile"];
 | |
| 		$contactPicture = file_get_contents ($tmpimage);
 | |
| 		
 | |
| 		error_log($tmpdata);
 | |
| 		
 | |
| 		
 | |
| 		error_log("opening store");
 | |
| 		$store = $GLOBALS["mapisession"]->openMessageStore(hex2bin($storeid));
 | |
| 
 | |
| 		error_log("opening message");
 | |
| 		// Open a message from the store
 | |
| 		try {
 | |
| 			$message = mapi_msgstore_openentry($store, hex2bin($entryid));
 | |
| 		} catch (MAPIException $e) {
 | |
| 			$e->setHandled();
 | |
| 			error_log($e->getCode());
 | |
| 			error_log(mapi_last_hresult());
 | |
|  		}
 | |
| 		
 | |
| 		error_log("opening attachment");
 | |
| 		// Open attachment number 0
 | |
| 		$attach = mapi_message_createattach($message);
 | |
| 		
 | |
| 		// 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
 | |
| 		);
 | |
| 
 | |
| 		error_log("setting props");
 | |
| 		mapi_setprops($attach, $properties);
 | |
| 		
 | |
| 		// 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));
 | |
| 
 | |
| 		
 | |
| 		$response['status'] = true;
 | |
| 		$response['storeid'] = $storeid;
 | |
| 		$response['entryid'] = $entryid;
 | |
| 		
 | |
| 		$this->addActionData($actionType, $response);
 | |
| 		$GLOBALS["bus"]->addData($this->getResponseData());
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * 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); 
 | |
| 
 | |
| 		$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"]);
 | |
| 		}
 | |
| 		
 | |
| 		$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!");
 | |
| 		}
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * The main import function, parses the uploaded vcf file
 | |
| 	 * @param $actionType
 | |
| 	 * @param $actionData
 | |
| 	 */
 | |
| 	private function importContacts($actionType, $actionData) {
 | |
| 		if($this->DEBUG) {
 | |
| 			error_log("PHP Timezone: " . $tz);
 | |
| 		}
 | |
| 		
 | |
| 		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) {
 | |
| 				$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)
 | |
| 				);
 | |
| 			}
 | |
| 		} else {
 | |
| 			$response['status']	= false;
 | |
| 			$response['message']= "File could not be read by server";
 | |
| 		}
 | |
| 		
 | |
| 		$this->addActionData($actionType, $response);
 | |
| 		$GLOBALS["bus"]->addData($this->getResponseData());
 | |
| 		
 | |
| 		if($this->DEBUG) {
 | |
| 			error_log("parsing done, bus data written!");
 | |
| 		}
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * Create a array with contacts
 | |
| 	 * 
 | |
| 	 * @param contacts vcard or csv contacts
 | |
| 	 * @param csv optional, true if contacts are csv contacts
 | |
| 	 * @return array parsed contacts
 | |
| 	 * @private
 | |
| 	 */
 | |
| 	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];
 | |
| 				
 | |
| 				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'];
 | |
| 							}
 | |
| 						}
 | |
| 					}
 | |
| 				}
 | |
| 				if ($vCard -> EMAIL) {
 | |
| 					$e=0;
 | |
| 					foreach ($vCard -> EMAIL as $Email) {
 | |
| 						$fileas = $Email['Value'];
 | |
| 						if(isset($properties["fileas"]) && !empty($properties["fileas"])) {
 | |
| 							$fileas = $properties["fileas"];
 | |
| 						}
 | |
| 						
 | |
| 						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;
 | |
| 							}
 | |
| 							$e++;
 | |
| 						}
 | |
| 					}
 | |
| 				}
 | |
| 				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 ($vCard -> TITLE) {
 | |
| 					$properties["title"] = $vCard -> TITLE[0];
 | |
| 				}
 | |
| 				if ($vCard -> URL) {
 | |
| 					$properties["webpage"] = $vCard -> URL[0];
 | |
| 				}
 | |
| 				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["body"] = $vCard -> NOTE[0];
 | |
| 				}
 | |
| 				if ($vCard -> PHOTO) {
 | |
| 					if(!is_writable(TMP_PATH . "/")) {
 | |
| 						error_log("could not write to export tmp directory!: " . $E);
 | |
| 					} else {
 | |
| 						$tmppath = TMP_PATH . "/" . $this->randomstring(15);
 | |
| 						try {
 | |
| 							if($vCard -> SaveFile('photo', 0, $tmppath)) {
 | |
| 								$properties["x_photo_path"] = $tmppath;								
 | |
| 							} else {
 | |
| 								if($this->DEBUG) {
 | |
| 									error_log("remote imagefetching not implemented");
 | |
| 								}
 | |
| 							}
 | |
| 						} catch (Exception $E) {
 | |
| 							error_log("Image exception: " . $E);
 | |
| 						}
 | |
| 					}
 | |
| 				}
 | |
| 				array_push($carr, $properties);
 | |
| 			}
 | |
| 		} else {
 | |
| 			error_log("csv parsing not implemented");
 | |
| 		}
 | |
| 		
 | |
| 		return $carr;
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * Generate the whole addressstring
 | |
| 	 *
 | |
| 	 * @param street
 | |
| 	 * @param zip
 | |
| 	 * @param city
 | |
| 	 * @param state
 | |
| 	 * @param country
 | |
| 	 * @return string the concatinated address string
 | |
| 	 * @private
 | |
| 	 */
 | |
| 	private function buildAddressString($street, $zip, $city, $state, $country) {
 | |
| 		$out = "";
 | |
| 
 | |
| 		if (isset($country) && $street != "") $out = $country;
 | |
| 
 | |
| 		$zcs = "";
 | |
| 		if (isset($zip) && $zip != "") $zcs = $zip;
 | |
| 		if (isset($city) && $city != "") $zcs .= (($zcs)?" ":"") . $city;
 | |
| 		if (isset($state) && $state != "") $zcs .= (($zcs)?" ":"") . $state;
 | |
| 		if ($zcs) $out = $zcs . "\r\n" . $out;
 | |
| 
 | |
| 		if (isset($street) && $street != "") $out = $street . (($out)?"\r\n". $out: "") ;
 | |
| 
 | |
| 		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());
 | |
| 		}
 | |
| 	}
 | |
| };
 | |
| 
 | |
| ?>
 |