Blob Blame History Raw
diff -ruN /usr/src/zarafa/zarafa-6.30.4.17264/php-ext/include/mapi/class.autoarchivesettings.php mapi/class.autoarchivesettings.php
--- /usr/src/zarafa/zarafa-6.30.4.17264/php-ext/include/mapi/class.autoarchivesettings.php	Thu Jan  1 01:00:00 1970
+++ mapi/class.autoarchivesettings.php	Sat Aug  8 11:49:05 2009
@@ -0,0 +1,218 @@
+<?php
+/*
+ * Copyright 2005 - 2009  Zarafa B.V.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3, 
+ * as published by the Free Software Foundation with the following additional 
+ * term according to sec. 7:
+ * 
+ * "Zarafa" is a registered trademark of Zarafa B.V. The licensing of the Program
+ * under the AGPL does not imply a trademark license. Therefore any rights,
+ * title and interest in our trademarks remain entirely with us.
+ * However, if you propagate an unmodified version of the Program you are 
+ * required to use the term "Zarafa" to indicate that you distribute the 
+ * Program. Furthermore you may use our trademarks where it is necessary to 
+ * indicate the intended purpose of a product or service provided you use it in 
+ * accordance with honest practices in industrial or commercial matters.
+ * If you want to propagate modified versions of the Program under the name
+ * "Zarafa" or "Zarafa Server", you may only do so if you have a written
+ * permission by Zarafa B.V. (to acquire a permission please contact Zarafa at
+ * trademark@zarafa.com).
+ * The user interface of the software displays a attribution notice containing
+ * the term "Zarafa" and/or the Logo of Zarafa. You have to preserve these
+ * attribution notices when you propagate unmodified or modified versions of
+ * the Program.
+ * 
+ * This program 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 Affero General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ * 
+ */
+
+?>
+<?php
+
+include_once('mapi.util.php');
+include_once('mapidefs.php');
+include_once('mapitags.php');
+
+/**
+ * AutoArchiveSettings 
+ * @author Andreas Brodowski <andreas@brodowski.org>
+ */
+
+class AutoArchiveSettings {
+
+	var $session;
+	var $store;
+	var $folder;
+	var $proptags;
+    
+	function agingproperties() {
+		$properties = array();
+		$properties["entryid"] = PR_ENTRYID;
+		$properties["parent_entryid"] = PR_PARENT_ENTRYID;
+		$properties["message_class"] = PR_MESSAGE_CLASS;
+		$properties["icon_index"] = PR_ICON_INDEX;
+		$properties["display_to"] = PR_DISPLAY_TO;
+		$properties["display_cc"] = PR_DISPLAY_CC;
+		$properties["subject"] = PR_SUBJECT;
+		$properties["importance"] = PR_IMPORTANCE;
+		$properties["sent_representing_name"] = PR_SENT_REPRESENTING_NAME;
+		$properties["sent_representing_email_address"] = PR_SENT_REPRESENTING_EMAIL_ADDRESS;
+		$properties["sent_representing_addrtype"] = PR_SENT_REPRESENTING_ADDRTYPE;
+		$properties["sent_representing_entryid"] = PR_SENT_REPRESENTING_ENTRYID;
+		$properties["sender_email_address"] = PR_SENDER_EMAIL_ADDRESS;
+		$properties["sender_name"] = PR_SENDER_NAME;
+		$properties["received_by_name"] = PR_RECEIVED_BY_NAME;
+		$properties["received_by_email_address"] = PR_RECEIVED_BY_EMAIL_ADDRESS;
+		$properties["message_delivery_time"] = PR_MESSAGE_DELIVERY_TIME;
+		$properties["last_modification_time"] = PR_LAST_MODIFICATION_TIME;
+		$properties["last_verb_executed"] = PR_LAST_VERB_EXECUTED;
+		$properties["last_verb_execution_time"] = PR_LAST_VERB_EXECUTION_TIME;
+		$properties["hasattach"] = PR_HASATTACH;
+		$properties["message_size"] = PR_MESSAGE_SIZE;
+		$properties["message_flags"] = PR_MESSAGE_FLAGS;
+		$properties["flag_status"] = PR_FLAG_STATUS;
+		$properties["flag_complete_time"] = PR_FLAG_COMPLETE_TIME;
+		$properties["flag_icon"] = PR_FLAG_ICON;
+		$properties["reminder_time"] = "PT_SYSTIME:PSETID_Common:0x8502";
+		$properties["reminder_set"] = "PT_BOOLEAN:PSETID_Common:0x8503";
+		$properties["flag_request"] = "PT_STRING8:PSETID_Common:0x8530";
+		$properties["flag_due_by"] = "PT_SYSTIME:PSETID_Common:0x8560";
+		$properties["reply_requested"] = PR_REPLY_REQUESTED;
+		$properties["reply_time"] = PR_REPLY_TIME;
+		$properties["response_requested"] = PR_RESPONSE_REQUESTED;
+		$properties["client_submit_time"] = PR_CLIENT_SUBMIT_TIME;
+		$properties["sensitivity"] = PR_SENSITIVITY;
+		$properties["read_receipt_requested"] = PR_READ_RECEIPT_REQUESTED;
+		$properties["location"] = "PT_STRING8:PSETID_Appointment:0x8208";
+		$properties["categories"] = "PT_MV_STRING8:PS_PUBLIC_STRINGS:Keywords";
+		$properties["transport_message_headers"] = PR_TRANSPORT_MESSAGE_HEADERS;
+		$properties["contacts"] = "PT_MV_STRING8:PSETID_Common:0x853A";
+		$properties["contacts_string"] = "PT_STRING8:PSETID_Common:0x8586";
+
+		$properties["aging_period"] = PR_AGING_PERIOD; // max 3 digits
+		$properties["aging_granularity"] = PR_AGING_GRANULARITY; // 0=month, 1=weeks, 2=days
+		$properties["aging_filename"] = PR_AGING_FILENAME;
+		$properties["aging_age_folder"] = PR_AGING_AGE_FOLDER;
+		$properties["aging_deleted_items"] = PR_AGING_DELETE_ITEMS;
+		$properties["aging_dont_age_me"] = PR_AGING_DONT_AGE_ME;
+		$properties["aging_file_name_after9"] = PR_AGING_FILE_NAME_AFTER9;
+		$properties["aging_when_deleted_on_server"] = PR_AGING_WHEN_DELETED_ON_SERVER;
+		$properties["aging_wait_until_expired"] = PR_AGING_WAIT_UNTIL_EXPIRED;
+		$properties["aging_version"] = PR_AGING_VERSION;
+		$properties["aging_default"] = PR_AGING_DEFAULT;
+	
+		$properties["deleted_on"] = PR_DELETED_ON;
+		$properties["updatecounter"] = "PT_LONG:PSETID_Appointment:0x8201";
+		$properties["hideattachments"] = "PT_BOOLEAN:PSETID_Common:0x8514";
+
+		return $properties;
+	}
+
+	/**
+	 * Constuctor
+	 *
+	 * @param mapi_session $session MAPI Session
+	 * @param mapi_folder $folder Folder to use for AutoArchive Settings retrival
+	 */	 
+	 
+	function retrieveSettings($session, $store, $folder, $properties = NULL)
+	{
+		if ($properties == NULL) {
+			$properties = $this->agingproperties();
+		};
+		
+		$this->proptags = getPropIdsFromStrings($store, $properties);
+	
+		$this->session = $session;
+		$this->store = $store;
+		$this->folder = $folder;
+
+		$msg = $this->getMessage();
+		
+		$props = mapi_getprops($msg,$this->proptags);
+
+		$data = $props;
+
+		return $data;
+	}
+
+	function getMessage() {
+	        $table = mapi_folder_getcontentstable($this->folder, MAPI_ASSOCIATED);
+		mapi_table_sort($table, array(PR_RECEIPT_TIME => TABLE_SORT_ASCEND));
+	        $restriction =  array ( RES_PROPERTY, 
+    	    				array ( RELOP => RELOP_EQ,
+    					        ULPROPTAG => PR_MESSAGE_CLASS,
+						VALUE => array (PR_MESSAGE_CLASS => "IPC.MS.Outlook.AgingProperties")
+					)
+				);
+		$msgs = mapi_table_queryallrows($table,array(PR_ENTRYID),$restriction);
+		if (isset($msgs[0][PR_ENTRYID])) {
+    		    $msg = mapi_msgstore_openentry($this->store,$msgs[0][PR_ENTRYID]);
+	        } else {
+	    	    $this->createMessage();
+	    	    $msg = $this->getMessage();
+	        }
+	        return $msg;
+	}
+	
+	function updateSettings($session, $store, $folder, $uprops) {
+		$properties = $this->agingproperties();
+	
+		$this->session = $session;
+		$this->store = $store;
+		$this->folder = $folder;
+
+		$msg = $this->getMessage();
+		
+		$write_props = array();
+		
+		if (isset($uprops["aging_period"])) 		$write_props[$properties["aging_period"]] 		= $uprops["aging_period"]; 
+		if (isset($uprops["aging_granularity"])) 	$write_props[$properties["aging_granularity"]] 		= $uprops["aging_granularity"]; 
+		if (isset($uprops["aging_age_folder"])) 	$write_props[$properties["aging_age_folder"]] 		= $uprops["aging_age_folder"]; 
+		if (isset($uprops["aging_deleted_items"])) 	$write_props[$properties["aging_deleted_items"]] 	= $uprops["aging_deleted_items"]; 
+		if (isset($uprops["aging_filename"])) 		$write_props[$properties["aging_filename"]] 		= $uprops["aging_filename"]; 
+		if (isset($uprops["aging_file_name_after9"])) 	$write_props[$properties["aging_file_name_after9"]] 	= $uprops["aging_file_name_after9"]; 
+		if (isset($uprops["aging_version"])) 		$write_props[$properties["aging_version"]] 		= $uprops["aging_version"]; 
+		if (isset($uprops["aging_default"])) 		$write_props[$properties["aging_default"]] 		= $uprops["aging_default"]; 
+		
+		mapi_setprops($msg,$write_props);	
+		
+		mapi_savechanges($msg);
+		
+	}
+	
+	function createMessage() {
+	
+		$properties = $this->agingproperties();
+		
+		$write_props = array(	$properties["message_class"] 		=> "IPC.MS.Outlook.AgingProperties",
+        				$properties["display_to"]	 	=> NULL,
+        				$properties["display_cc"] 		=> NULL,
+					$properties["aging_period"] 		=> "3",
+					$properties["aging_granularity"] 	=> "0",
+					$properties["aging_age_folder"] 	=> "0",
+					$properties["aging_deleted_items"]	=> "0",
+					$properties["aging_filename"] 		=> "",
+					$properties["aging_file_name_after9"]	=> "",
+					$properties["aging_version"] 		=> "2",
+					$properties["aging_default"] 		=> "0"
+				    );
+					
+    		$msg = mapi_folder_createmessage($this->folder,MAPI_ASSOCIATED);
+
+		mapi_setprops($msg,$write_props);	
+		
+		mapi_savechanges($msg);
+
+	}
+
+}
+?>
diff -ruN /usr/src/zarafa/zarafa-6.30.4.17264/php-ext/include/mapi/class.linkedappointment.php mapi/class.linkedappointment.php
--- /usr/src/zarafa/zarafa-6.30.4.17264/php-ext/include/mapi/class.linkedappointment.php	Thu Jan  1 01:00:00 1970
+++ mapi/class.linkedappointment.php	Fri Aug 14 11:16:18 2009
@@ -0,0 +1,393 @@
+<?php
+/*
+ * Copyright 2005 - 2009  Zarafa B.V.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3, 
+ * as published by the Free Software Foundation with the following additional 
+ * term according to sec. 7:
+ * 
+ * "Zarafa" is a registered trademark of Zarafa B.V. The licensing of the Program
+ * under the AGPL does not imply a trademark license. Therefore any rights,
+ * title and interest in our trademarks remain entirely with us.
+ * However, if you propagate an unmodified version of the Program you are 
+ * required to use the term "Zarafa" to indicate that you distribute the 
+ * Program. Furthermore you may use our trademarks where it is necessary to 
+ * indicate the intended purpose of a product or service provided you use it in 
+ * accordance with honest practices in industrial or commercial matters.
+ * If you want to propagate modified versions of the Program under the name
+ * "Zarafa" or "Zarafa Server", you may only do so if you have a written
+ * permission by Zarafa B.V. (to acquire a permission please contact Zarafa at
+ * trademark@zarafa.com).
+ * The user interface of the software displays a attribution notice containing
+ * the term "Zarafa" and/or the Logo of Zarafa. You have to preserve these
+ * attribution notices when you propagate unmodified or modified versions of
+ * the Program.
+ * 
+ * This program 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 Affero General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ * 
+ */
+?>
+<?php
+
+include_once('mapi.util.php');
+include_once('mapidefs.php');
+include_once('mapitags.php');
+include_once('class.recurrence.php');
+
+/**
+ * linkedAppointment 
+ * @author dw2412 Andreas Brodowski <andreas at brodowski.org>
+ */
+ 
+class linkedAppointment
+{
+
+		/**
+		 * @var object Mapi Message Store (may be null if readonly)
+		 */
+		var $_store;
+		
+	        var $_contactmapping = array (
+	    	        "fileas" => "PT_STRING8:{00062004-0000-0000-C000-000000000046}:0x8005",
+	    	        "birthday_event_entryid" => "PT_BINARY:{00062004-0000-0000-C000-000000000046}:0x804d",
+		        "anniversary_event_entryid" => "PT_BINARY:{00062004-0000-0000-C000-000000000046}:0x804e",
+		        "birthday" => PR_BIRTHDAY,
+	    	        "anniversary" => PR_WEDDING_ANNIVERSARY,
+		        "entryid" => PR_ENTRYID,
+		        "search_key" => PR_SEARCH_KEY
+	        );
+	        
+	        var $_appointmentmapping = array (
+                        "alldayevent" => "PT_BOOLEAN:{00062002-0000-0000-C000-000000000046}:0x8215",
+                        "body" => PR_BODY,
+                        "busystatus" => "PT_LONG:{00062002-0000-0000-C000-000000000046}:0x8205",
+                        "categories" => "PT_MV_STRING8:{00020329-0000-0000-C000-000000000046}:Keywords",
+                        "rtf" => PR_RTF_COMPRESSED,
+                        "dtstamp" => PR_LAST_MODIFICATION_TIME,
+                        "endtime" => "PT_SYSTIME:{00062002-0000-0000-C000-000000000046}:0x820e",
+                        "location" => "PT_STRING8:{00062002-0000-0000-C000-000000000046}:0x8208",
+                        "meetingstatus" => "PT_LONG:{00062002-0000-0000-C000-000000000046}:0x8217",
+                        "reminder" => "PT_LONG:{00062008-0000-0000-C000-000000000046}:0x8501",
+                        "sensitivity" => PR_SENSITIVITY,
+                        "subject" => PR_SUBJECT,
+                        "starttime" => "PT_SYSTIME:{00062002-0000-0000-C000-000000000046}:0x820d",
+                        "uid" => "PT_BINARY:{6ED8DA90-450B-101B-98DA-00AA003F1305}:0x3",
+			// Append the appointment attributes since we need them for appointment creation
+		    	"label" => "PT_LONG:{00062002-0000-0000-C000-000000000046}:0x8214",
+		    	"recurring" => "PT_BOOLEAN:{00062002-0000-0000-C000-000000000046}:0x8223",
+		    	"recurring_data" => "PT_BINARY:{00062002-0000-0000-C000-000000000046}:0x8216",
+			"recurring_pattern" => "PT_STRING8:{00062002-0000-0000-C000-000000000046}:0x8232",
+		    	"basedate" => "PT_SYSTIME:{00062002-0000-0000-C000-000000000046}:0x8228",
+		    	"icon_index" => PR_ICON_INDEX,
+		    	"entryid" => PR_ENTRYID,
+		    	"message_class" => PR_MESSAGE_CLASS,
+        	    	"parententryid" => PR_PARENT_ENTRYID,
+		    	"message_flags" => PR_MESSAGE_FLAGS,
+		    	"importance" => PR_IMPORTANCE,
+		    	// Append the common attributes since we need them for appointment creation
+		    	"contacts" => "PT_MV_STRING8:{00062008-0000-0000-C000-000000000046}:0x853a",
+		    	"contacts_string" => "PT_STRING8:{00062008-0000-0000-C000-000000000046}:0x8586",
+        	    	"commonstart" => "PT_SYSTIME:{00062008-0000-0000-C000-000000000046}:0x8516",
+        	    	"commonend" => "PT_SYSTIME:{00062008-0000-0000-C000-000000000046}:0x8517",
+        	    	"remindertime" => "PT_SYSTIME:{00062008-0000-0000-C000-000000000046}:0x8502",
+        	    	"duration" => "PT_LONG:{00062002-0000-0000-C000-000000000046}:0x8213",
+        	    	"reminder_minutes" => "PT_LONG:{00062008-0000-0000-C000-000000000046}:0x8501",
+        	    	"reminder" => "PT_BOOLEAN:{00062008-0000-0000-C000-000000000046}:0x8503",
+		    	"flagdueby" => "PT_SYSTIME:{00062008-0000-0000-C000-000000000046}:0x8560",
+		    	"lid_contact_link_search_key" => "PT_BINARY:{00062008-0000-0000-C000-000000000046}:0x8584",
+		    	"lid_contact_link_entryid" => "PT_BINARY:{00062008-0000-0000-C000-000000000046}:0x8585"
+                );
+	    
+		/**
+		 * Constructor
+		 * @param resource $store MAPI Message Store Object
+		 * @param resource $message the MAPI Source message
+		 */
+		function linkedAppointment($_store)
+		{
+		    $this->_store = $_store;
+		}
+
+	        function setLinkedContact($mapimessage) 
+	    	{
+		// get the linked contact (if any)
+		    // Set the appointment attributes
+		    $aprops = $this->_appointmentmapping;
+		    // Get the id's of the above...
+		    foreach ($aprops as $key => $value) {
+		        $aprops[$key] =  $this->GetPropIDFromString($this->_store, $value);
+		    }
+		    $appointment = mapi_getprops($mapimessage, $aprops);
+	            $recurrence = new Recurrence($this->_store, $mapimessage);
+		    $recur = $recurrence->getRecurrence();
+		    if (isset($appointment[$aprops["lid_contact_link_entryid"]])) {
+		        // we have a linked contact. so continue here, otherwise exit silently...
+		        $entryid = $this->_unpackContactLinkEntryIDS(bin2hex($appointment[$aprops["lid_contact_link_entryid"]]));
+		        // Set the contact attributes
+			$cprops = $this->_contactmapping;
+			// Get the id's of the above...
+			foreach ($cprops as $key => $value) {
+		    	    $cprops[$key] =  $this->GetPropIDFromString($this->_store, $value);
+			}
+		        foreach ($entryid as $value) {
+		    	    if (($contact_msg = mapi_msgstore_openentry($this->_store,$value))) {
+		    	        $contact = mapi_getprops($contact_msg, $cprops);
+		    	        switch ($appointment[$aprops["entryid"]]) {
+		    	            case $contact[$cprops["birthday_event_entryid"]]	:
+			    			if ($contact[$cprops["birthday"]] != $recur["start"]) {
+						    mapi_setprops($contact_msg,array($cprops["birthday"] => $recur["start"]));
+					    	    mapi_savechanges($contact_msg);
+						}
+						break;
+				    case $contact[$cprops["anniversary_event_entryid"]]	:
+						if ($contact[$cprops["anniversary"]] != $recur["start"]) {
+						    mapi_setprops($contact_msg,array($cprops["anniversary"] => $recur["start"]));
+					    	    mapi_savechanges($contact_msg);
+						}
+						break;
+				}
+			    }
+			}
+		    }
+		}
+	        // $what 0x01 = birthday 0x02 = anniversary
+		function setLinkedAppointment($mapimessage,$what) 
+		{
+		    // We love MS for this...
+		    $arrayMonth = array(0,44640,84960,129600,172800,217440,260640,305280,348480,393120,437760,480960);
+
+		    // Set the appointment attributes
+		    $aprops = $this->_appointmentmapping;
+		    // Get the id's of the above...
+		    foreach ($aprops as $key => $value) {
+		        $aprops[$key] =  $this->GetPropIDFromString($this->_store, $value);
+		    }
+	    
+		    // Set the contact attributes
+		    $cprops = $this->_contactmapping;
+		    // Get the id's of the above...
+		    foreach ($cprops as $key => $value) {
+			$cprops[$key] =  $this->GetPropIDFromString($this->_store, $value);
+		    }
+
+	    	    // Get the contact properties
+	    	    $contact = mapi_getprops($mapimessage,$cprops);
+	    
+	    	    // open root container, if not existing, leave this function...
+	    	    $rootcontainer = mapi_msgstore_openentry($this->_store);
+	    	    if ($rootcontainer) {
+	    		// find the appointment container, if this fails, leave this function since we cannot proceed...
+	    		if (($rootcontainerprops = mapi_getprops($rootcontainer, array(PR_IPM_APPOINTMENT_ENTRYID)))) {
+	    		    $parententryid = $rootcontainerprops[PR_IPM_APPOINTMENT_ENTRYID];
+	    
+	    		    $entryid = false;
+	    		    switch ($what) {
+	    			case 0x01	: if (isset($contact[$cprops["birthday_event_entryid"]])) 
+	    					      $entryid = $contact[$cprops["birthday_event_entryid"]];
+	    					  $entrydate = $contact[$cprops["birthday"]];
+	    					  $entryprop = $cprops["birthday_event_entryid"];
+	    					  $entrylabel = 8;
+	    					  $entrysubject = _("Birthday")." "._("of")." ".$contact[$cprops["fileas"]];
+	    					  break;
+	    			case 0x02	: if (isset($contact[$cprops["anniversary_event_entryid"]]))
+	    					     $entryid = $contact[$cprops["anniversary_event_entryid"]];
+	    					  $entrydate = $contact[$cprops["anniversary"]];
+	    					  $entryprop = $cprops["anniversary_event_entryid"];
+	    					  $entrylabel = 9;
+	    					  $entrysubject = _("Special Date")." "._("of")." ".$contact[$cprops["fileas"]];
+	    					  break;
+	    		    }
+	    
+	    		    if ($entrydate) {
+	    			// open if there is a linked appointment and it can be opened (no one deleted it by accident...)
+	        		// otherwise create it.
+	    			if ($entryid &&
+	    			    ($appointment_msg = mapi_msgstore_openentry($this->_store,$entryid))) {
+	    			    $appointment = mapi_getprops($appointment_msg);
+	    	    		} else {
+	    			    // create with base settings
+	    			    $folder = mapi_msgstore_openentry($this->_store,$parententryid);
+	    	    	    	    $appointment_msg = mapi_folder_createmessage($folder);
+	    	    		    $appointment = array($aprops["message_class"] => "IPM.Appointment",
+	    	    		    		         $aprops["location"] => "",
+	    	    				         $aprops["body"] => "",
+	    	    				         $aprops["busystatus"] => 0
+	    					        );
+	        	    	    mapi_setprops($appointment_msg,$appointment);
+	    	    		}
+	    			// Have the starttime im GMT
+	    	    		$starttime = gmmktime(0,0,0,
+	    	    		    		      date("m",$entrydate),
+	    	    				      date("j",$entrydate),
+	    	    				      date("Y",$entrydate));
+	    		        // Just update something in case changes occured to reduce amount
+	    		        // of sync activities...
+	    		      
+	    		        if ($entrydate != $appointment[$aprops["starttime"]] ||
+	    		    	    $entrysubject != $appointment[$aprops["subject"]]) {
+	    			    // Reset the subject in case the name has changed
+	        		    $appointment[$aprops["subject"]] = $entrysubject;
+	    		            // Set the label to 8 = birthday and 9 = anniversary
+	    			    $appointment[$aprops["label"]] = $entrylabel;
+	    			    // Instead of having rubbish inside...
+	            	    	    $appointment[$aprops["recurring_pattern"]] = "";
+	    		    	    // Setting the reminder values
+	    	    	    	    $appointment[$aprops["reminder"]] = true;
+	    	    	    	    $appointment[$aprops["reminder_minutes"]] = 15;
+	    	    	    	    $appointment[$aprops["remindertime"]] = $starttime-(15*60);
+	    		    	    // Setting start & Endtime
+	    	    	    	    $appointment[$aprops["starttime"]] = $starttime;
+	    	    	    	    $appointment[$aprops["endtime"]] = $starttime + 86400;
+	    		    	    // Set duration upon diff between start and endtime in minutes.
+	    	    	    	    $appointment[$aprops["duration"]] = ($appointment[$aprops["endtime"]] - $appointment[$aprops["starttime"]]) / 60;
+	    		    	    // Sure... birthdays and anniversaries occur on daily base :-)
+	    	    	    	    $appointment[$aprops["recurring"]] = true;
+	    	    	    	    $appointment[$aprops["alldayevent"]] = true;
+	    		    	    // Update the id's and search keys
+	    		    	    $appointment[$aprops["lid_contact_link_entryid"]] = hex2bin($this->_packContactLinkEntryIDS(array($contact[$cprops["entryid"]])));
+	    		    	    $appointment[$aprops["lid_contact_link_search_key"]] = hex2bin($this->_packContactLinkSearchKeys(array($contact[$cprops["search_key"]])));
+	    		    	    // Set the changed properties
+	        	    	    mapi_setprops($appointment_msg,$appointment);
+	        		    $recurrence = new Recurrence($this->_store, $appointment_msg);
+	    		    	    $tz = array();
+	    		    	    $tz["timezone"] = (($entrydate-$starttime)/3600)*60;
+	    		    	    $tz["timezonedst"] = 0; 
+	    		    	    $tz["dstendmonth"] = 0;
+	    		    	    $tz["dstendweek"] = 0;
+	    		    	    $tz["dstendhour"] = 0;
+	    		    	    $tz["dststartmonth"] = 0;
+	    		    	    $tz["dststartweek"] = 0;
+	    		    	    $tz["dststarthour"] = 0;
+	    		    	    // Set the iconindex to be recurring
+	    	    	    	    $appointment[$aprops["icon_index"]] = 1025;
+	    		    	    // Set the changed properties
+	    		    	    $appointment = mapi_setprops($appointment_msg,$appointment);
+	    		    	    // Recurring values
+	                            $recur["type"] = 13;
+	                            $recur["subtype"] = 2;
+	    	    	    	    $recur["month"] = $arrayMonth[gmdate("m",$starttime)-1];
+	                            $recur["everyn"] = 12;
+	    		    	    $recur["regen"] = 1;
+	    	    	    	    $recur["monthday"] = gmdate("j",$starttime);
+	    	            	    $recur["term"] = 0x23;
+	    		    	    $recur["numoccur"] = 0;
+	        		    $recur["start"] = $starttime;
+	    		    	    $recur["end"] = 79870662000; // no end
+	                            $recur["startocc"] = 0;
+	                            $recur["endocc"] = 1440;
+	    		    	    // Let class.recurrence do its job.
+	        	    	    $recurrence->setRecurrence($tz, $recur);
+	    		    	    // Save the changes to message
+	    		    	    mapi_savechanges($appointment_msg);
+	    		    	    $appointment = mapi_getprops($appointment_msg);
+	    		    	    mapi_setprops($mapimessage,array($entryprop => $appointment[$aprops['entryid']]));
+	    		    	    mapi_savechanges($mapimessage);
+	        		}    
+	        	    }
+	    		}
+	    	    }
+	        }
+    		/**
+    		* unpacks the Contact Link Entry IDs
+		*
+		* @param string in hex with the value
+		* @return array with all binary Contact Link Entry IDS
+		*
+		*/
+		function _unpackContactLinkEntryIDS($value) 
+		{
+		    $contact_link_entry_ids = unpack("Vcount",hex2bin(substr($value,0,8)));
+		    $contact_link_entry_ids["entry_ids"] = array();
+		    $length=8;
+		    for ($j=0,$i=8;$j<$contact_link_entry_ids["count"];$j++,$i=$i+$length+8) {
+			$l = unpack("Vlength",hex2bin(substr($value,$i,8)));
+			$length=$l["length"];
+			$temp = unpack ("VFlags/A16ProviderUID/VVersion/VType/VIndext/Vcbid/A*abeid",hex2bin(substr($value,$i+8,($length*2))));
+			$temp["abeid"] = hex2bin(substr(bin2hex($temp["abeid"]),0,$temp["cbid"]*2));
+			$contact_link_entry_ids["entry_ids"][]=$temp["abeid"];
+		    }
+		    return $contact_link_entry_ids["entry_ids"];
+		}
+		
+		/**
+		 * packs the Contact Link Entry IDs
+		 *
+		 * @param array with all binary Contact Link Entry IDs
+		 * @return string in hex with the value
+		 *
+		 */
+		function _packContactLinkEntryIDS($values) {
+		    $temp="";
+		    for ($i=0;$i<sizeof($values);$i++) {
+		        $temp .= pack("V",0).makeguid("{0aaa42fe-c718-101a-e885-0b651c240000}").pack("VVVV",3,4,0,(strlen(bin2hex($values[$i]))/2)).$values[$i];
+		    }
+		    $temp = bin2hex(pack("VV",sizeof($values),(strlen(bin2hex($temp))/2)).$temp);
+		    return $temp;
+		}
+		
+		/**
+		 * unpacks the Contact Link Search key
+		 *
+		 * @param string in hex with the value
+		 * @return array with all binary Contact Link Search Keys
+		 *
+		 */
+		function _unpackContactLinkSearchKeys($value) {
+		    $contact_link_search_keys = unpack("Vcount/Vlength",hex2bin(substr($value,0,16)));
+		    $contact_link_search_keys["skeys"] = array();
+		    $length=0;
+		    for ($i=16,$j=0;$i-16<($contact_link_search_keys["length"]*2) && $j<$contact_link_search_keys["count"];$i=$i+($length*2)+8,$j++) {
+		        $l = unpack("Vlength",hex2bin(substr($value,$i,8)));
+		        $length=$l["length"];
+		        $contact_link_search_keys["skeys"][] = hex2bin(substr($value,$i+8,($length*2)));
+		    };
+		    return $contact_link_search_keys["skeys"];
+		}
+		
+		/**
+		 * packs the Contact Link Search key
+		 *
+		 * @param array with all binary Contact Link Search Keys
+		 * @return string in hex with the value
+		 *
+		 */
+		function _packContactLinkSearchKeys($values) {
+		    $temp="";
+		    for ($i=0;$i<sizeof($values);$i++) {
+		        $temp .= pack("V",strlen($values[$i])).$values[$i];
+		    }
+		    $temp = bin2hex(pack("VV",sizeof($values),strlen($temp)).$temp);
+		    return $temp;
+		}
+
+
+		function GetPropIDFromString($store, $mapiprop) {
+		    if(is_string($mapiprop)) {
+		        $split = explode(":", $mapiprop);
+		
+		        if(count($split) != 3)
+		            continue;
+		
+		        if(substr($split[2], 0, 2) == "0x") {
+		            $id = hexdec(substr($split[2], 2));
+		        } else
+		            $id = $split[2];
+		
+		        $named = mapi_getidsfromnames($store, array($id), array(makeguid($split[1])));
+		
+		        $mapiprop = mapi_prop_tag(constant($split[0]), mapi_prop_id($named[0]));
+		    } else {
+		        return $mapiprop;
+		    }
+		
+		    return $mapiprop;
+		}
+}
+?>
diff -ruN /usr/src/zarafa/zarafa-6.30.4.17264/php-ext/include/mapi/class.recurrence.php mapi/class.recurrence.php
--- /usr/src/zarafa/zarafa-6.30.4.17264/php-ext/include/mapi/class.recurrence.php	Fri Oct 16 21:05:22 2009
+++ mapi/class.recurrence.php	Tue Oct 20 19:29:54 2009
@@ -363,9 +363,13 @@
 		 * @param array $exception_props the exception properties (same properties as normal recurring items)
 		 * @param date $base_date the base date of the exception (actual GMT time of non-exception occurrence)
 		 * @param boolean $delete true - delete occurrence, false - create new exception or modify existing
