| 1 |  |  | <?php | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3 |  |  | /* | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4 |  |  |  * SPDX-License-Identifier: AGPL-3.0-only | 
            
                                                                                                            
                            
            
                                    
            
            
                | 5 |  |  |  * SPDX-FileCopyrightText: Copyright 2005-2016 Zarafa Deutschland GmbH | 
            
                                                                                                            
                            
            
                                    
            
            
                | 6 |  |  |  * SPDX-FileCopyrightText: Copyright 2020-2025 grommunio GmbH | 
            
                                                                                                            
                            
            
                                    
            
            
                | 7 |  |  |  */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 8 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 9 |  |  | /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 10 |  |  |  * Recurrence. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 11 |  |  |  */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 12 |  |  | class Recurrence extends BaseRecurrence { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 13 |  |  | 	/* | 
            
                                                                                                            
                            
            
                                    
            
            
                | 14 |  |  | 	 * ABOUT TIMEZONES | 
            
                                                                                                            
                            
            
                                    
            
            
                | 15 |  |  | 	 * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 16 |  |  | 	 * Timezones are rather complicated here so here are some rules to think about: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 17 |  |  | 	 * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 18 |  |  | 	 * - Timestamps in mapi-like properties (so in PT_SYSTIME properties) are always in GMT (including | 
            
                                                                                                            
                            
            
                                    
            
            
                | 19 |  |  | 	 *   the 'basedate' property in exceptions !!) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 20 |  |  | 	 * - Timestamps for recurrence (so start/end of recurrence, and basedates for exceptions (everything | 
            
                                                                                                            
                            
            
                                    
            
            
                | 21 |  |  | 	 *   outside the 'basedate' property in the exception !!), and start/endtimes for exceptions) are | 
            
                                                                                                            
                            
            
                                    
            
            
                | 22 |  |  | 	 *   always in LOCAL time. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 23 |  |  | 	 */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 24 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 25 |  |  | 	// All properties for a recipient that are interesting | 
            
                                                                                                            
                            
            
                                    
            
            
                | 26 |  |  | 	public $recipprops = [ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 27 |  |  | 		PR_ENTRYID, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 28 |  |  | 		PR_SEARCH_KEY, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 29 |  |  | 		PR_DISPLAY_NAME, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 30 |  |  | 		PR_EMAIL_ADDRESS, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 31 |  |  | 		PR_RECIPIENT_ENTRYID, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 32 |  |  | 		PR_RECIPIENT_TYPE, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 33 |  |  | 		PR_SEND_INTERNET_ENCODING, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 34 |  |  | 		PR_SEND_RICH_INFO, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 35 |  |  | 		PR_RECIPIENT_DISPLAY_NAME, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 36 |  |  | 		PR_ADDRTYPE, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 37 |  |  | 		PR_DISPLAY_TYPE, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 38 |  |  | 		PR_DISPLAY_TYPE_EX, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 39 |  |  | 		PR_RECIPIENT_TRACKSTATUS, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 40 |  |  | 		PR_RECIPIENT_TRACKSTATUS_TIME, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 41 |  |  | 		PR_RECIPIENT_FLAGS, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 42 |  |  | 		PR_ROWID, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 43 |  |  | 	]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 44 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 45 |  |  | 	/** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 46 |  |  | 	 * Constructor. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 47 |  |  | 	 * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 48 |  |  | 	 * @param resource $store    MAPI Message Store Object | 
            
                                                                                                            
                            
            
                                    
            
            
                | 49 |  |  | 	 * @param mixed    $message  the MAPI (appointment) message | 
            
                                                                                                            
                            
            
                                    
            
            
                | 50 |  |  | 	 * @param array    $proptags an associative array of protags and their values | 
            
                                                                                                            
                            
            
                                    
            
            
                | 51 |  |  | 	 */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 52 |  |  | 	public function __construct(mixed $store, mixed $message, array $proptags = []) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 53 |  |  | 		if (!empty($proptags)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 54 |  |  | 			$this->proptags = $proptags; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 55 |  |  | 		} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 56 |  |  | 		else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 57 |  |  | 			$properties = []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 58 |  |  | 			$properties["entryid"] = PR_ENTRYID; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 59 |  |  | 			$properties["parent_entryid"] = PR_PARENT_ENTRYID; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 60 |  |  | 			$properties["message_class"] = PR_MESSAGE_CLASS; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 61 |  |  | 			$properties["icon_index"] = PR_ICON_INDEX; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 62 |  |  | 			$properties["subject"] = PR_SUBJECT; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 63 |  |  | 			$properties["display_to"] = PR_DISPLAY_TO; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 64 |  |  | 			$properties["importance"] = PR_IMPORTANCE; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 65 |  |  | 			$properties["sensitivity"] = PR_SENSITIVITY; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 66 |  |  | 			$properties["startdate"] = "PT_SYSTIME:PSETID_Appointment:" . PidLidAppointmentStartWhole; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 67 |  |  | 			$properties["duedate"] = "PT_SYSTIME:PSETID_Appointment:" . PidLidAppointmentEndWhole; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 68 |  |  | 			$properties["recurring"] = "PT_BOOLEAN:PSETID_Appointment:" . PidLidRecurring; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 69 |  |  | 			$properties["recurring_data"] = "PT_BINARY:PSETID_Appointment:" . PidLidAppointmentRecur; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 70 |  |  | 			$properties["busystatus"] = "PT_LONG:PSETID_Appointment:" . PidLidBusyStatus; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 71 |  |  | 			$properties["label"] = "PT_LONG:PSETID_Appointment:0x8214"; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 72 |  |  | 			$properties["alldayevent"] = "PT_BOOLEAN:PSETID_Appointment:" . PidLidAppointmentSubType; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 73 |  |  | 			$properties["private"] = "PT_BOOLEAN:PSETID_Common:" . PidLidPrivate; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 74 |  |  | 			$properties["meeting"] = "PT_LONG:PSETID_Appointment:" . PidLidAppointmentStateFlags; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 75 |  |  | 			$properties["startdate_recurring"] = "PT_SYSTIME:PSETID_Appointment:" . PidLidClipStart; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 76 |  |  | 			$properties["enddate_recurring"] = "PT_SYSTIME:PSETID_Appointment:" . PidLidClipEnd; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 77 |  |  | 			$properties["recurring_pattern"] = "PT_STRING8:PSETID_Appointment:" . PidLidRecurrencePattern; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 78 |  |  | 			$properties["location"] = "PT_STRING8:PSETID_Appointment:" . PidLidLocation; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 79 |  |  | 			$properties["duration"] = "PT_LONG:PSETID_Appointment:" . PidLidAppointmentDuration; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 80 |  |  | 			$properties["responsestatus"] = "PT_LONG:PSETID_Appointment:0x8218"; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 81 |  |  | 			$properties["reminder"] = "PT_BOOLEAN:PSETID_Common:" . PidLidReminderSet; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 82 |  |  | 			$properties["reminder_minutes"] = "PT_LONG:PSETID_Common:" . PidLidReminderDelta; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 83 |  |  | 			$properties["recurrencetype"] = "PT_LONG:PSETID_Appointment:0x8231"; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 84 |  |  | 			$properties["contacts"] = "PT_MV_STRING8:PSETID_Common:0x853a"; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 85 |  |  | 			$properties["contacts_string"] = "PT_STRING8:PSETID_Common:0x8586"; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 86 |  |  | 			$properties["categories"] = "PT_MV_STRING8:PS_PUBLIC_STRINGS:Keywords"; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 87 |  |  | 			$properties["reminder_time"] = "PT_SYSTIME:PSETID_Common:" . PidLidReminderTime; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 88 |  |  | 			$properties["commonstart"] = "PT_SYSTIME:PSETID_Common:0x8516"; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 89 |  |  | 			$properties["commonend"] = "PT_SYSTIME:PSETID_Common:0x8517"; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 90 |  |  | 			$properties["basedate"] = "PT_SYSTIME:PSETID_Appointment:" . PidLidExceptionReplaceTime; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 91 |  |  | 			$properties["timezone_data"] = "PT_BINARY:PSETID_Appointment:" . PidLidTimeZoneStruct; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 92 |  |  | 			$properties["timezone"] = "PT_STRING8:PSETID_Appointment:" . PidLidTimeZoneDescription; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 93 |  |  | 			$properties["flagdueby"] = "PT_SYSTIME:PSETID_Common:" . PidLidReminderSignalTime; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 94 |  |  | 			$properties["side_effects"] = "PT_LONG:PSETID_Common:0x8510"; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 95 |  |  | 			$properties["hideattachments"] = "PT_BOOLEAN:PSETID_Common:" . PidLidSmartNoAttach; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 96 |  |  | 			$properties['meetingrecurring'] = "PT_BOOLEAN:PSETID_Meeting:" . PidLidIsRecurring; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 97 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 98 |  |  | 			$this->proptags = getPropIdsFromStrings($store, $properties); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 99 |  |  | 		} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 100 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 101 |  |  | 		parent::__construct($store, $message); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 102 |  |  | 	} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 103 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 104 |  |  | 	/** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 105 |  |  | 	 * Create an exception. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 106 |  |  | 	 * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 107 |  |  | 	 * @param array $exception_props  the exception properties (same properties as normal recurring items) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 108 |  |  | 	 * @param mixed $base_date        the base date of the exception (LOCAL time of non-exception occurrence) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 109 |  |  | 	 * @param bool  $delete           true - delete occurrence, false - create new exception or modify existing | 
            
                                                                                                            
                            
            
                                    
            
            
                | 110 |  |  | 	 * @param array $exception_recips list of recipients | 
            
                                                                                                            
                            
            
                                    
            
            
                | 111 |  |  | 	 * @param mixed $copy_attach_from mapi message from which attachments should be copied | 
            
                                                                                                            
                            
            
                                    
            
            
                | 112 |  |  | 	 */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 113 |  |  | 	public function createException($exception_props, $base_date, $delete = false, $exception_recips = [], $copy_attach_from = false): bool { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 114 |  |  | 		$baseday = $this->dayStartOf($base_date); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 115 |  |  | 		$basetime = $baseday + $this->recur["startocc"] * 60; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 116 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 117 |  |  | 		// Remove any pre-existing exception on this base date | 
            
                                                                                                            
                            
            
                                    
            
            
                | 118 |  |  | 		if ($this->isException($baseday)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 119 |  |  | 			$this->deleteException($baseday); // note that deleting an exception is different from creating a deleted exception (deleting an occurrence). | 
            
                                                                                                            
                            
            
                                    
            
            
                | 120 |  |  | 		} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 121 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 122 |  |  | 		if (!$delete) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 123 |  |  | 			if (isset($exception_props[$this->proptags["startdate"]]) && !$this->isValidExceptionDate($base_date, $this->fromGMT($this->tz, $exception_props[$this->proptags["startdate"]]))) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 124 |  |  | 				return false; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 125 |  |  | 			} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 126 |  |  | 			$changed_item = []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 127 |  |  | 			// Properties in the attachment are the properties of the base object, plus $exception_props plus the base date | 
            
                                                                                                            
                            
            
                                    
            
            
                | 128 |  |  | 			foreach (["subject", "location", "label", "reminder", "reminder_minutes", "alldayevent", "busystatus"] as $propname) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 129 |  |  | 				if (isset($this->messageprops[$this->proptags[$propname]])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 130 |  |  | 					$props[$this->proptags[$propname]] = $this->messageprops[$this->proptags[$propname]]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 131 |  |  | 					if (isset($exception_props[$this->proptags[$propname]]) && | 
            
                                                                                                            
                            
            
                                    
            
            
                | 132 |  |  | 						$this->messageprops[$this->proptags[$propname]] != $exception_props[$this->proptags[$propname]]) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 133 |  |  | 						$changed_item[$propname] = $exception_props[$this->proptags[$propname]]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 134 |  |  | 					} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 135 |  |  | 				} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 136 |  |  | 				elseif (isset($exception_props[$this->proptags[$propname]])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 137 |  |  | 					$changed_item[$propname] = $exception_props[$this->proptags[$propname]]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 138 |  |  | 				} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 139 |  |  | 			} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 140 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 141 |  |  | 			$props[PR_MESSAGE_CLASS] = "IPM.OLE.CLASS.{00061055-0000-0000-C000-000000000046}"; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 142 |  |  | 			unset($exception_props[PR_MESSAGE_CLASS], $exception_props[PR_ICON_INDEX]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 143 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 144 |  |  | 			$props = $exception_props + $props; | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 145 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 146 |  |  | 			// Basedate in the exception attachment is the GMT time at which the original occurrence would have been | 
            
                                                                                                            
                            
            
                                    
            
            
                | 147 |  |  | 			$props[$this->proptags["basedate"]] = $this->toGMT($this->tz, $basetime); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 148 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 149 |  |  | 			if (!isset($exception_props[$this->proptags["startdate"]])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 150 |  |  | 				$props[$this->proptags["startdate"]] = $this->getOccurrenceStart($base_date); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 151 |  |  | 			} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 152 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 153 |  |  | 			if (!isset($exception_props[$this->proptags["duedate"]])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 154 |  |  | 				$props[$this->proptags["duedate"]] = $this->getOccurrenceEnd($base_date); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 155 |  |  | 			} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 156 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 157 |  |  | 			// synchronize commonstart/commonend with startdate/duedate | 
            
                                                                                                            
                            
            
                                    
            
            
                | 158 |  |  | 			if (isset($props[$this->proptags["startdate"]])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 159 |  |  | 				$props[$this->proptags["commonstart"]] = $props[$this->proptags["startdate"]]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 160 |  |  | 			} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 161 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 162 |  |  | 			if (isset($props[$this->proptags["duedate"]])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 163 |  |  | 				$props[$this->proptags["commonend"]] = $props[$this->proptags["duedate"]]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 164 |  |  | 			} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 165 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 166 |  |  | 			// Save the data into an attachment | 
            
                                                                                                            
                            
            
                                    
            
            
                | 167 |  |  | 			$this->createExceptionAttachment($props, $exception_recips, $copy_attach_from); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 168 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 169 |  |  | 			$changed_item["basedate"] = $baseday; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 170 |  |  | 			$changed_item["start"] = $this->fromGMT($this->tz, $props[$this->proptags["startdate"]]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 171 |  |  | 			$changed_item["end"] = $this->fromGMT($this->tz, $props[$this->proptags["duedate"]]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 172 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 173 |  |  | 			// Add the changed occurrence to the list | 
            
                                                                                                            
                            
            
                                    
            
            
                | 174 |  |  | 			$this->recur["changed_occurrences"][] = $changed_item; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 175 |  |  | 		} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 176 |  |  | 		else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 177 |  |  | 			// Delete the occurrence by placing it in the deleted occurrences list | 
            
                                                                                                            
                            
            
                                    
            
            
                | 178 |  |  | 			$this->recur["deleted_occurrences"][] = $baseday; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 179 |  |  | 		} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 180 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 181 |  |  | 		// Turn on hideattachments, because the attachments in this item are the exceptions | 
            
                                                                                                            
                            
            
                                    
            
            
                | 182 |  |  | 		mapi_setprops($this->message, [$this->proptags["hideattachments"] => true]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 183 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 184 |  |  | 		// Save recurrence data to message | 
            
                                                                                                            
                            
            
                                    
            
            
                | 185 |  |  | 		$this->saveRecurrence(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 186 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 187 |  |  | 		return true; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 188 |  |  | 	} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 189 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 190 |  |  | 	/** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 191 |  |  | 	 * Modifies an existing exception, but only updates the given properties | 
            
                                                                                                            
                            
            
                                    
            
            
                | 192 |  |  | 	 * NOTE: You can't remove properties from an exception, only add new ones. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 193 |  |  | 	 * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 194 |  |  | 	 * @param mixed $exception_props | 
            
                                                                                                            
                            
            
                                    
            
            
                | 195 |  |  | 	 * @param mixed $base_date | 
            
                                                                                                            
                            
            
                                    
            
            
                | 196 |  |  | 	 * @param mixed $exception_recips | 
            
                                                                                                            
                            
            
                                    
            
            
                | 197 |  |  | 	 * @param mixed $copy_attach_from | 
            
                                                                                                            
                            
            
                                    
            
            
                | 198 |  |  | 	 */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 199 |  |  | 	public function modifyException($exception_props, $base_date, $exception_recips = [], $copy_attach_from = false): bool { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 200 |  |  | 		if (isset($exception_props[$this->proptags["startdate"]]) && !$this->isValidExceptionDate($base_date, $this->fromGMT($this->tz, $exception_props[$this->proptags["startdate"]]))) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 201 |  |  | 			return false; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 202 |  |  | 		} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 203 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 204 |  |  | 		$baseday = $this->dayStartOf($base_date); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 205 |  |  | 		$extomodify = false; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 206 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 207 |  |  | 		for ($i = 0, $len = count($this->recur["changed_occurrences"]); $i < $len; ++$i) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 208 |  |  | 			if ($this->isSameDay($this->recur["changed_occurrences"][$i]["basedate"], $baseday)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 209 |  |  | 				$extomodify = &$this->recur["changed_occurrences"][$i]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 210 |  |  | 				break; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 211 |  |  | 			} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 212 |  |  | 		} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 213 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 214 |  |  | 		if (!$extomodify) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 215 |  |  | 			return false; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 216 |  |  | 		} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 217 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 218 |  |  | 		// remove basedate property as we want to preserve the old value | 
            
                                                                                                            
                            
            
                                    
            
            
                | 219 |  |  | 		// client will send basedate with time part as zero, so discard that value | 
            
                                                                                                            
                            
            
                                    
            
            
                | 220 |  |  | 		unset($exception_props[$this->proptags["basedate"]]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 221 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 222 |  |  | 		// Map of property keys to their target keys in $extomodify, with optional transformation | 
            
                                                                                                            
                            
            
                                    
            
            
                | 223 |  |  | 		$propertyMappings = [ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 224 |  |  | 			"startdate" => ["target" => "start", "transform" => true], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 225 |  |  | 			"duedate" => ["target" => "end", "transform" => true], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 226 |  |  | 			"subject" => ["target" => "subject", "transform" => false], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 227 |  |  | 			"location" => ["target" => "location", "transform" => false], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 228 |  |  | 			"label" => ["target" => "label", "transform" => false], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 229 |  |  | 			"reminder" => ["target" => "reminder_set", "transform" => false], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 230 |  |  | 			"reminder_minutes" => ["target" => "remind_before", "transform" => false], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 231 |  |  | 			"alldayevent" => ["target" => "alldayevent", "transform" => false], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 232 |  |  | 			"busystatus" => ["target" => "busystatus", "transform" => false], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 233 |  |  | 		]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 234 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 235 |  |  | 		foreach ($propertyMappings as $propKey => $mapping) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 236 |  |  | 			$propTag = $this->proptags[$propKey]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 237 |  |  | 			if (array_key_exists($propTag, $exception_props)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 238 |  |  | 				$extomodify[$mapping["target"]] = $mapping["transform"] ? | 
            
                                                                                                            
                            
            
                                    
            
            
                | 239 |  |  | 					$this->fromGMT($this->tz, $exception_props[$propTag]) : | 
            
                                                                                                            
                            
            
                                    
            
            
                | 240 |  |  | 					$exception_props[$propTag]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 241 |  |  | 			} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 242 |  |  | 		} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 243 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 244 |  |  | 		$exception_props[PR_MESSAGE_CLASS] = "IPM.OLE.CLASS.{00061055-0000-0000-C000-000000000046}"; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 245 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 246 |  |  | 		// synchronize commonstart/commonend with startdate/duedate | 
            
                                                                                                            
                            
            
                                    
            
            
                | 247 |  |  | 		if (isset($exception_props[$this->proptags["startdate"]])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 248 |  |  | 			$exception_props[$this->proptags["commonstart"]] = $exception_props[$this->proptags["startdate"]]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 249 |  |  | 		} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 250 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 251 |  |  | 		if (isset($exception_props[$this->proptags["duedate"]])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 252 |  |  | 			$exception_props[$this->proptags["commonend"]] = $exception_props[$this->proptags["duedate"]]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 253 |  |  | 		} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 254 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 255 |  |  | 		$attach = $this->getExceptionAttachment($baseday); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 256 |  |  | 		if (!$attach) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 257 |  |  | 			if ($copy_attach_from) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 258 |  |  | 				$this->deleteExceptionAttachment($base_date); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 259 |  |  | 				$this->createException($exception_props, $base_date, false, $exception_recips, $copy_attach_from); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 260 |  |  | 			} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 261 |  |  | 			else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 262 |  |  | 				$this->createExceptionAttachment($exception_props, $exception_recips, $copy_attach_from); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 263 |  |  | 			} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 264 |  |  | 		} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 265 |  |  | 		else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 266 |  |  | 			$message = mapi_attach_openobj($attach, MAPI_MODIFY); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 267 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 268 |  |  | 			// Set exception properties on embedded message and save | 
            
                                                                                                            
                            
            
                                    
            
            
                | 269 |  |  | 			mapi_setprops($message, $exception_props); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 270 |  |  | 			$this->setExceptionRecipients($message, $exception_recips, false); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 271 |  |  | 			mapi_savechanges($message); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 272 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 273 |  |  | 			// If a new start or duedate is provided, we update the properties 'PR_EXCEPTION_STARTTIME' and 'PR_EXCEPTION_ENDTIME' | 
            
                                                                                                            
                            
            
                                    
            
            
                | 274 |  |  | 			// on the attachment which holds the embedded msg and save everything. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 275 |  |  | 			$props = []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 276 |  |  | 			if (isset($exception_props[$this->proptags["startdate"]])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 277 |  |  | 				$props[PR_EXCEPTION_STARTTIME] = $this->fromGMT($this->tz, $exception_props[$this->proptags["startdate"]]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 278 |  |  | 			} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 279 |  |  | 			if (isset($exception_props[$this->proptags["duedate"]])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 280 |  |  | 				$props[PR_EXCEPTION_ENDTIME] = $this->fromGMT($this->tz, $exception_props[$this->proptags["duedate"]]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 281 |  |  | 			} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 282 |  |  | 			if (!empty($props)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 283 |  |  | 				mapi_setprops($attach, $props); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 284 |  |  | 			} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 285 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 286 |  |  | 			mapi_savechanges($attach); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 287 |  |  | 		} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 288 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 289 |  |  | 		// Save recurrence data to message | 
            
                                                                                                            
                            
            
                                    
            
            
                | 290 |  |  | 		$this->saveRecurrence(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 291 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 292 |  |  | 		return true; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 293 |  |  | 	} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 294 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 295 |  |  | 	// Checks to see if the following is true: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 296 |  |  | 	// 1) The exception to be created doesn't create two exceptions starting on one day (however, they can END on the same day by modifying duration) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 297 |  |  | 	// 2) The exception to be created doesn't 'jump' over another occurrence (which may be an exception itself!) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 298 |  |  | 	// | 
            
                                                                                                            
                            
            
                                    
            
            
                | 299 |  |  | 	// Both $basedate and $start are in LOCAL time | 
            
                                                                                                            
                            
            
                                    
            
            
                | 300 |  |  | 	public function isValidExceptionDate($basedate, $start): bool { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 301 |  |  | 		// The way we do this is to look at the days that we're 'moving' the item in the exception. Each | 
            
                                                                                                            
                            
            
                                    
            
            
                | 302 |  |  | 		// of these days may only contain the item that we're modifying. Any other item violates the rules. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 303 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 304 |  |  | 		if ($this->isException($basedate)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 305 |  |  | 			// If we're modifying an exception, we want to look at the days that we're 'moving' compared to where | 
            
                                                                                                            
                            
            
                                    
            
            
                | 306 |  |  | 			// the exception used to be. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 307 |  |  | 			$oldexception = $this->getChangeException($basedate); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 308 |  |  | 			$prevday = $this->dayStartOf($oldexception["start"]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 309 |  |  | 		} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 310 |  |  | 		else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 311 |  |  | 			// If its a new exception, we want to look at the original placement of this item. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 312 |  |  | 			$prevday = $basedate; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 313 |  |  | 		} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 314 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 315 |  |  | 		$startday = $this->dayStartOf($start); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 316 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 317 |  |  | 		// Get all the occurrences on the days between the basedate (may be reversed) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 318 |  |  | 		if ($prevday < $startday) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 319 |  |  | 			$items = $this->getItems($this->toGMT($this->tz, $prevday), $this->toGMT($this->tz, $startday + 24 * 60 * 60)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 320 |  |  | 		} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 321 |  |  | 		else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 322 |  |  | 			$items = $this->getItems($this->toGMT($this->tz, $startday), $this->toGMT($this->tz, $prevday + 24 * 60 * 60)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 323 |  |  | 		} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 324 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 325 |  |  | 		// There should now be exactly one item, namely the item that we are modifying. If there are any other items in the range, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 326 |  |  | 		// then we abort the change, since one of the rules has been violated. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 327 |  |  | 		return count($items) == 1; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 328 |  |  | 	} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 329 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 330 |  |  | 	/** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 331 |  |  | 	 * Check to see if the exception proposed at a certain basedate is allowed concerning reminder times:. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 332 |  |  | 	 * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 333 |  |  | 	 * Both must be true: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 334 |  |  | 	 * - reminder time of this item is not before the starttime of the previous recurring item | 
            
                                                                                                            
                            
            
                                    
            
            
                | 335 |  |  | 	 * - reminder time of the next item is not before the starttime of this item | 
            
                                                                                                            
                            
            
                                    
            
            
                | 336 |  |  | 	 * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 337 |  |  | 	 * @param int $basedate        the base date of the exception (LOCAL time of non-exception occurrence) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 338 |  |  | 	 * @param int $reminderminutes reminder minutes which is set of the item | 
            
                                                                                                            
                            
            
                                    
            
            
                | 339 |  |  | 	 * @param int $startdate       the startdate of the selected item | 
            
                                                                                                            
                            
            
                                    
            
            
                | 340 |  |  | 	 * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 341 |  |  | 	 * @returns boolean if the reminder minutes value valid (FALSE if either of the rules above are FALSE) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 342 |  |  | 	 */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 343 |  |  | 	public function isValidReminderTime($basedate, $reminderminutes, $startdate): bool { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 344 |  |  | 		// get all occurrence items before the selected items occurrence starttime | 
            
                                                                                                            
                            
            
                                    
            
            
                | 345 |  |  | 		$occitems = $this->getItems($this->messageprops[$this->proptags["startdate"]], $this->toGMT($this->tz, $basedate)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 346 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 347 |  |  | 		if (!empty($occitems)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 348 |  |  | 			// as occitems array is sorted in ascending order of startdate, to get the previous occurrence we take the last items in occitems . | 
            
                                                                                                            
                            
            
                                    
            
            
                | 349 |  |  | 			$previousitem_startdate = $occitems[count($occitems) - 1][$this->proptags["startdate"]]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 350 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 351 |  |  | 			// if our reminder is set before or equal to the beginning of the previous occurrence, then that's not allowed | 
            
                                                                                                            
                            
            
                                    
            
            
                | 352 |  |  | 			if ($startdate - ($reminderminutes * 60) <= $previousitem_startdate) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 353 |  |  | 				return false; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 354 |  |  | 			} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 355 |  |  | 		} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 356 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 357 |  |  | 		// Get the endtime of the current occurrence and find the next two occurrences (including the current occurrence) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 358 |  |  | 		$currentOcc = $this->getItems($this->toGMT($this->tz, $basedate), 0x7FF00000, 2, true); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 359 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 360 |  |  | 		// If there are another two occurrences, then the first is the current occurrence, and the one after that | 
            
                                                                                                            
                            
            
                                    
            
            
                | 361 |  |  | 		// is the next occurrence. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 362 |  |  | 		if (count($currentOcc) > 1) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 363 |  |  | 			$next = $currentOcc[1]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 364 |  |  | 			// Get reminder time of the next occurrence. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 365 |  |  | 			$nextOccReminderTime = $next[$this->proptags["startdate"]] - ($next[$this->proptags["reminder_minutes"]] * 60); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 366 |  |  | 			// If the reminder time of the next item is before the start of this item, then that's not allowed | 
            
                                                                                                            
                            
            
                                    
            
            
                | 367 |  |  | 			if ($nextOccReminderTime <= $startdate) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 368 |  |  | 				return false; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 369 |  |  | 			} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 370 |  |  | 		} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 371 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 372 |  |  | 		// All was ok | 
            
                                                                                                            
                            
            
                                    
            
            
                | 373 |  |  | 		return true; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 374 |  |  | 	} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 375 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 376 |  |  | 	public function setRecurrence(mixed $tz, mixed $recur): void { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 377 |  |  | 		// only reset timezone if specified | 
            
                                                                                                            
                            
            
                                    
            
            
                | 378 |  |  | 		if ($tz) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 379 |  |  | 			$this->tz = $tz; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 380 |  |  | 		} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 381 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 382 |  |  | 		$this->recur = $recur; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 383 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 384 |  |  | 		if (!isset($this->recur["changed_occurrences"])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 385 |  |  | 			$this->recur["changed_occurrences"] = []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 386 |  |  | 		} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 387 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 388 |  |  | 		if (!isset($this->recur["deleted_occurrences"])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 389 |  |  | 			$this->recur["deleted_occurrences"] = []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 390 |  |  | 		} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 391 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 392 |  |  | 		$this->deleteAttachments(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 393 |  |  | 		$this->saveRecurrence(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 394 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 395 |  |  | 		// if client has not set the recurring_pattern then we should generate it and save it | 
            
                                                                                                            
                            
            
                                    
            
            
                | 396 |  |  | 		$messageProps = mapi_getprops($this->message, [$this->proptags["recurring_pattern"]]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 397 |  |  | 		if (empty($messageProps[$this->proptags["recurring_pattern"]])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 398 |  |  | 			$this->saveRecurrencePattern(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 399 |  |  | 		} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 400 |  |  | 	} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 401 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 402 |  |  | 	// Returns the start or end time of the occurrence on the given base date. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 403 |  |  | 	// This assumes that the basedate you supply is in LOCAL time | 
            
                                                                                                            
                            
            
                                    
            
            
                | 404 |  |  | 	public function getOccurrenceStart(int $basedate): int { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 405 |  |  | 		$daystart = $this->dayStartOf($basedate); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 406 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 407 |  |  | 		return $this->toGMT($this->tz, $daystart + $this->recur["startocc"] * 60); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 408 |  |  | 	} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 409 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 410 |  |  | 	public function getOccurrenceEnd(int $basedate): int { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 411 |  |  | 		$daystart = $this->dayStartOf($basedate); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 412 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 413 |  |  | 		return $this->toGMT($this->tz, $daystart + $this->recur["endocc"] * 60); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 414 |  |  | 	} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 415 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 416 |  |  | 	/** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 417 |  |  | 	 * This function returns the next remindertime starting from $timestamp | 
            
                                                                                                            
                            
            
                                    
            
            
                | 418 |  |  | 	 * When no next reminder exists, false is returned. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 419 |  |  | 	 * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 420 |  |  | 	 * Note: Before saving this new reminder time (when snoozing), you must check for | 
            
                                                                                                            
                            
            
                                    
            
            
                | 421 |  |  | 	 *       yourself if this reminder time is earlier than your snooze time, else | 
            
                                                                                                            
                            
            
                                    
            
            
                | 422 |  |  | 	 *       use your snooze time and not this reminder time. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 423 |  |  | 	 */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 424 |  |  | 	public function getNextReminderTime(int $timestamp): false|int { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 425 |  |  | 		/** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 426 |  |  | 		 * Get next item from now until forever, but max 1 item with reminder set | 
            
                                                                                                            
                            
            
                                    
            
            
                | 427 |  |  | 		 * Note 0x7ff00000 instead of 0x7fffffff because of possible overflow failures when converting to GMT.... | 
            
                                                                                                            
                            
            
                                    
            
            
                | 428 |  |  | 		 * Here for getting next 10 occurrences assuming that next here we will be able to find | 
            
                                                                                                            
                            
            
                                    
            
            
                | 429 |  |  | 		 * nextreminder occurrence in 10 occurrences. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 430 |  |  | 		 */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 431 |  |  | 		$items = $this->getItems($timestamp, 0x7FF00000, 10, true); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 432 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 433 |  |  | 		// Initially setting nextreminder to false so when no next reminder exists, false is returned. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 434 |  |  | 		$nextreminder = false; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 435 |  |  | 		/* | 
            
                                                                                                            
                            
            
                                    
            
            
                | 436 |  |  | 		 * Loop through all reminder which we get in items variable | 
            
                                                                                                            
                            
            
                                    
            
            
                | 437 |  |  | 		 * and check whether the remindertime is greater than timestamp. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 438 |  |  | 		 * On the first occurrence of greater nextreminder break the loop | 
            
                                                                                                            
                            
            
                                    
            
            
                | 439 |  |  | 		 * and return the value to calling function. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 440 |  |  | 		 */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 441 |  |  | 		for ($i = 0, $len = count($items); $i < $len; ++$i) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 442 |  |  | 			$item = $items[$i]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 443 |  |  | 			$tempnextreminder = $item[$this->proptags["startdate"]] - ($item[$this->proptags["reminder_minutes"]] * 60); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 444 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 445 |  |  | 			// If tempnextreminder is greater than timestamp then save it in nextreminder and break from the loop. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 446 |  |  | 			if ($tempnextreminder > $timestamp) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 447 |  |  | 				$nextreminder = $tempnextreminder; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 448 |  |  | 				break; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 449 |  |  | 			} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 450 |  |  | 		} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 451 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 452 |  |  | 		return $nextreminder; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 453 |  |  | 	} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 454 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 455 |  |  | 	/** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 456 |  |  | 	 * Note: Static function, more like a utility function. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 457 |  |  | 	 * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 458 |  |  | 	 * Gets all the items (including recurring items) in the specified calendar in the given timeframe. Items are | 
            
                                                                                                            
                            
            
                                    
            
            
                | 459 |  |  | 	 * included as a whole if they overlap the interval <$start, $end> (non-inclusive). This means that if the interval | 
            
                                                                                                            
                            
            
                                    
            
            
                | 460 |  |  | 	 * is <08:00 - 14:00>, the item [6:00 - 8:00> is NOT included, nor is the item [14:00 - 16:00>. However, the item | 
            
                                                                                                            
                            
            
                                    
            
            
                | 461 |  |  | 	 * [7:00 - 9:00> is included as a whole, and is NOT capped to [8:00 - 9:00>. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 462 |  |  | 	 * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 463 |  |  | 	 * @param $store          resource The store in which the calendar resides | 
            
                                                                                                            
                            
            
                                    
            
            
                | 464 |  |  | 	 * @param $calendar       resource The calendar to get the items from | 
            
                                                                                                            
                            
            
                                    
            
            
                | 465 |  |  | 	 * @param $viewstart      int Timestamp of beginning of view window | 
            
                                                                                                            
                            
            
                                    
            
            
                | 466 |  |  | 	 * @param $viewend        int Timestamp of end of view window | 
            
                                                                                                            
                            
            
                                    
            
            
                | 467 |  |  | 	 * @param $propsrequested array Array of properties to return | 
            
                                                                                                            
                            
            
                                    
            
            
                | 468 |  |  | 	 * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 469 |  |  | 	 * @psalm-param list{0: mixed, 1: mixed, 2?: mixed} $propsrequested | 
            
                                                                                                            
                            
            
                                    
            
            
                | 470 |  |  | 	 */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 471 |  |  | 	public static function getCalendarItems(mixed $store, mixed $calendar, int $viewstart, int $viewend, array $propsrequested): array { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 472 |  |  | 		return getCalendarItems($store, $calendar, $viewstart, $viewend, $propsrequested); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 473 |  |  | 	} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 474 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 475 |  |  | 	/* | 
            
                                                                                                            
                            
            
                                    
            
            
                | 476 |  |  | 	 * CODE BELOW THIS LINE IS FOR INTERNAL USE ONLY | 
            
                                                                                                            
                            
            
                                    
            
            
                | 477 |  |  | 	 ***************************************************************************************************************** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 478 |  |  | 	 */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 479 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 480 |  |  | 	/** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 481 |  |  | 	 * Returns langified daily recurrence type string, whether it's singular or plural, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 482 |  |  | 	 * recurrence interval. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 483 |  |  | 	 */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 484 |  |  | 	public function getI18RecTypeDaily(mixed $type, mixed $interval, bool $occSingleDayRank): array { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 485 |  |  | 		switch ($interval) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 486 |  |  | 			case 1: // workdays | 
            
                                                                                                            
                            
            
                                    
            
            
                | 487 |  |  | 				$type = _('workday'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 488 |  |  | 				$occSingleDayRank = true; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 489 |  |  | 				break; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 490 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 491 |  |  | 			case 1440: // daily | 
            
                                                                                                            
                            
            
                                    
            
            
                | 492 |  |  | 				$type = _('day'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 493 |  |  | 				$occSingleDayRank = true; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 494 |  |  | 				break; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 495 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 496 |  |  | 			default: // every $interval days | 
            
                                                                                                            
                            
            
                                    
            
            
                | 497 |  |  | 				$interval /= 1440; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 498 |  |  | 				$type = _('days'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 499 |  |  | 				$occSingleDayRank = false; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 500 |  |  | 				break; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 501 |  |  | 		} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 502 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 503 |  |  | 		return [ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 504 |  |  | 			'type' => $type, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 505 |  |  | 			'interval' => $interval, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 506 |  |  | 			'occSingleDayRank' => boolval($occSingleDayRank), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 507 |  |  | 		]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 508 |  |  | 	} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 509 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 510 |  |  | 	/** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 511 |  |  | 	 * Returns langified weekly recurrence type string, whether it's singular or plural, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 512 |  |  | 	 * recurrence interval. | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 513 |  |  | 	 */ | 
            
                                                                        
                            
            
                                    
            
            
                | 514 |  |  | 	public function getI18RecTypeWeekly(mixed $type, mixed $interval, bool $occSingleDayRank): array { | 
            
                                                                        
                            
            
                                    
            
            
                | 515 |  |  | 		if ($interval == 1) { | 
            
                                                                        
                            
            
                                    
            
            
                | 516 |  |  | 			$type = _('week'); | 
            
                                                                        
                            
            
                                    
            
            
                | 517 |  |  | 			$occSingleDayRank = true; | 
            
                                                                        
                            
            
                                    
            
            
                | 518 |  |  | 		} | 
            
                                                                        
                            
            
                                    
            
            
                | 519 |  |  | 		else { | 
            
                                                                        
                            
            
                                    
            
            
                | 520 |  |  | 			$type = _('weeks'); | 
            
                                                                        
                            
            
                                    
            
            
                | 521 |  |  | 			$occSingleDayRank = false; | 
            
                                                                        
                            
            
                                    
            
            
                | 522 |  |  | 		} | 
            
                                                                        
                            
            
                                    
            
            
                | 523 |  |  | 		$daysOfWeek = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]; | 
            
                                                                        
                            
            
                                    
            
            
                | 524 |  |  | 		$type .= sprintf(" %s ", _('on')); | 
            
                                                                        
                            
            
                                    
            
            
                | 525 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 526 |  |  | 		for ($j = 0, $weekdays = (int) $this->recur["weekdays"]; $j < 7; ++$j) { | 
            
                                                                        
                            
            
                                    
            
            
                | 527 |  |  | 			if ($weekdays & (1 << $j)) { | 
            
                                                                        
                            
            
                                    
            
            
                | 528 |  |  | 				$type .= sprintf("%s, ", _($daysOfWeek[$j])); | 
            
                                                                        
                            
            
                                    
            
            
                | 529 |  |  | 			} | 
            
                                                                        
                            
            
                                    
            
            
                | 530 |  |  | 		} | 
            
                                                                        
                            
            
                                    
            
            
                | 531 |  |  | 		$type = trim($type, ", "); | 
            
                                                                        
                            
            
                                    
            
            
                | 532 |  |  | 		if (($pos = strrpos($type, ",")) !== false) { | 
            
                                                                        
                            
            
                                    
            
            
                | 533 |  |  | 			$type = substr_replace($type, " " . _('and'), $pos, 1); | 
            
                                                                        
                            
            
                                    
            
            
                | 534 |  |  | 		} | 
            
                                                                        
                            
            
                                    
            
            
                | 535 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 536 |  |  | 		return [ | 
            
                                                                        
                            
            
                                    
            
            
                | 537 |  |  | 			'type' => $type, | 
            
                                                                        
                            
            
                                    
            
            
                | 538 |  |  | 			'interval' => $interval, | 
            
                                                                        
                            
            
                                    
            
            
                | 539 |  |  | 			'occSingleDayRank' => boolval($occSingleDayRank), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 540 |  |  | 		]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 541 |  |  | 	} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 542 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 543 |  |  | 	/** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 544 |  |  | 	 * Returns langified monthly recurrence type string, whether it's singular or plural, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 545 |  |  | 	 * recurrence interval. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 546 |  |  | 	 */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 547 |  |  | 	public function getI18RecTypeMonthly(mixed $type, mixed $interval, bool $occSingleDayRank): array { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 548 |  |  | 		if ($interval == 1) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 549 |  |  | 			$type = _('month'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 550 |  |  | 			$occSingleDayRank = true; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 551 |  |  | 		} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 552 |  |  | 		else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 553 |  |  | 			$type = _('months'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 554 |  |  | 			$occSingleDayRank = false; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 555 |  |  | 		} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 556 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 557 |  |  | 		return [ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 558 |  |  | 			'type' => $type, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 559 |  |  | 			'interval' => $interval, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 560 |  |  | 			'occSingleDayRank' => boolval($occSingleDayRank), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 561 |  |  | 		]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 562 |  |  | 	} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 563 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 564 |  |  | 	/** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 565 |  |  | 	 * Returns langified yearly recurrence type string, whether it's singular or plural, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 566 |  |  | 	 * recurrence interval. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 567 |  |  | 	 */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 568 |  |  | 	public function getI18RecTypeYearly(mixed $type, mixed $interval, bool $occSingleDayRank): array { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 569 |  |  | 		if ($interval <= 12) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 570 |  |  | 			$interval = 1; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 571 |  |  | 			$type = _('year'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 572 |  |  | 			$occSingleDayRank = true; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 573 |  |  | 		} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 574 |  |  | 		else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 575 |  |  | 			$interval = $interval / 12; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 576 |  |  | 			$type = _('years'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 577 |  |  | 			$occSingleDayRank = false; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 578 |  |  | 		} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 579 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 580 |  |  | 		return [ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 581 |  |  | 			'type' => $type, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 582 |  |  | 			'interval' => $interval, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 583 |  |  | 			'occSingleDayRank' => boolval($occSingleDayRank), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 584 |  |  | 		]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 585 |  |  | 	} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 586 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 587 |  |  | 	/** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 588 |  |  | 	 * Returns langified recurrence type string, whether it's singular or plural, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 589 |  |  | 	 * recurrence interval. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 590 |  |  | 	 */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 591 |  |  | 	public function getI18nRecurrenceType(): array { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 592 |  |  | 		$type = $this->recur['type']; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 593 |  |  | 		$interval = $this->recur['everyn']; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 594 |  |  | 		$occSingleDayRank = false; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 595 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 596 |  |  | 		return match ($type) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 597 |  |  | 			// Daily | 
            
                                                                                                            
                            
            
                                    
            
            
                | 598 |  |  | 			0x0A => $this->getI18RecTypeDaily($type, $interval, $occSingleDayRank), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 599 |  |  | 			// Weekly | 
            
                                                                                                            
                            
            
                                    
            
            
                | 600 |  |  | 			0x0B => $this->getI18RecTypeWeekly($type, $interval, $occSingleDayRank), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 601 |  |  | 			// Monthly | 
            
                                                                                                            
                            
            
                                    
            
            
                | 602 |  |  | 			0x0C => $this->getI18RecTypeMonthly($type, $interval, $occSingleDayRank), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 603 |  |  | 			// Yearly | 
            
                                                                                                            
                            
            
                                    
            
            
                | 604 |  |  | 			0x0D => $this->getI18RecTypeYearly($type, $interval, $occSingleDayRank), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 605 |  |  | 			default => [ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 606 |  |  | 				'type' => $type, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 607 |  |  | 				'interval' => $interval, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 608 |  |  | 				'occSingleDayRank' => boolval($occSingleDayRank), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 609 |  |  | 			], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 610 |  |  | 		}; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 611 |  |  | 	} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 612 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 613 |  |  | 	/** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 614 |  |  | 	 * Returns the start or end time of the first occurrence. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 615 |  |  | 	 */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 616 |  |  | 	public function getOccDate(bool $getStart = true): mixed { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 617 |  |  | 		return $getStart ? | 
            
                                                                                                            
                            
            
                                    
            
            
                | 618 |  |  | 			(isset($this->recur['startocc']) ? | 
            
                                                                                                            
                            
            
                                    
            
            
                | 619 |  |  | 				$this->recur['start'] + (((int) $this->recur['startocc']) * 60) : | 
            
                                                                                                            
                            
            
                                    
            
            
                | 620 |  |  | 				$this->recur['start']) : | 
            
                                                                                                            
                            
            
                                    
            
            
                | 621 |  |  | 			(isset($this->recur['endocc']) ? | 
            
                                                                                                            
                            
            
                                    
            
            
                | 622 |  |  | 				$this->recur['start'] + (((int) $this->recur['endocc']) * 60) : | 
            
                                                                                                            
                            
            
                                    
            
            
                | 623 |  |  | 				$this->recur['end']); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 624 |  |  | 	} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 625 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 626 |  |  | 	/** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 627 |  |  | 	 * Returns langified occurrence time. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 628 |  |  | 	 */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 629 |  |  | 	public function getI18nTime(string $format, mixed $occTime): string { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 630 |  |  | 		return gmdate(_($format), $occTime); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 631 |  |  | 	} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 632 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 633 |  |  | 	/** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 634 |  |  | 	 * Returns langified recurrence pattern termination after the given date. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 635 |  |  | 	 */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 636 |  |  | 	public function getI18nRecTermDate( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 637 |  |  | 		bool $occTimeRange, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 638 |  |  | 		bool $occSingleDayRank, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 639 |  |  | 		mixed $type, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 640 |  |  | 		mixed $interval, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 641 |  |  | 		string $start, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 642 |  |  | 		string $end, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 643 |  |  | 		string $startocc, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 644 |  |  | 		string $endocc | 
            
                                                                                                            
                            
            
                                    
            
            
                | 645 |  |  | 	): string { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 646 |  |  | 		return $occTimeRange ? | 
            
                                                                                                            
                            
            
                                    
            
            
                | 647 |  |  | 			( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 648 |  |  | 				$occSingleDayRank ? | 
            
                                                                                                            
                            
            
                                    
            
            
                | 649 |  |  | 					sprintf( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 650 |  |  | 						_('Occurs every %s effective %s until %s from %s to %s.'), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 651 |  |  | 						$type, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 652 |  |  | 						$start, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 653 |  |  | 						$end, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 654 |  |  | 						$startocc, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 655 |  |  | 						$endocc | 
            
                                                                                                            
                            
            
                                    
            
            
                | 656 |  |  | 					) : | 
            
                                                                                                            
                            
            
                                    
            
            
                | 657 |  |  | 					sprintf( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 658 |  |  | 						_('Occurs every %s %s effective %s until %s from %s to %s.'), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 659 |  |  | 						$interval, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 660 |  |  | 						$type, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 661 |  |  | 						$start, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 662 |  |  | 						$end, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 663 |  |  | 						$startocc, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 664 |  |  | 						$endocc | 
            
                                                                                                            
                            
            
                                    
            
            
                | 665 |  |  | 					) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 666 |  |  | 			) : | 
            
                                                                                                            
                            
            
                                    
            
            
                | 667 |  |  | 			( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 668 |  |  | 				$occSingleDayRank ? | 
            
                                                                                                            
                            
            
                                    
            
            
                | 669 |  |  | 					sprintf( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 670 |  |  | 						_('Occurs every %s effective %s until %s.'), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 671 |  |  | 						$type, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 672 |  |  | 						$start, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 673 |  |  | 						$end | 
            
                                                                                                            
                            
            
                                    
            
            
                | 674 |  |  | 					) : | 
            
                                                                                                            
                            
            
                                    
            
            
                | 675 |  |  | 					sprintf( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 676 |  |  | 						_('Occurs every %s %s effective %s until %s.'), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 677 |  |  | 						$interval, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 678 |  |  | 						$type, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 679 |  |  | 						$start, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 680 |  |  | 						$end | 
            
                                                                                                            
                            
            
                                    
            
            
                | 681 |  |  | 					) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 682 |  |  | 			); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 683 |  |  | 	} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 684 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 685 |  |  | 	/** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 686 |  |  | 	 * Returns langified recurrence pattern termination after a number of | 
            
                                                                                                            
                            
            
                                    
            
            
                | 687 |  |  | 	 * occurrences. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 688 |  |  | 	 */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 689 |  |  | 	public function getI18nRecTermNrOcc( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 690 |  |  | 		bool $occTimeRange, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 691 |  |  | 		bool $occSingleDayRank, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 692 |  |  | 		mixed $type, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 693 |  |  | 		mixed $interval, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 694 |  |  | 		string $start, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 695 |  |  | 		mixed $numocc, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 696 |  |  | 		string $startocc, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 697 |  |  | 		string $endocc | 
            
                                                                                                            
                            
            
                                    
            
            
                | 698 |  |  | 	): string { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 699 |  |  | 		return $occTimeRange ? | 
            
                                                                                                            
                            
            
                                    
            
            
                | 700 |  |  | 			( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 701 |  |  | 				$occSingleDayRank ? | 
            
                                                                                                            
                            
            
                                    
            
            
                | 702 |  |  | 					sprintf( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 703 |  |  | 						dngettext( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 704 |  |  | 							'zarafa', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 705 |  |  | 							'Occurs every %s effective %s for %s occurrence from %s to %s.', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 706 |  |  | 							'Occurs every %s effective %s for %s occurrences from %s to %s.', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 707 |  |  | 							$numocc | 
            
                                                                                                            
                            
            
                                    
            
            
                | 708 |  |  | 						), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 709 |  |  | 						$type, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 710 |  |  | 						$start, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 711 |  |  | 						$numocc, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 712 |  |  | 						$startocc, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 713 |  |  | 						$endocc | 
            
                                                                                                            
                            
            
                                    
            
            
                | 714 |  |  | 					) : | 
            
                                                                                                            
                            
            
                                    
            
            
                | 715 |  |  | 					sprintf( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 716 |  |  | 						dngettext( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 717 |  |  | 							'zarafa', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 718 |  |  | 							'Occurs every %s %s effective %s for %s occurrence from %s to %s.', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 719 |  |  | 							'Occurs every %s %s effective %s for %s occurrences %s to %s.', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 720 |  |  | 							$numocc | 
            
                                                                                                            
                            
            
                                    
            
            
                | 721 |  |  | 						), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 722 |  |  | 						$interval, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 723 |  |  | 						$type, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 724 |  |  | 						$start, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 725 |  |  | 						$numocc, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 726 |  |  | 						$startocc, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 727 |  |  | 						$endocc | 
            
                                                                                                            
                            
            
                                    
            
            
                | 728 |  |  | 					) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 729 |  |  | 			) : | 
            
                                                                                                            
                            
            
                                    
            
            
                | 730 |  |  | 			( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 731 |  |  | 				$occSingleDayRank ? | 
            
                                                                                                            
                            
            
                                    
            
            
                | 732 |  |  | 					sprintf( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 733 |  |  | 						dngettext( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 734 |  |  | 							'zarafa', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 735 |  |  | 							'Occurs every %s effective %s for %s occurrence.', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 736 |  |  | 							'Occurs every %s effective %s for %s occurrences.', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 737 |  |  | 							$numocc | 
            
                                                                                                            
                            
            
                                    
            
            
                | 738 |  |  | 						), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 739 |  |  | 						$type, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 740 |  |  | 						$start, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 741 |  |  | 						$numocc | 
            
                                                                                                            
                            
            
                                    
            
            
                | 742 |  |  | 					) : | 
            
                                                                                                            
                            
            
                                    
            
            
                | 743 |  |  | 					sprintf( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 744 |  |  | 						dngettext( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 745 |  |  | 							'zarafa', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 746 |  |  | 							'Occurs every %s %s effective %s for %s occurrence.', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 747 |  |  | 							'Occurs every %s %s effective %s for %s occurrences.', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 748 |  |  | 							$numocc | 
            
                                                                                                            
                            
            
                                    
            
            
                | 749 |  |  | 						), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 750 |  |  | 						$interval, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 751 |  |  | 						$type, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 752 |  |  | 						$start, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 753 |  |  | 						$numocc | 
            
                                                                                                            
                            
            
                                    
            
            
                | 754 |  |  | 					) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 755 |  |  | 			); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 756 |  |  | 	} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 757 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 758 |  |  | 	/** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 759 |  |  | 	 * Returns langified recurrence pattern termination with no end date. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 760 |  |  | 	 */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 761 |  |  | 	public function getI18nRecTermNoEnd( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 762 |  |  | 		bool $occTimeRange, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 763 |  |  | 		bool $occSingleDayRank, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 764 |  |  | 		mixed $type, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 765 |  |  | 		mixed $interval, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 766 |  |  | 		string $start, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 767 |  |  | 		string $startocc, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 768 |  |  | 		string $endocc | 
            
                                                                                                            
                            
            
                                    
            
            
                | 769 |  |  | 	): string { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 770 |  |  | 		return $occTimeRange ? | 
            
                                                                                                            
                            
            
                                    
            
            
                | 771 |  |  | 			( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 772 |  |  | 				$occSingleDayRank ? | 
            
                                                                                                            
                            
            
                                    
            
            
                | 773 |  |  | 					sprintf( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 774 |  |  | 						_('Occurs every %s effective %s from %s to %s.'), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 775 |  |  | 						$type, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 776 |  |  | 						$start, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 777 |  |  | 						$startocc, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 778 |  |  | 						$endocc | 
            
                                                                                                            
                            
            
                                    
            
            
                | 779 |  |  | 					) : | 
            
                                                                                                            
                            
            
                                    
            
            
                | 780 |  |  | 					sprintf( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 781 |  |  | 						_('Occurs every %s %s effective %s from %s to %s.'), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 782 |  |  | 						$interval, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 783 |  |  | 						$type, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 784 |  |  | 						$start, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 785 |  |  | 						$startocc, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 786 |  |  | 						$endocc | 
            
                                                                                                            
                            
            
                                    
            
            
                | 787 |  |  | 					) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 788 |  |  | 			) : | 
            
                                                                                                            
                            
            
                                    
            
            
                | 789 |  |  | 			( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 790 |  |  | 				$occSingleDayRank ? | 
            
                                                                                                            
                            
            
                                    
            
            
                | 791 |  |  | 					sprintf( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 792 |  |  | 						_('Occurs every %s effective %s.'), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 793 |  |  | 						$type, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 794 |  |  | 						$start | 
            
                                                                                                            
                            
            
                                    
            
            
                | 795 |  |  | 					) : | 
            
                                                                                                            
                            
            
                                    
            
            
                | 796 |  |  | 					sprintf( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 797 |  |  | 						_('Occurs every %s %s effective %s.'), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 798 |  |  | 						$interval, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 799 |  |  | 						$type, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 800 |  |  | 						$start | 
            
                                                                                                            
                            
            
                                    
            
            
                | 801 |  |  | 					) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 802 |  |  | 			); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 803 |  |  | 	} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 804 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 805 |  |  | 	/** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 806 |  |  | 	 * Generates and stores recurrence pattern string to recurring_pattern property. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 807 |  |  | 	 */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 808 |  |  | 	public function saveRecurrencePattern(): string { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 809 |  |  | 		// Start formatting the properties in such a way we can apply | 
            
                                                                                                            
                            
            
                                    
            
            
                | 810 |  |  | 		// them directly into the recurrence pattern. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 811 |  |  | 		$pattern = ''; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 812 |  |  | 		$occTimeRange = $this->recur['startocc'] != 0 && $this->recur['endocc'] != 0; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 813 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 814 |  |  | 		[ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 815 |  |  | 			'type' => $type, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 816 |  |  | 			'interval' => $interval, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 817 |  |  | 			'occSingleDayRank' => $occSingleDayRank, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 818 |  |  | 		] = $this->getI18nRecurrenceType(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 819 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 820 |  |  | 		// get timings of the first occurrence | 
            
                                                                                                            
                            
            
                                    
            
            
                | 821 |  |  | 		$firstoccstartdate = $this->getOccDate(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 822 |  |  | 		$firstoccenddate = $this->getOccDate(false); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 823 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 824 |  |  | 		$start = $this->getI18nTime('d-m-Y', $firstoccstartdate); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 825 |  |  | 		$end = $this->getI18nTime('d-m-Y', $firstoccenddate); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 826 |  |  | 		$startocc = $this->getI18nTime('G:i', $firstoccstartdate); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 827 |  |  | 		$endocc = $this->getI18nTime('G:i', $firstoccenddate); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 828 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 829 |  |  | 		// Based on the properties, we need to generate the recurrence pattern string. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 830 |  |  | 		// This is obviously very easy since we can simply concatenate a bunch of strings, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 831 |  |  | 		// however this messes up translations for languages which order their words | 
            
                                                                                                            
                            
            
                                    
            
            
                | 832 |  |  | 		// differently. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 833 |  |  | 		// To improve translation quality we create a series of default strings, in which | 
            
                                                                                                            
                            
            
                                    
            
            
                | 834 |  |  | 		// we only have to fill in the correct variables. The base string is thus selected | 
            
                                                                                                            
                            
            
                                    
            
            
                | 835 |  |  | 		// based on the available properties. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 836 |  |  | 		switch ($this->recur['term']) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 837 |  |  | 			case 0x21: // After the given enddate | 
            
                                                                                                            
                            
            
                                    
            
            
                | 838 |  |  | 				$pattern = $this->getI18nRecTermDate( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 839 |  |  | 					$occTimeRange, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 840 |  |  | 					boolval($occSingleDayRank), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 841 |  |  | 					$type, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 842 |  |  | 					$interval, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 843 |  |  | 					$start, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 844 |  |  | 					$end, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 845 |  |  | 					$startocc, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 846 |  |  | 					$endocc | 
            
                                                                                                            
                            
            
                                    
            
            
                | 847 |  |  | 				); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 848 |  |  | 				break; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 849 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 850 |  |  | 			case 0x22: // After a number of times | 
            
                                                                                                            
                            
            
                                    
            
            
                | 851 |  |  | 				$pattern = $this->getI18nRecTermNrOcc( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 852 |  |  | 					$occTimeRange, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 853 |  |  | 					boolval($occSingleDayRank), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 854 |  |  | 					$type, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 855 |  |  | 					$interval, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 856 |  |  | 					$start, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 857 |  |  | 					$this->recur['numoccur'] ?? 0, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 858 |  |  | 					$startocc, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 859 |  |  | 					$endocc | 
            
                                                                                                            
                            
            
                                    
            
            
                | 860 |  |  | 				); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 861 |  |  | 				break; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 862 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 863 |  |  | 			case 0x23: // Never ends | 
            
                                                                                                            
                            
            
                                    
            
            
                | 864 |  |  | 				$pattern = $this->getI18nRecTermNoEnd( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 865 |  |  | 					$occTimeRange, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 866 |  |  | 					boolval($occSingleDayRank), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 867 |  |  | 					$type, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 868 |  |  | 					$interval, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 869 |  |  | 					$start, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 870 |  |  | 					$startocc, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 871 |  |  | 					$endocc | 
            
                                                                                                            
                            
            
                                    
            
            
                | 872 |  |  | 				); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 873 |  |  | 				break; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 874 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 875 |  |  | 			default: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 876 |  |  | 				error_log(sprintf("Invalid recurrence pattern termination %d", $this->recur['term'])); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 877 |  |  | 				break; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 878 |  |  | 		} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 879 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 880 |  |  | 		if (!empty($pattern)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 881 |  |  | 			mapi_setprops($this->message, [$this->proptags["recurring_pattern"] => $pattern]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 882 |  |  | 		} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 883 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 884 |  |  | 		return $pattern; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 885 |  |  | 	} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 886 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 887 |  |  | 	/* | 
            
                                                                                                            
                            
            
                                    
            
            
                | 888 |  |  | 	 * Remove an exception by base_date. This is the base date in local daystart time | 
            
                                                                                                            
                            
            
                                    
            
            
                | 889 |  |  | 	 */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 890 |  |  | 	/** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 891 |  |  | 	 * @param false|int $base_date | 
            
                                                                                                            
                            
            
                                    
            
            
                | 892 |  |  | 	 */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 893 |  |  | 	public function deleteException($base_date): void { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 894 |  |  | 		// Remove all exceptions on $base_date from the deleted and changed occurrences lists | 
            
                                                                                                            
                            
            
                                    
            
            
                | 895 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 896 |  |  | 		// Remove all items in $todelete from deleted_occurrences | 
            
                                                                                                            
                            
            
                                    
            
            
                | 897 |  |  | 		$new = []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 898 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 899 |  |  | 		foreach ($this->recur["deleted_occurrences"] as $entry) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 900 |  |  | 			if ($entry != $base_date) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 901 |  |  | 				$new[] = $entry; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 902 |  |  | 			} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 903 |  |  | 		} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 904 |  |  | 		$this->recur["deleted_occurrences"] = $new; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 905 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 906 |  |  | 		$new = []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 907 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 908 |  |  | 		foreach ($this->recur["changed_occurrences"] as $entry) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 909 |  |  | 			if (!$this->isSameDay($entry["basedate"], $base_date)) { | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 910 |  |  | 				$new[] = $entry; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 911 |  |  | 			} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 912 |  |  | 			else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 913 |  |  | 				$this->deleteExceptionAttachment($this->toGMT($this->tz, $base_date + $this->recur["startocc"] * 60)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 914 |  |  | 			} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 915 |  |  | 		} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 916 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 917 |  |  | 		$this->recur["changed_occurrences"] = $new; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 918 |  |  | 	} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 919 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 920 |  |  | 	/** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 921 |  |  | 	 * Function which saves the exception data in an attachment. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 922 |  |  | 	 * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 923 |  |  | 	 * @param array          $exception_props  the exception data (like any other MAPI appointment) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 924 |  |  | 	 * @param array          $exception_recips list of recipients | 
            
                                                                                                            
                            
            
                                    
            
            
                | 925 |  |  | 	 * @param false|resource $copy_attach_from mapi message from which attachments should be copied | 
            
                                                                                                            
                            
            
                                    
            
            
                | 926 |  |  | 	 */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 927 |  |  | 	public function createExceptionAttachment($exception_props, $exception_recips = [], $copy_attach_from = false): void { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 928 |  |  | 		// Create new attachment. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 929 |  |  | 		$attachment = mapi_message_createattach($this->message); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 930 |  |  | 		$props = []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 931 |  |  | 		$props[PR_ATTACHMENT_FLAGS] = 2; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 932 |  |  | 		$props[PR_ATTACHMENT_HIDDEN] = true; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 933 |  |  | 		$props[PR_ATTACHMENT_LINKID] = 0; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 934 |  |  | 		$props[PR_ATTACH_FLAGS] = 0; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 935 |  |  | 		$props[PR_ATTACH_METHOD] = ATTACH_EMBEDDED_MSG; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 936 |  |  | 		$props[PR_DISPLAY_NAME] = "Exception"; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 937 |  |  | 		$props[PR_EXCEPTION_STARTTIME] = $this->fromGMT($this->tz, $exception_props[$this->proptags["startdate"]]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 938 |  |  | 		$props[PR_EXCEPTION_ENDTIME] = $this->fromGMT($this->tz, $exception_props[$this->proptags["duedate"]]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 939 |  |  | 		mapi_setprops($attachment, $props); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 940 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 941 |  |  | 		$imessage = mapi_attach_openobj($attachment, MAPI_CREATE | MAPI_MODIFY); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 942 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 943 |  |  | 		if ($copy_attach_from) { | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 944 |  |  | 			$attachmentTable = mapi_message_getattachmenttable($copy_attach_from); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 945 |  |  | 			if ($attachmentTable) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 946 |  |  | 				$attachments = mapi_table_queryallrows($attachmentTable, [PR_ATTACH_NUM, PR_ATTACH_SIZE, PR_ATTACH_LONG_FILENAME, PR_ATTACHMENT_HIDDEN, PR_DISPLAY_NAME, PR_ATTACH_METHOD]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 947 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 948 |  |  | 				foreach ($attachments as $attach_props) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 949 |  |  | 					$attach_old = mapi_message_openattach($copy_attach_from, (int) $attach_props[PR_ATTACH_NUM]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 950 |  |  | 					$attach_newResourceMsg = mapi_message_createattach($imessage); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 951 |  |  | 					mapi_copyto($attach_old, [], [], $attach_newResourceMsg, 0); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 952 |  |  | 					mapi_savechanges($attach_newResourceMsg); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 953 |  |  | 				} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 954 |  |  | 			} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 955 |  |  | 		} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 956 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 957 |  |  | 		$props = $props + $exception_props; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 958 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 959 |  |  | 		// FIXME: the following piece of code is written to fix the creation | 
            
                                                                                                            
                            
            
                                    
            
            
                | 960 |  |  | 		// of an exception. This is only a quickfix as it is not yet possible | 
            
                                                                                                            
                            
            
                                    
            
            
                | 961 |  |  | 		// to change an existing exception. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 962 |  |  | 		// remove mv properties when needed | 
            
                                                                                                            
                            
            
                                    
            
            
                | 963 |  |  | 		foreach ($props as $propTag => $propVal) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 964 |  |  | 			if ((mapi_prop_type($propTag) & MV_FLAG) == MV_FLAG && $propVal === null) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 965 |  |  | 				unset($props[$propTag]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 966 |  |  | 			} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 967 |  |  | 		} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 968 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 969 |  |  | 		mapi_setprops($imessage, $props); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 970 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 971 |  |  | 		$this->setExceptionRecipients($imessage, $exception_recips, true); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 972 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 973 |  |  | 		mapi_savechanges($imessage); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 974 |  |  | 		mapi_savechanges($attachment); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 975 |  |  | 	} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 976 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 977 |  |  | 	/** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 978 |  |  | 	 * Function which deletes the attachment of an exception. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 979 |  |  | 	 * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 980 |  |  | 	 * @param mixed $base_date base date of the attachment. Should be in GMT. The attachment | 
            
                                                                                                            
                            
            
                                    
            
            
                | 981 |  |  | 	 *                         actually saves the real time of the original date, so we have | 
            
                                                                                                            
                            
            
                                    
            
            
                | 982 |  |  | 	 *                         to check whether it's on the same day. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 983 |  |  | 	 */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 984 |  |  | 	public function deleteExceptionAttachment($base_date): void { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 985 |  |  | 		$attachments = mapi_message_getattachmenttable($this->message); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 986 |  |  | 		// Retrieve only exceptions which are stored as embedded messages | 
            
                                                                                                            
                            
            
                                    
            
            
                | 987 |  |  | 		$attach_res = $this->getEmbeddedMessageRestriction(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 988 |  |  | 		$attachRows = mapi_table_queryallrows($attachments, [PR_ATTACH_NUM], $attach_res); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 989 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 990 |  |  | 		foreach ($attachRows as $attachRow) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 991 |  |  | 			$tempattach = mapi_message_openattach($this->message, $attachRow[PR_ATTACH_NUM]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 992 |  |  | 			$exception = mapi_attach_openobj($tempattach); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 993 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 994 |  |  | 			$data = mapi_message_getprops($exception, [$this->proptags["basedate"]]); | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 995 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 996 |  |  | 			if ($this->dayStartOf($this->fromGMT($this->tz, $data[$this->proptags["basedate"]])) == $this->dayStartOf($base_date)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 997 |  |  | 				mapi_message_deleteattach($this->message, $attachRow[PR_ATTACH_NUM]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 998 |  |  | 			} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 999 |  |  | 		} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1000 |  |  | 	} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1001 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1002 |  |  | 	/** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1003 |  |  | 	 * Function which deletes all attachments of a message. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1004 |  |  | 	 */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1005 |  |  | 	public function deleteAttachments(): void { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1006 |  |  | 		$attachments = mapi_message_getattachmenttable($this->message); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1007 |  |  | 		$attachTable = mapi_table_queryallrows($attachments, [PR_ATTACH_NUM, PR_ATTACHMENT_HIDDEN]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1008 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1009 |  |  | 		foreach ($attachTable as $attachRow) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1010 |  |  | 			if (isset($attachRow[PR_ATTACHMENT_HIDDEN]) && $attachRow[PR_ATTACHMENT_HIDDEN]) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1011 |  |  | 				mapi_message_deleteattach($this->message, $attachRow[PR_ATTACH_NUM]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1012 |  |  | 			} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1013 |  |  | 		} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1014 |  |  | 	} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1015 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1016 |  |  | 	/** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1017 |  |  | 	 * Get an exception attachment based on its basedate. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1018 |  |  | 	 */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1019 |  |  | 	public function getExceptionAttachment(int $base_date): mixed { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1020 |  |  | 		// Retrieve only exceptions which are stored as embedded messages | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1021 |  |  | 		$attach_res = $this->getEmbeddedMessageRestriction(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1022 |  |  | 		$attachments = mapi_message_getattachmenttable($this->message); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1023 |  |  | 		$attachRows = mapi_table_queryallrows($attachments, [PR_ATTACH_NUM], $attach_res); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1024 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1025 |  |  | 		if (is_array($attachRows)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1026 |  |  | 			foreach ($attachRows as $attachRow) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1027 |  |  | 				$tempattach = mapi_message_openattach($this->message, $attachRow[PR_ATTACH_NUM]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1028 |  |  | 				$exception = mapi_attach_openobj($tempattach); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1029 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1030 |  |  | 				$data = mapi_message_getprops($exception, [$this->proptags["basedate"]]); | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1031 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1032 |  |  | 				if (!isset($data[$this->proptags["basedate"]])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1033 |  |  | 					// if no basedate found then it could be embedded message so ignore it | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1034 |  |  | 					// we need proper restriction to exclude embedded messages as well | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1035 |  |  | 					continue; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1036 |  |  | 				} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1037 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1038 |  |  | 				if ($this->isSameDay($this->fromGMT($this->tz, $data[$this->proptags["basedate"]]), $base_date)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1039 |  |  | 					return $tempattach; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1040 |  |  | 				} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1041 |  |  | 			} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1042 |  |  | 		} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1043 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1044 |  |  | 		return false; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1045 |  |  | 	} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1046 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1047 |  |  | 	/** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1048 |  |  | 	 * processOccurrenceItem, adds an item to a list of occurrences, but only if the following criteria are met: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1049 |  |  | 	 * - The resulting occurrence (or exception) starts or ends in the interval <$start, $end> | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1050 |  |  | 	 * - The occurrence isn't specified as a deleted occurrence. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1051 |  |  | 	 * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1052 |  |  | 	 * @param array $items        reference to the array to be added to | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1053 |  |  | 	 * @param int   $start        start of timeframe in GMT TIME | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1054 |  |  | 	 * @param int   $end          end of timeframe in GMT TIME | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1055 |  |  | 	 * @param int   $basedate     (hour/sec/min assumed to be 00:00:00) in LOCAL TIME OF THE OCCURRENCE | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1056 |  |  | 	 * @param int   $startocc     start of occurrence since beginning of day in minutes | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1057 |  |  | 	 * @param int   $endocc       end of occurrence since beginning of day in minutes | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1058 |  |  | 	 * @param mixed $tz           the timezone info for this occurrence ( applied to $basedate / $startocc / $endocc ) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1059 |  |  | 	 * @param bool  $reminderonly If TRUE, only add the item if the reminder is set | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1060 |  |  | 	 */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1061 |  |  | 	public function processOccurrenceItem(array &$items, mixed $start, int $end, mixed $basedate, mixed $startocc, mixed $endocc, mixed $tz, mixed $reminderonly): ?false { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1062 |  |  | 		$exception = $this->isException($basedate); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1063 |  |  | 		if ($exception) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1064 |  |  | 			return false; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1065 |  |  | 		} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1066 |  |  | 		$occstart = $basedate + $startocc * 60; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1067 |  |  | 		$occend = $basedate + $endocc * 60; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1068 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1069 |  |  | 		// Convert to GMT | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1070 |  |  | 		$occstart = $this->toGMT($tz, $occstart); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1071 |  |  | 		$occend = $this->toGMT($tz, $occend); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1072 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1073 |  |  | 		/** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1074 |  |  | 		 * FIRST PART: Check range criterium. Exact matches (eg when $occstart == $end), do NOT match since you cannot | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1075 |  |  | 		 * see any part of the appointment. Partial overlaps DO match. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1076 |  |  | 		 * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1077 |  |  | 		 * SECOND PART: check if occurrence is not a zero duration occurrence which | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1078 |  |  | 		 * starts at 00:00 and ends on 00:00. if it is so, then process | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1079 |  |  | 		 * the occurrence and send it in response. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1080 |  |  | 		 */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1081 |  |  | 		if (($occstart >= $end || $occend <= $start) && !($occstart == $occend && $occstart == $start)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1082 |  |  | 			return null; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1083 |  |  | 		} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1084 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1085 |  |  | 		// Properties for this occurrence are the same as the main object, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1086 |  |  | 		// With these properties overridden | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1087 |  |  | 		$newitem = $this->messageprops; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1088 |  |  | 		$newitem[$this->proptags["startdate"]] = $occstart; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1089 |  |  | 		$newitem[$this->proptags["duedate"]] = $occend; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1090 |  |  | 		$newitem[$this->proptags["commonstart"]] = $occstart; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1091 |  |  | 		$newitem[$this->proptags["commonend"]] = $occend; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1092 |  |  | 		$newitem["basedate"] = $basedate; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1093 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1094 |  |  | 		// If reminderonly is set, only add reminders | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1095 |  |  | 		if ($reminderonly && (!isset($newitem[$this->proptags["reminder"]]) || $newitem[$this->proptags["reminder"]] === false)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1096 |  |  | 			return null; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1097 |  |  | 		} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1098 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1099 |  |  | 		$items[] = $newitem; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1100 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1101 |  |  | 		return null; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1102 |  |  | 	} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1103 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1104 |  |  | 	/** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1105 |  |  | 	 * Function which verifies if on the given date an exception, delete or change, occurs. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1106 |  |  | 	 * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1107 |  |  | 	 * @return bool true - if an exception occurs on the given date, false - no exception occurs on the given date | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1108 |  |  | 	 */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1109 |  |  | 	public function isException(int $basedate): bool { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1110 |  |  | 		if ($this->isDeleteException($basedate)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1111 |  |  | 			return true; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1112 |  |  | 		} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1113 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1114 |  |  | 		if ($this->getChangeException($basedate) != false) { | 
                            
                    |  |  |  | 
                                                                                        
                                                                                            
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1115 |  |  | 			return true; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1116 |  |  | 		} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1117 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1118 |  |  | 		return false; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1119 |  |  | 	} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1120 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1121 |  |  | 	/** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1122 |  |  | 	 * Returns TRUE if there is a DELETE exception on the given base date. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1123 |  |  | 	 */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1124 |  |  | 	public function isDeleteException(int $basedate): bool { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1125 |  |  | 		// Check if the occurrence is deleted on the specified date | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1126 |  |  | 		foreach ($this->recur["deleted_occurrences"] as $deleted) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1127 |  |  | 			if ($this->isSameDay($deleted, $basedate)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1128 |  |  | 				return true; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1129 |  |  | 			} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1130 |  |  | 		} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1131 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1132 |  |  | 		return false; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1133 |  |  | 	} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1134 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1135 |  |  | 	/** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1136 |  |  | 	 * Returns the exception if there is a CHANGE exception on the given base date, or FALSE otherwise. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1137 |  |  | 	 */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1138 |  |  | 	public function getChangeException(int $basedate): array|false { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1139 |  |  | 		// Check if the occurrence is modified on the specified date | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1140 |  |  | 		foreach ($this->recur["changed_occurrences"] as $changed) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1141 |  |  | 			if ($this->isSameDay($changed["basedate"], $basedate)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1142 |  |  | 				return $changed; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1143 |  |  | 			} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1144 |  |  | 		} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1145 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1146 |  |  | 		return false; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1147 |  |  | 	} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1148 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1149 |  |  | 	/** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1150 |  |  | 	 * Function to see if two dates are on the same day. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1151 |  |  | 	 * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1152 |  |  | 	 * @return bool Returns TRUE when both dates are on the same day | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1153 |  |  | 	 */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1154 |  |  | 	public function isSameDay(int $date1, int $date2): bool { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1155 |  |  | 		$time1 = $this->gmtime($date1); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1156 |  |  | 		$time2 = $this->gmtime($date2); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1157 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1158 |  |  | 		return $time1["tm_mon"] == $time2["tm_mon"] && $time1["tm_year"] == $time2["tm_year"] && $time1["tm_mday"] == $time2["tm_mday"]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1159 |  |  | 	} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1160 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1161 |  |  | 	/** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1162 |  |  | 	 * Function which sets recipients for an exception. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1163 |  |  | 	 * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1164 |  |  | 	 * The $exception_recips can be provided in 2 ways: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1165 |  |  | 	 *  - A delta which indicates which recipients must be added, removed or deleted. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1166 |  |  | 	 *  - A complete array of the recipients which should be applied to the message. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1167 |  |  | 	 * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1168 |  |  | 	 * The first option is preferred as it will require less work to be executed. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1169 |  |  | 	 * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1170 |  |  | 	 * @param resource $message          exception attachment of recurring item | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1171 |  |  | 	 * @param array    $exception_recips list of recipients | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1172 |  |  | 	 * @param bool     $copy_orig_recips True to copy all recipients which are on the original | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1173 |  |  | 	 *                                   message to the attachment by default. False if only the $exception_recips changes should | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1174 |  |  | 	 *                                   be applied. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1175 |  |  | 	 */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1176 |  |  | 	public function setExceptionRecipients(mixed $message, array $exception_recips, bool $copy_orig_recips = true): void { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1177 |  |  | 		if (isset($exception_recips['add']) || isset($exception_recips['remove']) || isset($exception_recips['modify'])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1178 |  |  | 			$this->setDeltaExceptionRecipients($message, $exception_recips, $copy_orig_recips); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1179 |  |  | 		} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1180 |  |  | 		else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1181 |  |  | 			$this->setAllExceptionRecipients($message, $exception_recips); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1182 |  |  | 		} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1183 |  |  | 	} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1184 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1185 |  |  | 	/** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1186 |  |  | 	 * Function which applies the provided delta for recipients changes to the exception. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1187 |  |  | 	 * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1188 |  |  | 	 * The $exception_recips should be an array containing the following keys: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1189 |  |  | 	 *  - "add": this contains an array of recipients which must be added | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1190 |  |  | 	 *  - "remove": This contains an array of recipients which must be removed | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1191 |  |  | 	 *  - "modify": This contains an array of recipients which must be modified | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1192 |  |  | 	 * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1193 |  |  | 	 * @param array $exception_recips list of recipients | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1194 |  |  | 	 * @param bool  $copy_orig_recips True to copy all recipients which are on the original | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1195 |  |  | 	 *                                message to the attachment by default. False if only the $exception_recips changes should | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1196 |  |  | 	 *                                be applied. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1197 |  |  | 	 */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1198 |  |  | 	public function setDeltaExceptionRecipients(mixed $exception, array $exception_recips, bool $copy_orig_recips): void { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1199 |  |  | 		// Check if the recipients from the original message should be copied, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1200 |  |  | 		// if so, open the recipient table of the parent message and apply all | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1201 |  |  | 		// rows on the target recipient. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1202 |  |  | 		if ($copy_orig_recips === true) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1203 |  |  | 			$origTable = mapi_message_getrecipienttable($this->message); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1204 |  |  | 			$recipientRows = mapi_table_queryallrows($origTable, $this->recipprops); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1205 |  |  | 			mapi_message_modifyrecipients($exception, MODRECIP_ADD, $recipientRows); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1206 |  |  | 		} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1207 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1208 |  |  | 		// Add organizer to meeting only if it is not organized. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1209 |  |  | 		$msgprops = mapi_getprops($exception, [PR_SENT_REPRESENTING_ENTRYID, PR_SENT_REPRESENTING_EMAIL_ADDRESS, PR_SENT_REPRESENTING_NAME, PR_SENT_REPRESENTING_ADDRTYPE, PR_SENT_REPRESENTING_SEARCH_KEY, $this->proptags['responsestatus']]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1210 |  |  | 		if (isset($msgprops[$this->proptags['responsestatus']]) && $msgprops[$this->proptags['responsestatus']] != olResponseOrganized) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1211 |  |  | 			$this->addOrganizer($msgprops, $exception_recips['add']); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1212 |  |  | 		} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1213 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1214 |  |  | 		// Remove all deleted recipients | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1215 |  |  | 		if (isset($exception_recips['remove'])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1216 |  |  | 			foreach ($exception_recips['remove'] as &$recip) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1217 |  |  | 				if (!isset($recip[PR_RECIPIENT_FLAGS]) || $recip[PR_RECIPIENT_FLAGS] != (recipReserved | recipExceptionalDeleted | recipSendable)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1218 |  |  | 					$recip[PR_RECIPIENT_FLAGS] = recipSendable | recipExceptionalDeleted; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1219 |  |  | 				} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1220 |  |  | 				else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1221 |  |  | 					$recip[PR_RECIPIENT_FLAGS] = recipReserved | recipExceptionalDeleted | recipSendable; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1222 |  |  | 				} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1223 |  |  | 				$recip[PR_RECIPIENT_TRACKSTATUS] = olResponseNone;		// No Response required | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1224 |  |  | 			} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1225 |  |  | 			unset($recip); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1226 |  |  | 			mapi_message_modifyrecipients($exception, MODRECIP_MODIFY, $exception_recips['remove']); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1227 |  |  | 		} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1228 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1229 |  |  | 		// Add all new recipients | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1230 |  |  | 		if (isset($exception_recips['add'])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1231 |  |  | 			mapi_message_modifyrecipients($exception, MODRECIP_ADD, $exception_recips['add']); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1232 |  |  | 		} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1233 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1234 |  |  | 		// Modify the existing recipients | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1235 |  |  | 		if (isset($exception_recips['modify'])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1236 |  |  | 			mapi_message_modifyrecipients($exception, MODRECIP_MODIFY, $exception_recips['modify']); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1237 |  |  | 		} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1238 |  |  | 	} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1239 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1240 |  |  | 	/** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1241 |  |  | 	 * Function which applies the provided recipients to the exception, also checks for deleted recipients. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1242 |  |  | 	 * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1243 |  |  | 	 * The $exception_recips should be an array containing all recipients which must be applied | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1244 |  |  | 	 * to the exception. This will copy all recipients from the original message and then start filter | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1245 |  |  | 	 * out all recipients which are not provided by the $exception_recips list. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1246 |  |  | 	 * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1247 |  |  | 	 * @param resource $message          exception attachment of recurring item | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1248 |  |  | 	 * @param array    $exception_recips list of recipients | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1249 |  |  | 	 */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1250 |  |  | 	public function setAllExceptionRecipients(mixed $message, array $exception_recips): void { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1251 |  |  | 		$deletedRecipients = []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1252 |  |  | 		$useMessageRecipients = false; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1253 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1254 |  |  | 		$recipientTable = mapi_message_getrecipienttable($message); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1255 |  |  | 		$recipientRows = mapi_table_queryallrows($recipientTable, $this->recipprops); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1256 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1257 |  |  | 		if (empty($recipientRows)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1258 |  |  | 			$useMessageRecipients = true; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1259 |  |  | 			$recipientTable = mapi_message_getrecipienttable($this->message); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1260 |  |  | 			$recipientRows = mapi_table_queryallrows($recipientTable, $this->recipprops); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1261 |  |  | 		} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1262 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1263 |  |  | 		// Add organizer to meeting only if it is not organized. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1264 |  |  | 		$msgprops = mapi_getprops($message, [PR_SENT_REPRESENTING_ENTRYID, PR_SENT_REPRESENTING_EMAIL_ADDRESS, PR_SENT_REPRESENTING_NAME, PR_SENT_REPRESENTING_ADDRTYPE, PR_SENT_REPRESENTING_SEARCH_KEY, $this->proptags['responsestatus']]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1265 |  |  | 		if (isset($msgprops[$this->proptags['responsestatus']]) && $msgprops[$this->proptags['responsestatus']] != olResponseOrganized) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1266 |  |  | 			$this->addOrganizer($msgprops, $exception_recips); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1267 |  |  | 		} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1268 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1269 |  |  | 		if (!empty($exception_recips)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1270 |  |  | 			foreach ($recipientRows as $recipient) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1271 |  |  | 				$found = false; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1272 |  |  | 				foreach ($exception_recips as $excep_recip) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1273 |  |  | 					if (isset($recipient[PR_SEARCH_KEY], $excep_recip[PR_SEARCH_KEY]) && $recipient[PR_SEARCH_KEY] == $excep_recip[PR_SEARCH_KEY]) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1274 |  |  | 						$found = true; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1275 |  |  | 					} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1276 |  |  | 				} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1277 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1278 |  |  | 				if (!$found) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1279 |  |  | 					$foundInDeletedRecipients = false; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1280 |  |  | 					// Look if the $recipient is in the list of deleted recipients | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1281 |  |  | 					if (!empty($deletedRecipients)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1282 |  |  | 						foreach ($deletedRecipients as $recip) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1283 |  |  | 							if (isset($recipient[PR_SEARCH_KEY], $excep_recip[PR_SEARCH_KEY]) && $recip[PR_SEARCH_KEY] == $recipient[PR_SEARCH_KEY]) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1284 |  |  | 								$foundInDeletedRecipients = true; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1285 |  |  | 								break; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1286 |  |  | 							} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1287 |  |  | 						} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1288 |  |  | 					} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1289 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1290 |  |  | 					// If recipient is not in list of deleted recipient, add him | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1291 |  |  | 					if (!$foundInDeletedRecipients) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1292 |  |  | 						if (!isset($recipient[PR_RECIPIENT_FLAGS]) || $recipient[PR_RECIPIENT_FLAGS] != (recipReserved | recipExceptionalDeleted | recipSendable)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1293 |  |  | 							$recipient[PR_RECIPIENT_FLAGS] = recipSendable | recipExceptionalDeleted; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1294 |  |  | 						} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1295 |  |  | 						else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1296 |  |  | 							$recipient[PR_RECIPIENT_FLAGS] = recipReserved | recipExceptionalDeleted | recipSendable; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1297 |  |  | 						} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1298 |  |  | 						$recipient[PR_RECIPIENT_TRACKSTATUS] = olRecipientTrackStatusNone;	// No Response required | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1299 |  |  | 						$deletedRecipients[] = $recipient; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1300 |  |  | 					} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1301 |  |  | 				} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1302 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1303 |  |  | 				// When $message contains a non-empty recipienttable, we must delete the recipients | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1304 |  |  | 				// before re-adding them. However, when $message is doesn't contain any recipients, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1305 |  |  | 				// we are using the recipient table of the original message ($this->message) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1306 |  |  | 				// rather then $message. In that case, we don't need to remove the recipients | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1307 |  |  | 				// from the $message, as the recipient table is already empty, and | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1308 |  |  | 				// mapi_message_modifyrecipients() will throw an error. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1309 |  |  | 				if ($useMessageRecipients === false) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1310 |  |  | 					mapi_message_modifyrecipients($message, MODRECIP_REMOVE, [$recipient]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1311 |  |  | 				} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1312 |  |  | 			} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1313 |  |  | 			$exception_recips = array_merge($exception_recips, $deletedRecipients); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1314 |  |  | 		} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1315 |  |  | 		else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1316 |  |  | 			$exception_recips = $recipientRows; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1317 |  |  | 		} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1318 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1319 |  |  | 		if (!empty($exception_recips)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1320 |  |  | 			// Set the new list of recipients on the exception message, this also removes the existing recipients | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1321 |  |  | 			mapi_message_modifyrecipients($message, MODRECIP_MODIFY, $exception_recips); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1322 |  |  | 		} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1323 |  |  | 	} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1324 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1325 |  |  | 	/** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1326 |  |  | 	 * Function returns basedates of all changed occurrences. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1327 |  |  | 	 * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1328 |  |  | 	 * @return array|false array( 0 => 123459321 ) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1329 |  |  | 	 * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1330 |  |  | 	 * @psalm-return false|list<mixed> | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1331 |  |  | 	 */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1332 |  |  | 	public function getAllExceptions(): array|false { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1333 |  |  | 		if (!empty($this->recur["changed_occurrences"])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1334 |  |  | 			$result = []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1335 |  |  | 			foreach ($this->recur["changed_occurrences"] as $exception) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1336 |  |  | 				$result[] = $exception["basedate"]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1337 |  |  | 			} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1338 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1339 |  |  | 			return $result; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1340 |  |  | 		} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1341 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1342 |  |  | 		return false; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1343 |  |  | 	} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1344 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1345 |  |  | 	/** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1346 |  |  | 	 * Function which adds organizer to recipient list which is passed. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1347 |  |  | 	 * This function also checks if it has organizer. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1348 |  |  | 	 * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1349 |  |  | 	 * @param array $messageProps message properties | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1350 |  |  | 	 * @param array $recipients   recipients list of message | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1351 |  |  | 	 * @param bool  $isException  true if we are processing recipient of exception | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1352 |  |  | 	 */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1353 |  |  | 	public function addOrganizer(array $messageProps, array &$recipients, bool $isException = false): void { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1354 |  |  | 		$hasOrganizer = false; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1355 |  |  | 		// Check if meeting already has an organizer. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1356 |  |  | 		foreach ($recipients as $key => $recipient) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1357 |  |  | 			if (isset($recipient[PR_RECIPIENT_FLAGS]) && $recipient[PR_RECIPIENT_FLAGS] == (recipSendable | recipOrganizer)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1358 |  |  | 				$hasOrganizer = true; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1359 |  |  | 			} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1360 |  |  | 			elseif ($isException && !isset($recipient[PR_RECIPIENT_FLAGS])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1361 |  |  | 				// Recipients for an occurrence | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1362 |  |  | 				$recipients[$key][PR_RECIPIENT_FLAGS] = recipSendable | recipExceptionalResponse; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1363 |  |  | 			} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1364 |  |  | 		} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1365 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1366 |  |  | 		if (!$hasOrganizer) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1367 |  |  | 			// Create organizer. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1368 |  |  | 			$organizer = []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1369 |  |  | 			$organizer[PR_ENTRYID] = $messageProps[PR_SENT_REPRESENTING_ENTRYID]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1370 |  |  | 			$organizer[PR_DISPLAY_NAME] = $messageProps[PR_SENT_REPRESENTING_NAME]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1371 |  |  | 			$organizer[PR_EMAIL_ADDRESS] = $messageProps[PR_SENT_REPRESENTING_EMAIL_ADDRESS]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1372 |  |  | 			$organizer[PR_RECIPIENT_TYPE] = MAPI_TO; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1373 |  |  | 			$organizer[PR_RECIPIENT_DISPLAY_NAME] = $messageProps[PR_SENT_REPRESENTING_NAME]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1374 |  |  | 			$organizer[PR_ADDRTYPE] = empty($messageProps[PR_SENT_REPRESENTING_ADDRTYPE]) ? 'SMTP' : $messageProps[PR_SENT_REPRESENTING_ADDRTYPE]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1375 |  |  | 			$organizer[PR_RECIPIENT_TRACKSTATUS] = olRecipientTrackStatusNone; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1376 |  |  | 			$organizer[PR_RECIPIENT_FLAGS] = recipSendable | recipOrganizer; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1377 |  |  | 			$organizer[PR_SEARCH_KEY] = $messageProps[PR_SENT_REPRESENTING_SEARCH_KEY]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1378 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1379 |  |  | 			// Add organizer to recipients list. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1380 |  |  | 			array_unshift($recipients, $organizer); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1381 |  |  | 		} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1382 |  |  | 	} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1383 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1384 |  |  | 	/** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1385 |  |  | 	 * Returns restriction array for filtering embedded message attachments. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1386 |  |  | 	 * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1387 |  |  | 	 * @return array restriction array for ATTACH_EMBEDDED_MSG | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1388 |  |  | 	 */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1389 |  |  | 	private function getEmbeddedMessageRestriction(): array { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1390 |  |  | 		return [ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1391 |  |  | 			RES_PROPERTY, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1392 |  |  | 			[ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1393 |  |  | 				RELOP => RELOP_EQ, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1394 |  |  | 				ULPROPTAG => PR_ATTACH_METHOD, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1395 |  |  | 				VALUE => [PR_ATTACH_METHOD => ATTACH_EMBEDDED_MSG], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1396 |  |  | 			], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1397 |  |  | 		]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1398 |  |  | 	} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1399 |  |  | } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1400 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1401 |  |  | /* | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1402 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1403 |  |  | From http://www.ohelp-one.com/new-6765483-3268.html: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1404 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1405 |  |  | Recurrence Data Structure Offset Type Value | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1406 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1407 |  |  | 0 ULONG (?) Constant : { 0x04, 0x30, 0x04, 0x30} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1408 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1409 |  |  | 4 UCHAR 0x0A + recurrence type: 0x0A for daily, 0x0B for weekly, 0x0C for | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1410 |  |  | monthly, 0x0D for yearly | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1411 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1412 |  |  | 5 UCHAR Constant: { 0x20} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1413 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1414 |  |  | 6 ULONG Seems to be a variant of the recurrence type: 1 for daily every n | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1415 |  |  | days, 2 for daily every weekday and weekly, 3 for monthly or yearly. The | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1416 |  |  | special exception is regenerating tasks that regenerate on a weekly basis: 0 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1417 |  |  | is used in that case (I have no idea why). | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1418 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1419 |  |  | Here's the recurrence-type-specific data. Because the daily every N days | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1420 |  |  | data are 4 bytes shorter than the data for the other types, the offsets for | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1421 |  |  | the rest of the data will be 4 bytes off depending on the recurrence type. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1422 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1423 |  |  | Daily every N days: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1424 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1425 |  |  | 10 ULONG ( N - 1) * ( 24 * 60). I'm not sure what this is used for, but it's consistent. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1426 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1427 |  |  | 14 ULONG N * 24 * 60: minutes between recurrences | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1428 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1429 |  |  | 18 ULONG 0 for all events and non-regenerating recurring tasks. 1 for | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1430 |  |  | regenerating tasks. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1431 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1432 |  |  | Daily every weekday (this is essentially a subtype of weekly recurrence): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1433 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1434 |  |  | 10 ULONG 6 * 24 * 60: minutes between recurrences ( a week... sort of) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1435 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1436 |  |  | 14 ULONG 1: recur every week (corresponds to the second parameter for weekly | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1437 |  |  | recurrence) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1438 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1439 |  |  | 18 ULONG 0 for all events and non-regenerating recurring tasks. 1 for | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1440 |  |  | regenerating tasks. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1441 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1442 |  |  | 22 ULONG 0x3E: bitmask for recurring every weekday (corresponds to fourth | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1443 |  |  | parameter for weekly recurrence) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1444 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1445 |  |  | Weekly every N weeks for all events and non-regenerating tasks: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1446 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1447 |  |  | 10 ULONG 6 * 24 * 60: minutes between recurrences (a week... sort of) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1448 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1449 |  |  | 14 ULONG N: recurrence interval | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1450 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1451 |  |  | 18 ULONG Constant: 0 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1452 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1453 |  |  | 22 ULONG Bitmask for determining which days of the week the event recurs on | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1454 |  |  | ( 1 << dayOfWeek, where Sunday is 0). | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1455 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1456 |  |  | Weekly every N weeks for regenerating tasks: 10 ULONG Constant: 0 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1457 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1458 |  |  | 14 ULONG N * 7 * 24 * 60: recurrence interval in minutes between occurrences | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1459 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1460 |  |  | 18 ULONG Constant: 1 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1461 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1462 |  |  | Monthly every N months on day D: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1463 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1464 |  |  | 10 ULONG This is the most complicated value | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1465 |  |  | in the entire mess. It's basically a very complicated way of stating the | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1466 |  |  | recurrence interval. I tweaked fbs' basic algorithm. DateTime::MonthInDays | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1467 |  |  | simply returns the number of days in a given month, e.g. 31 for July for 28 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1468 |  |  | for February (the algorithm doesn't take into account leap years, but it | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1469 |  |  | doesn't seem to matter). My DateTime object, like Microsoft's COleDateTime, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1470 |  |  | uses 1-based months (i.e. January is 1, not 0). With that in mind, this | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1471 |  |  | works: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1472 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1473 |  |  | long monthIndex = ( ( ( ( 12 % schedule-=GetInterval()) * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1474 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1475 |  |  | ( ( schedule-=GetStartDate().GetYear() - 1601) % | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1476 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1477 |  |  | schedule-=GetInterval())) % schedule-=GetInterval()) + | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1478 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1479 |  |  | ( schedule-=GetStartDate().GetMonth() - 1)) % schedule-=GetInterval(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1480 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1481 |  |  | for( int i = 0; i < monthIndex; i++) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1482 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1483 |  |  | { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1484 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1485 |  |  | value += DateTime::GetDaysInMonth( ( i % 12) + 1) * 24 * 60; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1486 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1487 |  |  | } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1488 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1489 |  |  | This should work for any recurrence interval, including those greater than | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1490 |  |  | 12. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1491 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1492 |  |  | 14 ULONG N: recurrence interval | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1493 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1494 |  |  | 18 ULONG 0 for all events and non-regenerating recurring tasks. 1 for | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1495 |  |  | regenerating tasks. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1496 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1497 |  |  | 22 ULONG D: day of month the event recurs on (if this value is greater than | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1498 |  |  | the number of days in a given month [e.g. 31 for and recurs in June], then | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1499 |  |  | the event will recur on the last day of the month) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1500 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1501 |  |  | Monthly every N months on the Xth Y (e.g. "2nd Tuesday"): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1502 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1503 |  |  | 10 ULONG See above: same as for monthly every N months on day D | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1504 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1505 |  |  | 14 ULONG N: recurrence interval | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1506 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1507 |  |  | 18 ULONG 0 for all events and non-regenerating recurring tasks. 1 for | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1508 |  |  | regenerating tasks. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1509 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1510 |  |  | 22 ULONG Y: bitmask for determining which day of the week the event recurs | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1511 |  |  | on (see weekly every N weeks). Some useful values are 0x7F for any day, 0x3E | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1512 |  |  | for a weekday, or 0x41 for a weekend day. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1513 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1514 |  |  | 26 ULONG X: 1 for first occurrence, 2 for second, etc. 5 for last | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1515 |  |  | occurrence. E.g. for "2nd Tuesday", you should have values of 0x04 for the | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1516 |  |  | prior value and 2 for this one. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1517 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1518 |  |  | Yearly on day D of month M: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1519 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1520 |  |  | 10 ULONG M (sort of): This is another messy | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1521 |  |  | value. It's the number of minute since the startning of the year to the | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1522 |  |  | given month. For an explanation of GetDaysInMonth, see monthly every N | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1523 |  |  | months. This will work: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1524 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1525 |  |  | ULONG monthOfYearInMinutes = 0; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1526 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1527 |  |  | for( int i = DateTime::cJanuary; i < schedule-=GetMonth(); i++) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1528 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1529 |  |  | { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1530 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1531 |  |  | monthOfYearInMinutes += DateTime::GetDaysInMonth( i) * 24 * 60; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1532 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1533 |  |  | } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1534 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1535 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1536 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1537 |  |  | 14 ULONG 12: recurrence interval in months. Naturally, 12. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1538 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1539 |  |  | 18 ULONG 0 for all events and non-regenerating recurring tasks. 1 for | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1540 |  |  | regenerating tasks. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1541 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1542 |  |  | 22 ULONG D: day of month the event recurs on. See monthly every N months on | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1543 |  |  | day D. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1544 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1545 |  |  | Yearly on the Xth Y of month M: 10 ULONG M (sort of): See yearly on day D of | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1546 |  |  | month M. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1547 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1548 |  |  | 14 ULONG 12: recurrence interval in months. Naturally, 12. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1549 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1550 |  |  | 18 ULONG Constant: 0 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1551 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1552 |  |  | 22 ULONG Y: see monthly every N months on the Xth Y. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1553 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1554 |  |  | 26 ULONG X: see monthly every N months on the Xth Y. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1555 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1556 |  |  | After these recurrence-type-specific values, the offsets will change | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1557 |  |  | depending on the type. For every type except daily every N days, the offsets | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1558 |  |  | will grow by at least 4. For those types using the Xth Y, the offsets will | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1559 |  |  | grow by an additional 4, for a total of 8. The offsets for the rest of these | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1560 |  |  | values will be given for the most basic case, daily every N days, i.e. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1561 |  |  | without any growth. Adjust as necessary. Also, the presence of exceptions | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1562 |  |  | will change the offsets following the exception data by a variable number of | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1563 |  |  | bytes, so the offsets given in the table are accurate only for those | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1564 |  |  | recurrence patterns without any exceptions. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1565 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1566 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1567 |  |  | 22 UCHAR Type of pattern termination: 0x21 for terminating on a given date, 0x22 for terminating | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1568 |  |  | after a given number of recurrences, or 0x23 for never terminating | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1569 |  |  | (recurring infinitely) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1570 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1571 |  |  | 23 UCHARx3 Constant: { 0x20, 0x00, 0x00} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1572 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1573 |  |  | 26 ULONG Number of occurrences in pattern: 0 for infinite recurrence, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1574 |  |  | otherwise supply the value, even if it terminates on a given date, not after | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1575 |  |  | a given number | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1576 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1577 |  |  | 30 ULONG Constant: 0 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1578 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1579 |  |  | 34 ULONG Number of exceptions to pattern (i.e. deleted or changed | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1580 |  |  | occurrences) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1581 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1582 |  |  | .... ULONGxN Base date of each exception, given in hundreds of nanoseconds | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1583 |  |  | since 1601, so see below to turn them into a comprehensible format. The base | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1584 |  |  | date of an exception is the date (and only the date-- not the time) the | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1585 |  |  | exception would have occurred on in the pattern. They must occur in | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1586 |  |  | ascending order. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1587 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1588 |  |  | 38 ULONG Number of changed exceptions (i.e. total number of exceptions - | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1589 |  |  | number of deleted exceptions): if there are changed exceptions, again, more | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1590 |  |  | data will be needed, but that will wait | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1591 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1592 |  |  | .... ULONGxN Start date (and only the date-- not the time) of each changed | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1593 |  |  | exception, i.e. the exceptions which aren't deleted. These must also occur | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1594 |  |  | in ascending order. If all of the exceptions are deleted, this data will be | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1595 |  |  | absent. If present, they will be in the format above. Any dates that are in | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1596 |  |  | the first list but not in the second are exceptions that have been deleted | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1597 |  |  | (i.e. the difference between the two sets). Note that this is the start date | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1598 |  |  | (including time), not the base date. Given that the values are unordered and | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1599 |  |  | that they can't be matched up against the previous list in this iteration of | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1600 |  |  | the recurrence data (they could in previous ones), it is very difficult to | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1601 |  |  | tell which exceptions are deleted and which are changed. Fortunately, for | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1602 |  |  | this new format, the base dates are given on the attachment representing the | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1603 |  |  | changed exception (described below), so you can simply ignore this list of | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1604 |  |  | changed exceptions. Just create a list of exceptions from the previous list | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1605 |  |  | and assume they're all deleted unless you encounter an attachment with a | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1606 |  |  | matching base date later on. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1607 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1608 |  |  | 42 ULONG Start date of pattern given in hundreds of nanoseconds since 1601; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1609 |  |  | see below for an explanation. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1610 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1611 |  |  | 46 ULONG End date of pattern: see start date of pattern | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1612 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1613 |  |  | 50 ULONG Constant: { 0x06, 0x30, 0x00, 0x00} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1614 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1615 |  |  | NOTE: I find the following 8-byte sequence of bytes to be very useful for | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1616 |  |  | orienting myself when looking at the raw data. If you can find { 0x06, 0x30, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1617 |  |  | 0x00, 0x00, 0x08, 0x30, 0x00, 0x00}, you can use these tables to work either | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1618 |  |  | forwards or backwards to find the data you need. The sequence sort of | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1619 |  |  | delineates certain critical exception-related data and delineates the | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1620 |  |  | exceptions themselves from the rest of the data and is relatively easy to | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1621 |  |  | find. If you're going to be meddling in here a lot, I suggest making a | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1622 |  |  | friend of ol' 0x00003006. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1623 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1624 |  |  | 54 UCHAR This number is some kind of version indicator. Use 0x08 for Outlook | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1625 |  |  | 2003. I believe 0x06 is Outlook 2000 and possibly 98, while 0x07 is Outlook | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1626 |  |  | XP. This number must be consistent with the features of the data structure | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1627 |  |  | generated by the version of Outlook indicated thereby-- there are subtle | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1628 |  |  | differences between the structures, and, if the version doesn't match the | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1629 |  |  | data, Outlook will sometimes failto read the structure. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1630 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1631 |  |  | 55 UCHARx3 Constant: { 0x30, 0x00, 0x00} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1632 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1633 |  |  | 58 ULONG Start time of occurrence in minutes: e.g. 0 for midnight or 720 for | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1634 |  |  | 12 PM | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1635 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1636 |  |  | 62 ULONG End time of occurrence in minutes: i.e. start time + duration, e.g. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1637 |  |  | 900 for an event that starts at 12 PM and ends at 3PM | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1638 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1639 |  |  | Exception Data 66 USHORT Number of changed exceptions: essentially a check | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1640 |  |  | on the prior occurrence of this value; should be equivalent. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1641 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1642 |  |  | NOTE: The following structure will occur N many times (where N = number of | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1643 |  |  | changed exceptions), and each structure can be of variable length. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1644 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1645 |  |  | .... ULONG Start date of changed exception given in hundreds of nanoseconds | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1646 |  |  | since 1601 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1647 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1648 |  |  | .... ULONG End date of changed exception given in hundreds of nanoseconds | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1649 |  |  | since 1601 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1650 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1651 |  |  | .... ULONG This is a value I don't clearly understand. It seems to be some | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1652 |  |  | kind of archival value that matches the start time most of the time, but | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1653 |  |  | will lag behind when the start time is changed and then match up again under | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1654 |  |  | certain conditions later. In any case, setting to the same value as the | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1655 |  |  | start time seems to work just fine (more information on this value would be | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1656 |  |  | appreciated). | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1657 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1658 |  |  | .... USHORT Bitmask of changes to the exception (see below). This will be 0 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1659 |  |  | if the only changes to the exception were to its start or end time. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1660 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1661 |  |  | .... ULONGxN Numeric values (e.g. label or minutes to remind before the | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1662 |  |  | event) changed in the exception. These will occur in the order of their | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1663 |  |  | corresponding bits (see below). If no numeric values were changed, then | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1664 |  |  | these values will be absent. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1665 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1666 |  |  | NOTE: The following three values constitute a single sub-structure that will | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1667 |  |  | occur N many times, where N is the number of strings that are changed in the | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1668 |  |  | exception. Since there are at most 2 string values that can be excepted | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1669 |  |  | (i.e. subject [or description], and location), there can at most be two of | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1670 |  |  | these, but there may be none. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1671 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1672 |  |  | .... USHORT Length of changed string value with NULL character | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1673 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1674 |  |  | .... USHORT Length of changed string value without NULL character (i.e. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1675 |  |  | previous value - 1) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1676 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1677 |  |  | .... CHARxN Changed string value (without NULL terminator) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1678 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1679 |  |  | Unicode Data NOTE: If a string value was changed on an exception, those | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1680 |  |  | changed string values will reappear here in Unicode format after 8 bytes of | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1681 |  |  | NULL padding (possibly a Unicode terminator?). For each exception with a | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1682 |  |  | changed string value, there will be an identifier, followed by the changed | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1683 |  |  | strings in Unicode. The strings will occur in the order of their | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1684 |  |  | corresponding bits (see below). E.g., if both subject and location were | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1685 |  |  | changed in the exception, there would be the 3-ULONG identifier, then the | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1686 |  |  | length of the subject, then the subject, then the length of the location, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1687 |  |  | then the location. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1688 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1689 |  |  | 70 ULONGx2 Constant: { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}. This | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1690 |  |  | padding serves as a barrier between the older data structure and the | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1691 |  |  | appended Unicode data. This is the same sequence as the Unicode terminator, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1692 |  |  | but I'm not sure whether that's its identity or not. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1693 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1694 |  |  | .... ULONGx3 These are the three times used to identify the exception above: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1695 |  |  | start date, end date, and repeated start date. These should be the same as | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1696 |  |  | they were above. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1697 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1698 |  |  | .... USHORT Length of changed string value without NULL character. This is | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1699 |  |  | given as count of WCHARs, so it should be identical to the value above. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1700 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1701 |  |  | .... WCHARxN Changed string value in Unicode (without NULL terminator) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1702 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1703 |  |  | Terminator ... ULONGxN Constant: { 0x00, 0x00, 0x00, 0x00}. 4 bytes of NULL | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1704 |  |  | padding per changed exception. If there were no changed exceptions, all | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1705 |  |  | you'll need is the final terminator below. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1706 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1707 |  |  | .... ULONGx2 Constant: { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1708 |  |  |  | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 1709 |  |  | */ | 
            
                                                        
            
                                    
            
            
                | 1710 |  |  |  |