+		 * @param boolean $islocal true - expect the base_date in local time (happens in case basedate is returned from WA!
 		 */
-		function createException($exception_props, $base_date, $delete = false)
+		function createException($exception_props, $base_date, $delete = false, $islocal=false)
 		{
+			// CHANGED dw2412 to support local base_date as delivered from WebAccess
+			if ($islocal == true) $base_date = $this->toGMT($this->tz, $base_date);
+			
 			$baseday = $this->dayStartOf($this->fromGMT($this->tz, $base_date));
 			$basetime = $baseday + $this->recur["startocc"] * 60;
 			
@@ -447,8 +451,10 @@
 		 * Modifies an existing exception, but only updates the given properties
 		 * NOTE: You can't remove properites from an exception, only add new ones
 		 */
-		function modifyException($exception_props, $base_date)
+		function modifyException($exception_props, $base_date, $islocal=false)
 		{
+		    // ADDED dw2412 to support local base_date as delivered from WebAccess
+		    if ($islocal == true) $base_date = $this->toGMT($this->tz, $base_date);
 		    if(!$this->isValidExceptionDate($base_date, $exception_props[$this->proptags["startdate"]]))
 		        return false;
 		        
@@ -573,13 +579,17 @@
 		
 		// Returns the start or end time of the occurrence on the given base date.
 		// This assumes that the basedate you supply is correct .. !
-		function getOccurrenceStart($basedate)  {
-			$daystart = $this->dayStartOf($this->fromGMT($this->tz, $basedate));
+		function getOccurrenceStart($basedate, $islocal = false)  {
+			// CHANGED dw2412 to support local base_date as delivered from WebAccess
+			if ($islocal == false) $daystart = $this->dayStartOf($this->fromGMT($this->tz, $basedate));
+			else $daystart = $this->dayStartOf($basedate);
 			return $this->toGMT($this->tz, $daystart + $this->recur["startocc"] * 60);
 		}
 		
-		function getOccurrenceEnd($basedate)  {
-			$daystart = $this->dayStartOf($this->fromGMT($this->tz, $basedate));
+		function getOccurrenceEnd($basedate, $islocal = false)  {
+			// CHANGED dw2412 to support local base_date as delivered from WebAccess
+			if ($islocal == false) $daystart = $this->dayStartOf($this->fromGMT($this->tz, $basedate));
+			else $daystart = $this->dayStartOf($basedate);
 			return $this->toGMT($this->tz, $daystart + $this->recur["endocc"] * 60);
 		}
 		
@@ -1229,8 +1239,12 @@
         /**
          * Returns the exception if there is a CHANGE exception on the given base date, or FALSE otherwise
          */
-        function getChangeException($basedate)
+        function getChangeException($basedate, $islocal)
         {
+	    // CHANGED dw2412 to support local base_date as delivered from WebAccess
+	    if ($islocal == true) $basedate = $this->toGMT($this->tz, $basedate);
+
+
             // Check if the occurrence is modified on the specified date
 			foreach($this->recur["changed_occurences"] as $changed)
 			{
@@ -1263,7 +1277,6 @@
 		function dayStartOf($date)
 		{
 		    $time1 = $this->gmtime($date);
-		    
 		    return gmmktime(0, 0, 0, $time1["tm_mon"] + 1, $time1["tm_mday"], $time1["tm_year"] + 1900);
 		}
 		
diff -ruN /usr/src/zarafa/zarafa-6.30.4.17264/php-ext/include/mapi/mapiguid.php mapi/mapiguid.php
--- /usr/src/zarafa/zarafa-6.30.4.17264/php-ext/include/mapi/mapiguid.php	Fri Oct 16 21:05:22 2009
+++ mapi/mapiguid.php	Tue Oct 20 19:29:54 2009
@@ -67,4 +67,7 @@
 define('PS_MAPI',                               makeguid("{00020328-0000-0000-C000-000000000046}"));
 define('PS_PUBLIC_STRINGS',                     makeguid("{00020329-0000-0000-C000-000000000046}"));
 define('PS_INTERNET_HEADERS',                   makeguid("{00020386-0000-0000-c000-000000000046}"));
+
+define('MAPIUID_LinkContactEntryID',		makeguid("{0aaa42fe-c718-101a-e885-0b651c240000}")); // http://msdn.microsoft.com/en-us/library/bb820924.aspx misc2 in CONTAB structure in Internet This parameter is reserved for Outlook internal use and is not supported.
+
 ?>
diff -ruN /usr/src/zarafa/zarafa-6.30.4.17264/php-ext/include/mapi/mapitags.php mapi/mapitags.php
--- /usr/src/zarafa/zarafa-6.30.4.17264/php-ext/include/mapi/mapitags.php	Fri Oct 16 21:05:22 2009
+++ mapi/mapitags.php	Tue Oct 20 19:29:54 2009
@@ -601,7 +601,25 @@
 define('PR_FINDER_ENTRYID'                            ,mapi_prop_tag(PT_BINARY,      0x35E7));
 define('PR_IPM_FAVORITES_ENTRYID'                     ,mapi_prop_tag(PT_BINARY,      0x6630));
 define('PR_IPM_PUBLIC_FOLDERS_ENTRYID'                ,mapi_prop_tag(PT_BINARY,      0x6631));
+//* start: Added dw2412 source www.cdolive.com/cdo10.htm
+define('PR_HAS_RULES'				      ,mapi_prop_tag(PT_BINARY,	     0x663A));
 
+// Outlook AutoArchive Properties
+define('PR_AGING_PERIOD'			      ,mapi_prop_tag(PT_LONG,	     0x36EC));
+define('PR_AGING_GRANULARITY'			      ,mapi_prop_tag(PT_LONG,	     0x36EE));
+define('PR_AGING_FILENAME'			      ,mapi_prop_tag(PT_TSTRING,     0x6856));
+define('PR_AGING_AGE_FOLDER'			      ,mapi_prop_tag(PT_BOOLEAN,     0x6857));
+define('PR_AGING_DELETE_ITEMS'			      ,mapi_prop_tag(PT_BOOLEAN,     0x6855));
+define('PR_AGING_FILE_NAME_AFTER9'		      ,mapi_prop_tag(PT_TSTRING,     0x6859));
+define('PR_AGING_DONT_AGE_ME'			      ,mapi_prop_tag(PT_BOOLEAN,     0x6858));
+define('PR_AGING_WHEN_DELETED_ON_SERVER'	      ,mapi_prop_tag(PT_BOOLEAN,     0x685B));
+define('PR_AGING_WAIT_UNTIL_EXPIRED'		      ,mapi_prop_tag(PT_BOOLEAN,     0x685C));
+define('PR_AGING_VERSION'			      ,mapi_prop_tag(PT_LONG,	     0x685D));
+define('PR_AGING_DEFAULT'			      ,mapi_prop_tag(PT_LONG,	     0x685E));
+
+
+
+//* End  : added dw2412
 
 /* Proptags 0x35E8-0x35FF reserved for folders "guaranteed" by 'PR_VALID_FOLDER_MASK */
 
@@ -637,6 +655,19 @@
 define('PR_DEFAULT_VIEW_ENTRYID'                      ,mapi_prop_tag(PT_BINARY,      0x3616));
 define('PR_ASSOC_CONTENT_COUNT'                       ,mapi_prop_tag(PT_LONG,        0x3617));
 
+//* start: Added dw2412 source www.cdolive.com/cdo10.htm
+define('PR_DEF_FORM_ALLOWED'			      ,mapi_prop_tag(PT_LONG,	     0x3FE2));
+define('PR_PUBLISH_IN_ADDRESS_BOOK'		      ,mapi_prop_tag(PT_BOOLEAN,     0x3FE6));
+define('PR_WEBPAGE'				      ,mapi_prop_tag(PT_TSTRING,     0x36DF));
+define('PR_FOLDER_VIEWS_ONLY'			      ,mapi_prop_tag(PT_LONG,	     0x36E1));
+define('PR_DEF_MSG_CLASS'			      ,mapi_prop_tag(PT_TSTRING,     0x36E5));
+define('PR_DEF_FORM_NAME'			      ,mapi_prop_tag(PT_TSTRING,     0x36E6));
+define('PR_GENERATE_EXCHANGE_VIEWS'		      ,mapi_prop_tag(PT_BOOLEAN,     0x36E9));
+define('PR_VIEW_NAME'				      ,mapi_prop_tag(PT_TSTRING,     0x7006));
+define('PR_OFFLINE_FLAG'			      ,mapi_prop_tag(PT_LONG,        0x663D));
+define('PR_REPLICA_VERSION'			      ,mapi_prop_tag(PT_LONG,        0x664B));
+//* end  : Added dw2412
+
 define('PR_RIGHTS'                                    ,mapi_prop_tag(PT_LONG,        0x6639));
 
 /* Reserved 0x36C0-0x36FF */
@@ -1231,6 +1262,9 @@
 
 define('PR_PROCESSED', mapi_prop_tag(PT_BOOLEAN, 0x7D01));
 
+// ADDED dw2412 Contact Photo Attachment
+define('PR_ATTACHMENT_CONTACTPHOTO'			,mapi_prop_tag(PT_BOOLEAN,	0x7FFF));
+
 // Delegates properties 
 define('PR_DELEGATES_SEE_PRIVATE', mapi_prop_tag(PT_MV_LONG, 0x686B));
 define('PR_SCHDINFO_DELEGATE_ENTRYIDS', mapi_prop_tag(PT_MV_BINARY, 0x6845));
--- /usr/src/zarafa/zarafa-6.30.4.17264/php-ext/Makefile.am			2009-10-16 15:55:59.000000000 +0200
+++ zarafa-6.30.4/php-ext/Makefile.am.brodowski		2009-10-24 23:48:37.000000000 +0200
@@ -23,7 +23,7 @@
 # and be missing at runtime.
 # therefore, we explicitly link mapi.so with -lpthread :(
 
-dist_data_DATA = include/mapi/mapicode.php include/mapi/mapidefs.php include/mapi/mapitags.php include/mapi/mapi.util.php include/mapi/class.recurrence.php include/mapi/class.meetingrequest.php include/mapi/class.freebusypublish.php include/mapi/mapiguid.php
+dist_data_DATA = include/mapi/mapicode.php include/mapi/mapidefs.php include/mapi/mapitags.php include/mapi/mapi.util.php include/mapi/class.recurrence.php include/mapi/class.meetingrequest.php include/mapi/class.freebusypublish.php include/mapi/mapiguid.php include/mapi/class.autoarchivesettings.php include/mapi/class.linkedappointment.php
 datadir = ${datarootdir}/php/mapi
 
 mapi_la_SOURCES = main.cpp Session.cpp SessionPool.cpp util.cpp \