Passed
Push — master ( bc722f...03cdb2 )
by
unknown
03:21 queued 12s
created

TaskRequest::getSubProperties()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 19
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 17
c 0
b 0
f 0
nop 0
dl 0
loc 19
rs 9.7
nc 1
1
<?php
2
/*
3
 * SPDX-License-Identifier: AGPL-3.0-only
4
 * SPDX-FileCopyrightText: Copyright 2005-2016 Zarafa Deutschland GmbH
5
 * SPDX-FileCopyrightText: Copyright 2020-2022 grommunio GmbH
6
 */
7
8
	/*
9
	* In general
10
	*
11
	* This class never actually modifies a task item unless we receive a task request update. This means
12
	* that setting all the properties to make the task item itself behave like a task request is up to the
13
	* caller.
14
	*
15
	* The only exception to this is the generation of the TaskGlobalObjId, the unique identifier identifying
16
	* this task request to both the organizer and the assignee. The globalobjectid is generated when the
17
	* task request is sent via sendTaskRequest.
18
	*/
19
20
	/* The TaskMode value is only used for the IPM.TaskRequest items.
21
	 * It must 0 (tdmtNothing) on IPM.Task items.
22
	 *
23
	 * It is used to indicate the type of change that is being
24
	 * carried in the IPM.TaskRequest item (although this information seems
25
	 * redundant due to that information already being available in PR_MESSAGE_CLASS).
26
	 */
27
	define('tdmtNothing', 0);			// Value in IPM.Task items
28
	define('tdmtTaskReq', 1);			// Assigner -> Assignee
29
	define('tdmtTaskAcc', 2);			// Assignee -> Assigner
30
	define('tdmtTaskDec', 3);			// Assignee -> Assigner
31
	define('tdmtTaskUpd', 4);			// Assignee -> Assigner
32
	define('tdmtTaskSELF', 5);			// Assigner -> Assigner (?)
33
34
	/* The TaskHistory is used to show the last action on the task
35
	 * on both the assigner and the assignee's side.
36
	 *
37
	 * It is used in combination with 'task_assigned_time' and 'tasklastdelegate'
38
	 * or 'tasklastuser' to show the information at the top of the task request in
39
	 * the format 'Accepted by <user> on 01-01-2010 11:00'.
40
	 */
41
	define('thNone', 0);
42
	define('thAccepted', 1);			// Set by assignee
43
	define('thDeclined', 2);			// Set by assignee
44
	define('thUpdated', 3);				// Set by assignee
45
	define('thDueDateChanged', 4);
46
	define('thAssigned', 5);			// Set by assigner
47
48
	/* The TaskState value is used to differentiate the version of a task
49
	 * in the assigner's folder and the version in the
50
	 * assignee's folder. The buttons shown depend on this and
51
	 * the 'taskaccepted' boolean (for the assignee)
52
	 */
53
	define('tdsNOM', 0);		// Got a response to a deleted task, and re-created the task for the assigner
54
	define('tdsOWNNEW', 1);		// Not assigned
55
	define('tdsOWN', 2);		// Assignee version
56
	define('tdsACC', 3);		// Assigner version
57
	define('tdsDEC', 4);		// Assigner version, but assignee declined
58
59
	/* The TaskAcceptanceState is used for the assigner to indicate state */
60
	define('olTaskNotDelegated', 0);
61
	define('olTaskDelegationUnknown', 1); // After sending req
62
	define('olTaskDelegationAccepted', 2); // After receiving accept
63
	define('olTaskDelegationDeclined', 3); // After receiving decline
64
65
	/* The task ownership indicates the role of the current user relative to the task. */
66
	define('olNewTask', 0);
67
	define('olDelegatedTask', 1);	// Task has been assigned
68
	define('olOwnTask', 2);			// Task owned
69
70
	/* taskmultrecips indicates whether the task request sent or received has multiple assignees or not. */
71
	define('tmrNone', 0);
72
	define('tmrSent', 1);		// Task has been sent to multiple assignee
73
	define('tmrReceived', 2);	// Task Request received has multiple assignee
74
75
	// Task icon index.
76
	define('ICON_TASK_ASSIGNEE', 0x00000502);
77
	define('ICON_TASK_DECLINE', 0x00000506);
78
	define('ICON_TASK_ASSIGNER', 0x00000503);
79
80
	class TaskRequest {
81
		private $props;
82
		private $store;
83
		private $message;
84
		private $session;
85
		private $taskCommentsInfo;
86
87
		// All recipient properties
88
		public $recipProps = [
89
			PR_ENTRYID,
90
			PR_DISPLAY_NAME,
0 ignored issues
show
Bug introduced by
The constant PR_DISPLAY_NAME was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
91
			PR_EMAIL_ADDRESS,
0 ignored issues
show
Bug introduced by
The constant PR_EMAIL_ADDRESS was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
92
			PR_RECIPIENT_ENTRYID,
0 ignored issues
show
Bug introduced by
The constant PR_RECIPIENT_ENTRYID was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
93
			PR_RECIPIENT_TYPE,
0 ignored issues
show
Bug introduced by
The constant PR_RECIPIENT_TYPE was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
94
			PR_SEND_INTERNET_ENCODING,
0 ignored issues
show
Bug introduced by
The constant PR_SEND_INTERNET_ENCODING was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
95
			PR_SEND_RICH_INFO,
0 ignored issues
show
Bug introduced by
The constant PR_SEND_RICH_INFO was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
96
			PR_RECIPIENT_DISPLAY_NAME,
0 ignored issues
show
Bug introduced by
The constant PR_RECIPIENT_DISPLAY_NAME was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
97
			PR_ADDRTYPE,
0 ignored issues
show
Bug introduced by
The constant PR_ADDRTYPE was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
98
			PR_DISPLAY_TYPE,
0 ignored issues
show
Bug introduced by
The constant PR_DISPLAY_TYPE was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
99
			PR_RECIPIENT_TRACKSTATUS,
0 ignored issues
show
Bug introduced by
The constant PR_RECIPIENT_TRACKSTATUS was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
100
			PR_RECIPIENT_TRACKSTATUS_TIME,
0 ignored issues
show
Bug introduced by
The constant PR_RECIPIENT_TRACKSTATUS_TIME was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
101
			PR_RECIPIENT_FLAGS,
0 ignored issues
show
Bug introduced by
The constant PR_RECIPIENT_FLAGS was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
102
			PR_ROWID,
0 ignored issues
show
Bug introduced by
The constant PR_ROWID was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
103
			PR_SEARCH_KEY,
0 ignored issues
show
Bug introduced by
The constant PR_SEARCH_KEY was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
104
		];
105
106
		/**
107
		 * Constructor
108
		 *
109
		 * Constructs a TaskRequest object for the specified message. This can be either the task request
110
		 * message itself (in the inbox) or the task in the tasks folder, depending on the action to be performed.
111
		 *
112
		 * As a general rule, the object message passed is the object 'in view' when the user performs one of the
113
		 * actions in this class.
114
		 *
115
		 * @param resource $store   MAPI Store in which $message resides. This is also the store where the tasks folder is assumed to be in
116
		 * @param resource $message MAPI Message to which the task request refers (can be an email or a task)
117
		 * @param resource $session MAPI Session which is used to open tasks folders for delegated task requests or responses
118
		 */
119
		public function __construct($store, $message, $session) {
120
			$this->store = $store;
121
			$this->message = $message;
122
			$this->session = $session;
123
			$this->taskCommentsInfo = false;
124
125
			$properties = [];
126
			$properties["owner"] = "PT_STRING8:PSETID_Task:0x811f";
127
			$properties["updatecount"] = "PT_LONG:PSETID_Task:0x8112";
128
			$properties["taskstate"] = "PT_LONG:PSETID_Task:0x8113";
129
			$properties["taskmultrecips"] = "PT_LONG:PSETID_Task:0x8120";
130
			$properties["taskupdates"] = "PT_BOOLEAN:PSETID_Task:0x811b";
131
			$properties["tasksoc"] = "PT_BOOLEAN:PSETID_Task:0x8119";
132
			$properties["taskhistory"] = "PT_LONG:PSETID_Task:0x811a";
133
			$properties["taskmode"] = "PT_LONG:PSETID_Common:0x8518";
134
			$properties["task_goid"] = "PT_BINARY:PSETID_Common:0x8519";
135
			$properties["complete"] = "PT_BOOLEAN:PSETID_Common:" . PidLidTaskComplete;
0 ignored issues
show
Bug introduced by
The constant PidLidTaskComplete was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
136
			$properties["task_assigned_time"] = "PT_SYSTIME:PSETID_Task:0x8115";
137
			$properties["taskfcreator"] = "PT_BOOLEAN:PSETID_Task:0x0x811e";
138
			$properties["tasklastuser"] = "PT_STRING8:PSETID_Task:0x8122";
139
			$properties["tasklastdelegate"] = "PT_STRING8:PSETID_Task:0x8125";
140
			$properties["taskaccepted"] = "PT_BOOLEAN:PSETID_Task:0x8108";
141
			$properties["task_acceptance_state"] = "PT_LONG:PSETID_Task:0x812a";
142
			$properties["ownership"] = "PT_LONG:PSETID_Task:0x8129";
143
144
			$properties["complete"] = "PT_BOOLEAN:PSETID_Task:" . PidLidTaskComplete;
145
			$properties["datecompleted"] = "PT_SYSTIME:PSETID_Task:" . PidLidTaskDateCompleted;
0 ignored issues
show
Bug introduced by
The constant PidLidTaskDateCompleted was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
146
			$properties["recurring"] = "PT_BOOLEAN:PSETID_Task:0x8126";
147
			$properties["startdate"] = "PT_SYSTIME:PSETID_Task:" . PidLidTaskStartDate;
0 ignored issues
show
Bug introduced by
The constant PidLidTaskStartDate was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
148
			$properties["duedate"] = "PT_SYSTIME:PSETID_Task:" . PidLidTaskDueDate;
0 ignored issues
show
Bug introduced by
The constant PidLidTaskDueDate was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
149
			$properties["status"] = "PT_LONG:PSETID_Task:" . PidLidTaskStatus;
0 ignored issues
show
Bug introduced by
The constant PidLidTaskStatus was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
150
			$properties["percent_complete"] = "PT_DOUBLE:PSETID_Task:" . PidLidPercentComplete;
0 ignored issues
show
Bug introduced by
The constant PidLidPercentComplete was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
151
			$properties["totalwork"] = "PT_LONG:PSETID_Task:0x8111";
152
			$properties["actualwork"] = "PT_LONG:PSETID_Task:0x8110";
153
			$properties["categories"] = "PT_MV_STRING8:PS_PUBLIC_STRINGS:Keywords";
154
			$properties["companies"] = "PT_MV_STRING8:PSETID_Common:0x8539";
155
			$properties["mileage"] = "PT_STRING8:PSETID_Common:0x8534";
156
			$properties["billinginformation"] = "PT_STRING8:PSETID_Common:0x8535";
157
158
			$this->props = getPropIdsFromStrings($store, $properties);
159
		}
160
161
		// General functions
162
163
		/**
164
		 * Returns TRUE if the message pointed to is an incoming task request and should
165
		 * therefore be replied to with doAccept or doDecline().
166
		 *
167
		 * @param mixed $messageClass message class to use for checking
168
		 *
169
		 * @return bool true if this is a task request else false
170
		 */
171
		public function isTaskRequest($messageClass = false) {
172
			if ($messageClass === false) {
173
				$props = mapi_getprops($this->message, [PR_MESSAGE_CLASS]);
0 ignored issues
show
Bug introduced by
The constant PR_MESSAGE_CLASS was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
174
				$messageClass = isset($props[PR_MESSAGE_CLASS]) ? $props[PR_MESSAGE_CLASS] : false;
175
			}
176
177
			if ($messageClass !== false && $messageClass === "IPM.TaskRequest") {
178
				return true;
179
			}
180
181
			return false;
182
		}
183
184
		/**
185
		 * Returns TRUE if the message pointed to is a returning task request response.
186
		 *
187
		 * @param mixed $messageClass message class to use for checking
188
		 *
189
		 * @return bool true if this is a task request else false
190
		 */
191
		public function isTaskRequestResponse($messageClass = false) {
192
			if ($messageClass === false) {
193
				$props = mapi_getprops($this->message, [PR_MESSAGE_CLASS]);
0 ignored issues
show
Bug introduced by
The constant PR_MESSAGE_CLASS was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
194
				$messageClass = isset($props[PR_MESSAGE_CLASS]) ? $props[PR_MESSAGE_CLASS] : false;
195
			}
196
197
			if ($messageClass !== false && strpos($messageClass, "IPM.TaskRequest.") === 0) {
198
				return true;
199
			}
200
201
			return false;
202
		}
203
204
		/**
205
		 * Returns TRUE if the message pointed to is an incoming task request/response.
206
		 *
207
		 * @param array $props The MAPI properties to check message is an incoming task request/response
208
		 *
209
		 * @return bool true if this is an incoming task request/response else false
210
		 */
211
		public function isReceivedItem($props) {
212
			return isset($props[PR_MESSAGE_TO_ME]) ? $props[PR_MESSAGE_TO_ME] : false;
0 ignored issues
show
Bug introduced by
The constant PR_MESSAGE_TO_ME was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
213
		}
214
215
		/**
216
		 * Gets the task associated with an IPM.TaskRequest message.
217
		 *
218
		 * If the task does not exist yet, it is created, using the attachment object in the
219
		 * task request item.
220
		 *
221
		 * @param bool $create true - try create task in user's task folder if task does not exist
222
		 *                     false - find the associated task in user's task folder
223
		 *
224
		 * @return resource|bool associated task of task request else false
225
		 */
226
		public function getAssociatedTask($create) {
227
			$props = mapi_getprops($this->message, [PR_MESSAGE_CLASS, $this->props['task_goid']]);
0 ignored issues
show
Bug introduced by
The constant PR_MESSAGE_CLASS was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
228
229
			if ($props[PR_MESSAGE_CLASS] == "IPM.Task") {
230
				// Message itself is task, so return that
231
				return $this->message;
232
			}
233
234
			$taskFolder = $this->getDefaultTasksFolder();
235
			$goid = $props[$this->props['task_goid']];
236
237
			// Find the task by looking for the task_goid
238
			$restriction = [
239
				RES_PROPERTY,
240
				[
241
					RELOP => RELOP_EQ,
242
					ULPROPTAG => $this->props['task_goid'],
243
					VALUE => $goid,
244
				],
245
			];
246
247
			$contents = mapi_folder_getcontentstable($taskFolder);
248
249
			$rows = mapi_table_queryallrows($contents, [PR_ENTRYID], $restriction);
250
251
			if (empty($rows)) {
252
				// None found, create one if possible
253
				if (!$create) {
254
					return false;
255
				}
256
257
				$task = mapi_folder_createmessage($taskFolder);
258
259
				$sub = $this->getEmbeddedTask();
260
				mapi_copyto($sub, [], [$this->props['categories']], $task);
261
262
				$senderProps = [
263
					PR_SENT_REPRESENTING_NAME,
0 ignored issues
show
Bug introduced by
The constant PR_SENT_REPRESENTING_NAME was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
264
					PR_SENT_REPRESENTING_EMAIL_ADDRESS,
0 ignored issues
show
Bug introduced by
The constant PR_SENT_REPRESENTING_EMAIL_ADDRESS was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
265
					PR_SENT_REPRESENTING_ENTRYID,
0 ignored issues
show
Bug introduced by
The constant PR_SENT_REPRESENTING_ENTRYID was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
266
					PR_SENT_REPRESENTING_ADDRTYPE,
0 ignored issues
show
Bug introduced by
The constant PR_SENT_REPRESENTING_ADDRTYPE was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
267
					PR_SENT_REPRESENTING_SEARCH_KEY,
0 ignored issues
show
Bug introduced by
The constant PR_SENT_REPRESENTING_SEARCH_KEY was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
268
					PR_SENDER_NAME,
0 ignored issues
show
Bug introduced by
The constant PR_SENDER_NAME was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
269
					PR_SENDER_EMAIL_ADDRESS,
0 ignored issues
show
Bug introduced by
The constant PR_SENDER_EMAIL_ADDRESS was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
270
					PR_SENDER_ENTRYID,
0 ignored issues
show
Bug introduced by
The constant PR_SENDER_ENTRYID was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
271
					PR_SENDER_ADDRTYPE,
0 ignored issues
show
Bug introduced by
The constant PR_SENDER_ADDRTYPE was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
272
					PR_SENDER_SEARCH_KEY, ];
0 ignored issues
show
Bug introduced by
The constant PR_SENDER_SEARCH_KEY was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
273
274
				// Copy sender information from the e-mail
275
				$props = mapi_getprops($this->message, $senderProps);
276
				$props[PR_MESSAGE_CLASS] = 'IPM.Task';
277
				mapi_setprops($task, $props);
278
			}
279
			else {
280
				// If there are multiple, just use the first
281
				$entryid = $rows[0][PR_ENTRYID];
282
283
				$store = $this->getTaskFolderStore();
284
				$task = mapi_msgstore_openentry($store, $entryid);
285
			}
286
287
			return $task;
288
		}
289
290
		/**
291
		 * Function which checks that if we have received a task request/response
292
		 * for an already updated task in task folder.
293
		 *
294
		 * @return bool true if task request is updated later
295
		 */
296
		public function isTaskRequestUpdated() {
297
			$props = mapi_getprops($this->message, [PR_MESSAGE_CLASS, $this->props['task_goid'], $this->props['updatecount']]);
0 ignored issues
show
Bug introduced by
The constant PR_MESSAGE_CLASS was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
298
			$result = false;
299
			$associatedTask = $this->getAssociatedTask(false);
300
			if ($this->isTaskRequest($props[PR_MESSAGE_CLASS])) {
301
				if ($associatedTask) {
302
					return true;
303
				}
304
				$folder = $this->getDefaultTasksFolder();
305
				$goid = $props[$this->props['task_goid']];
306
307
				// Find the task by looking for the task_goid
308
				$restriction = [
309
					RES_PROPERTY,
310
					[
311
						RELOP => RELOP_EQ,
312
						ULPROPTAG => $this->props['task_goid'],
313
						VALUE => $goid,
314
					],
315
				];
316
317
				$table = mapi_folder_getcontentstable($folder, MAPI_DEFERRED_ERRORS | SHOW_SOFT_DELETES);
318
				$softDeletedItems = mapi_table_queryallrows($table, [PR_ENTRYID], $restriction);
319
				if (!empty($softDeletedItems)) {
320
					return true;
321
				}
322
			}
323
324
			if ($associatedTask !== false) {
325
				$taskItemProps = mapi_getprops($associatedTask, [$this->props['updatecount']]);
326
				/*
327
				 * if(message_counter < task_counter) task object is newer then task response (task is updated)
328
				 * if(message_counter >= task_counter) task is not updated, do normal processing
329
				 */
330
				if (isset($taskItemProps[$this->props['updatecount']], $props[$this->props['updatecount']])) {
331
					if ($props[$this->props['updatecount']] < $taskItemProps[$this->props['updatecount']]) {
332
						$result = true;
333
					}
334
				}
335
			}
336
337
			return $result;
338
		}
339
340
		// Organizer functions (called by the organizer)
341
342
		/**
343
		 * Processes a task request response, which can be any of the following:
344
		 * - Task accept (task history is marked as accepted)
345
		 * - Task decline (task history is marked as declined)
346
		 * - Task update (updates completion %, etc).
347
		 */
348
		public function processTaskResponse() {
349
			$messageProps = mapi_getprops($this->message, [PR_PROCESSED, $this->props["taskupdates"], PR_MESSAGE_TO_ME]);
0 ignored issues
show
Bug introduced by
The constant PR_MESSAGE_TO_ME was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
Bug introduced by
The constant PR_PROCESSED was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
350
			if (isset($messageProps[PR_PROCESSED]) && $messageProps[PR_PROCESSED]) {
351
				return true;
352
			}
353
			mapi_setprops($this->message, [PR_PROCESSED => true]);
354
			mapi_savechanges($this->message);
355
356
			// Get the embedded task information.
357
			$sub = $this->getEmbeddedTask();
358
			// OL saves the task related properties in the embedded message
359
			$subProps = mapi_getprops($sub, [$this->props["taskupdates"]]);
360
361
			// If task is updated in task folder then we don't need to process
362
			// old response
363
			if ($this->isTaskRequestUpdated()) {
364
				return true;
365
			}
366
367
			$isReceivedItem = $this->isReceivedItem($messageProps);
368
369
			$isCreateAssociatedTask = false;
370
			$isAllowUpdateAssociatedTask = $subProps[$this->props["taskupdates"]];
371
			$props = mapi_getprops($this->message, [PR_MESSAGE_CLASS]);
0 ignored issues
show
Bug introduced by
The constant PR_MESSAGE_CLASS was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
372
			// Set correct taskmode and taskhistory depending on response type
373
			switch ($props[PR_MESSAGE_CLASS]) {
374
				case 'IPM.TaskRequest.Accept':
375
					$taskHistory = thAccepted;
376
					$taskState = $isReceivedItem ? tdsACC : tdsOWN;
377
					$taskOwner = $isReceivedItem ? olDelegatedTask : olOwnTask;
378
					$taskAcceptanceState = $isReceivedItem ? olTaskDelegationAccepted : olTaskNotDelegated;
379
					break;
380
381
				case 'IPM.TaskRequest.Decline':
382
					$isCreateAssociatedTask = $isReceivedItem;
383
					$isAllowUpdateAssociatedTask = $isReceivedItem;
384
					$taskHistory = thDeclined;
385
					$taskState = $isReceivedItem ? tdsDEC : tdsACC;
386
					$taskOwner = $isReceivedItem ? olOwnTask : olDelegatedTask;
387
					$taskAcceptanceState = $isReceivedItem ? olTaskDelegationDeclined : olTaskDelegationUnknown;
388
					break;
389
390
				case 'IPM.TaskRequest.Update':
391
				case 'IPM.TaskRequest.Complete':
392
					$taskHistory = thUpdated;
393
					$taskState = $isReceivedItem ? tdsACC : tdsOWN;
394
					$taskAcceptanceState = olTaskNotDelegated;
395
					$taskOwner = $isReceivedItem ? olDelegatedTask : olOwnTask;
396
					break;
397
			}
398
399
			$props = [
400
				$this->props['taskhistory'] => $taskHistory,
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $taskHistory does not seem to be defined for all execution paths leading up to this point.
Loading history...
401
				$this->props['taskstate'] => $taskState,
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $taskState does not seem to be defined for all execution paths leading up to this point.
Loading history...
402
				$this->props['task_acceptance_state'] => $taskAcceptanceState,
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $taskAcceptanceState does not seem to be defined for all execution paths leading up to this point.
Loading history...
403
				$this->props['ownership'] => $taskOwner,
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $taskOwner does not seem to be defined for all execution paths leading up to this point.
Loading history...
404
			];
405
406
			// Get the task for this response
407
			$task = $this->getAssociatedTask($isCreateAssociatedTask);
408
			if ($task && $isAllowUpdateAssociatedTask) {
409
				// To avoid duplication of attachments in associated task. we simple remove the
410
				// all attachments from associated task.
411
				$taskAttachTable = mapi_message_getattachmenttable($task);
412
				$taskAttachments = mapi_table_queryallrows($taskAttachTable, [PR_ATTACH_NUM]);
0 ignored issues
show
Bug introduced by
The constant PR_ATTACH_NUM was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
413
				foreach ($taskAttachments as $taskAttach) {
414
					mapi_message_deleteattach($task, $taskAttach[PR_ATTACH_NUM]);
415
				}
416
417
				$ignoreProps = [
418
					$this->props['taskstate'],
419
					$this->props['taskhistory'],
420
					$this->props['taskmode'],
421
					$this->props['taskfcreator'],
422
				];
423
				// Ignore PR_ICON_INDEX when task request response
424
				// is not received item.
425
				if ($isReceivedItem === false) {
426
					$ignoreProps[] = PR_ICON_INDEX;
0 ignored issues
show
Bug introduced by
The constant PR_ICON_INDEX was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
427
				}
428
429
				// We copy all properties except taskstate, taskhistory, taskmode and taskfcreator properties
430
				// from $sub message to $task even also we copy all attachments from $sub to $task message.
431
				mapi_copyto($sub, [], $ignoreProps, $task);
432
				$senderProps = mapi_getprops($this->message, [
433
					PR_SENDER_NAME,
0 ignored issues
show
Bug introduced by
The constant PR_SENDER_NAME was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
434
					PR_SENDER_EMAIL_ADDRESS,
0 ignored issues
show
Bug introduced by
The constant PR_SENDER_EMAIL_ADDRESS was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
435
					PR_SENDER_ENTRYID,
0 ignored issues
show
Bug introduced by
The constant PR_SENDER_ENTRYID was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
436
					PR_SENDER_ADDRTYPE,
0 ignored issues
show
Bug introduced by
The constant PR_SENDER_ADDRTYPE was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
437
					PR_SENDER_SEARCH_KEY,
0 ignored issues
show
Bug introduced by
The constant PR_SENDER_SEARCH_KEY was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
438
					PR_MESSAGE_DELIVERY_TIME,
0 ignored issues
show
Bug introduced by
The constant PR_MESSAGE_DELIVERY_TIME was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
439
					PR_SENT_REPRESENTING_NAME,
0 ignored issues
show
Bug introduced by
The constant PR_SENT_REPRESENTING_NAME was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
440
					PR_SENT_REPRESENTING_EMAIL_ADDRESS,
0 ignored issues
show
Bug introduced by
The constant PR_SENT_REPRESENTING_EMAIL_ADDRESS was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
441
					PR_SENT_REPRESENTING_ADDRTYPE,
0 ignored issues
show
Bug introduced by
The constant PR_SENT_REPRESENTING_ADDRTYPE was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
442
					PR_SENT_REPRESENTING_ENTRYID,
0 ignored issues
show
Bug introduced by
The constant PR_SENT_REPRESENTING_ENTRYID was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
443
					PR_SENT_REPRESENTING_SEARCH_KEY, ]);
0 ignored issues
show
Bug introduced by
The constant PR_SENT_REPRESENTING_SEARCH_KEY was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
444
445
				mapi_setprops($task, $senderProps);
446
447
				// Update taskstate and task history (last action done by the assignee)
448
				mapi_setprops($task, $props);
449
450
				// Copy missing properties from embedded task
451
				$subProperties = $this->getSubProperties();
452
				$subprops = mapi_getprops($sub, $subProperties);
453
				mapi_setprops($task, $subprops);
454
455
				mapi_savechanges($task);
456
			}
457
458
			mapi_setprops($this->message, $props);
459
			mapi_savechanges($this->message);
460
461
			if ($isReceivedItem) {
462
				$this->updateSentTaskRequest();
463
			}
464
465
			return true;
466
		}
467
468
		/**
469
		 * Update the sent task request in sent items folder.
470
		 *
471
		 * @return bool
472
		 */
473
		public function updateSentTaskRequest() {
474
			$props = mapi_getprops($this->message, [
475
				$this->props['taskhistory'],
476
				$this->props["taskstate"],
477
				$this->props["ownership"],
478
				$this->props['task_goid'],
479
				$this->props['task_acceptance_state'],
480
				$this->props["tasklastuser"],
481
				$this->props["tasklastdelegate"], ]);
482
483
			$store = $this->getDefaultStore();
484
			$storeProps = mapi_getprops($store, [PR_IPM_SENTMAIL_ENTRYID]);
0 ignored issues
show
Bug introduced by
The constant PR_IPM_SENTMAIL_ENTRYID was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
485
486
			$sentFolder = mapi_msgstore_openentry($store, $storeProps[PR_IPM_SENTMAIL_ENTRYID]);
487
			if (!$sentFolder) {
488
				return false;
489
			}
490
491
			// Find the task by looking for the task_goid
492
			$restriction = [
493
				RES_PROPERTY,
494
				[
495
					RELOP => RELOP_EQ,
496
					ULPROPTAG => $this->props['task_goid'],
497
					VALUE => $props[$this->props['task_goid']],
498
				],
499
			];
500
501
			$contentsTable = mapi_folder_getcontentstable($sentFolder);
502
503
			$rows = mapi_table_queryallrows($contentsTable, [PR_ENTRYID], $restriction);
504
505
			if (!empty($rows)) {
506
				foreach ($rows as $row) {
507
					$sentTaskRequest = mapi_msgstore_openentry($store, $row[PR_ENTRYID]);
508
					mapi_setprops($sentTaskRequest, $props);
509
					mapi_setprops($sentTaskRequest, [PR_PROCESSED => true]);
0 ignored issues
show
Bug introduced by
The constant PR_PROCESSED was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
510
					mapi_savechanges($sentTaskRequest);
511
				}
512
			}
513
514
			return true;
515
		}
516
517
		/**
518
		 * Creates a new message in the current user's outbox and submits it.
519
		 *
520
		 * Takes the task passed in the constructor as the task to be sent; recipient should
521
		 * be pre-existing. The task request will be sent to all recipients.
522
		 *
523
		 * @param string $prefix
524
		 */
525
		public function sendTaskRequest($prefix) {
526
			// Generate a TaskGlobalObjectId
527
			$taskid = $this->createTGOID();
528
			$messageprops = mapi_getprops($this->message, [PR_SUBJECT]);
0 ignored issues
show
Bug introduced by
The constant PR_SUBJECT was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
529
530
			// Set properties on Task Request
531
			mapi_setprops($this->message, [
532
				$this->props['task_goid'] => $taskid, // our new task_goid
533
				$this->props['taskstate'] => tdsACC, // state for our outgoing request
534
				$this->props['taskmode'] => tdmtNothing, // we're not sending a change
535
				$this->props['updatecount'] => 2, // version 2 (no idea)
536
				$this->props['task_acceptance_state'] => olTaskDelegationUnknown, // no reply yet
537
				$this->props['ownership'] => olDelegatedTask, // Task has been assigned
538
				$this->props['taskhistory'] => thAssigned, // Task has been assigned
539
				PR_CONVERSATION_TOPIC => $messageprops[PR_SUBJECT],
0 ignored issues
show
Bug introduced by
The constant PR_CONVERSATION_TOPIC was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
540
				PR_ICON_INDEX => ICON_TASK_ASSIGNER,
0 ignored issues
show
Bug introduced by
The constant PR_ICON_INDEX was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
541
			]);
542
			$this->setLastUser();
543
			$this->setOwnerForAssignor();
544
			mapi_savechanges($this->message);
545
546
			// Create outgoing task request message
547
			$outgoing = $this->createOutgoingMessage();
548
549
			// No need to copy PR_ICON_INDEX and  PR_SENT_* information in to outgoing message.
550
			$ignoreProps = [PR_ICON_INDEX, PR_SENT_REPRESENTING_NAME, PR_SENT_REPRESENTING_EMAIL_ADDRESS, PR_SENT_REPRESENTING_ADDRTYPE, PR_SENT_REPRESENTING_ENTRYID, PR_SENT_REPRESENTING_SEARCH_KEY];
0 ignored issues
show
Bug introduced by
The constant PR_SENT_REPRESENTING_SEARCH_KEY was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
Bug introduced by
The constant PR_SENT_REPRESENTING_ENTRYID was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
Bug introduced by
The constant PR_SENT_REPRESENTING_ADDRTYPE was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
Bug introduced by
The constant PR_SENT_REPRESENTING_NAME was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
Bug introduced by
The constant PR_SENT_REPRESENTING_EMAIL_ADDRESS was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
551
			mapi_copyto($this->message, [], $ignoreProps, $outgoing);
552
553
			// Make it a task request, and put it in sent items after it is sent
554
			mapi_setprops($outgoing, [
555
				PR_MESSAGE_CLASS => "IPM.TaskRequest", // class is task request
0 ignored issues
show
Bug introduced by
The constant PR_MESSAGE_CLASS was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
556
				$this->props['taskstate'] => tdsOWN, // for the recipient he is the task owner
557
				$this->props['taskmode'] => tdmtTaskReq, // for the recipient it's a request
558
				$this->props['updatecount'] => 1, // version 2 is in the attachment
559
				PR_SUBJECT_PREFIX => $prefix,
0 ignored issues
show
Bug introduced by
The constant PR_SUBJECT_PREFIX was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
560
				PR_SUBJECT => $prefix . $messageprops[PR_SUBJECT],
561
			]);
562
563
			$attach = mapi_message_createattach($outgoing);
564
			mapi_setprops($attach, [
565
				PR_ATTACH_METHOD => ATTACH_EMBEDDED_MSG,
0 ignored issues
show
Bug introduced by
The constant PR_ATTACH_METHOD was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
566
				PR_ATTACHMENT_HIDDEN => true,
0 ignored issues
show
Bug introduced by
The constant PR_ATTACHMENT_HIDDEN was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
567
				PR_DISPLAY_NAME => $messageprops[PR_SUBJECT], ]);
0 ignored issues
show
Bug introduced by
The constant PR_DISPLAY_NAME was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
568
569
			$sub = mapi_attach_openproperty($attach, PR_ATTACH_DATA_OBJ, IID_IMessage, 0, MAPI_MODIFY | MAPI_CREATE);
0 ignored issues
show
Bug introduced by
The constant PR_ATTACH_DATA_OBJ was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
570
571
			mapi_copyto($this->message, [], [], $sub);
572
			mapi_setprops($sub, [PR_MESSAGE_CLASS => 'IPM.Task']);
573
574
			mapi_savechanges($sub);
575
576
			mapi_savechanges($attach);
577
578
			mapi_savechanges($outgoing);
579
			mapi_message_submitmessage($outgoing);
580
581
			return true;
582
		}
583
584
		// Assignee functions (called by the assignee)
585
586
		/**
587
		 * Updates task version counter.
588
		 *
589
		 * Must be called before each update to increase counter.
590
		 */
591
		public function updateTaskRequest() {
592
			$messageprops = mapi_getprops($this->message, [$this->props['updatecount']]);
593
594
			if (isset($messageprops)) {
595
				++$messageprops[$this->props['updatecount']];
596
			}
597
			else {
598
				$messageprops[$this->props['updatecount']] = 1;
599
			}
600
601
			mapi_setprops($this->message, $messageprops);
602
		}
603
604
		/**
605
		 * Processes a task request.
606
		 *
607
		 * Message passed should be an IPM.TaskRequest message. The task request is then processed to create
608
		 * the task in the tasks folder if needed.
609
		 *
610
		 * @return bool
611
		 */
612
		public function processTaskRequest() {
613
			if (!$this->isTaskRequest()) {
614
				return false;
615
			}
616
			$messageProps = mapi_getprops($this->message, [PR_PROCESSED, $this->props["taskupdates"], PR_MESSAGE_TO_ME]);
0 ignored issues
show
Bug introduced by
The constant PR_PROCESSED was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
Bug introduced by
The constant PR_MESSAGE_TO_ME was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
617
			if (isset($messageProps[PR_PROCESSED]) && $messageProps[PR_PROCESSED]) {
618
				return true;
619
			}
620
621
			// if task is updated in task folder then we don't need to process
622
			// old request.
623
			if ($this->isTaskRequestUpdated()) {
624
				return true;
625
			}
626
627
			$isReceivedItem = $this->isReceivedItem($messageProps);
628
629
			$props = [];
630
			$props[PR_PROCESSED] = true;
631
			$props[$this->props["taskstate"]] = $isReceivedItem ? tdsOWN : tdsACC;
632
			$props[$this->props["ownership"]] = $isReceivedItem ? olOwnTask : olDelegatedTask;
633
634
			mapi_setprops($this->message, $props);
635
			mapi_savechanges($this->message);
636
637
			// Don't create associated task in task folder if "taskupdates" is not true.
638
			if (!$isReceivedItem && !$messageProps[$this->props["taskupdates"]]) {
639
				return true;
640
			}
641
			// create an associated task in task folder while
642
			// reading/loading task request on client side.
643
			$task = $this->getAssociatedTask(true);
644
645
			$taskProps = mapi_getprops($task, [$this->props['taskmultrecips']]);
646
			$taskProps[$this->props["taskstate"]] = $isReceivedItem ? tdsOWN : tdsACC;
647
			$taskProps[$this->props["taskhistory"]] = thAssigned;
648
			$taskProps[$this->props["taskmode"]] = tdmtNothing;
649
			$taskProps[$this->props["taskaccepted"]] = false;
650
			$taskProps[$this->props["taskfcreator"]] = false;
651
			$taskProps[$this->props["ownership"]] = $isReceivedItem ? olOwnTask : olDelegatedTask;
652
			$taskProps[$this->props["task_acceptance_state"]] = olTaskNotDelegated;
653
			$taskProps[PR_ICON_INDEX] = ICON_TASK_ASSIGNEE;
0 ignored issues
show
Bug introduced by
The constant PR_ICON_INDEX was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
654
655
			mapi_setprops($task, $taskProps);
656
			$this->setAssignorInRecipients($task);
657
658
			mapi_savechanges($task);
659
660
			return true;
661
		}
662
663
		/**
664
		 * Accepts a task request and sends the response.
665
		 *
666
		 * Message passed should be an IPM.Task (eg the task from getAssociatedTask())
667
		 *
668
		 * Copies the task to the user's task folder, sets it to accepted, and sends the acceptation
669
		 * message back to the organizer. The caller is responsible for removing the message.
670
		 *
671
		 * @return array|bool PR_ENTRYID, PR_STORE_ENTRYID and PR_PARENT_ENTRYID of the task
672
		 */
673
		public function doAccept() {
674
			$prefix = _("Task Accepted:") . " ";
675
			$messageProps = mapi_getprops($this->message, [PR_MESSAGE_CLASS, $this->props['taskstate']]);
0 ignored issues
show
Bug introduced by
The constant PR_MESSAGE_CLASS was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
676
677
			if (!isset($messageProps[$this->props['taskstate']]) || $messageProps[$this->props['taskstate']] != tdsOWN) {
678
				// Can only accept assignee task
679
				return false;
680
			}
681
682
			$this->setLastUser();
683
			$this->updateTaskRequest();
684
685
			$props = [
686
				$this->props['taskhistory'] => thAccepted,
687
				$this->props['task_assigned_time'] => time(),
688
				$this->props['taskaccepted'] => true,
689
				$this->props['task_acceptance_state'] => olTaskNotDelegated, ];
690
691
			// Message is TaskRequest then update the associated task as well.
692
			if ($this->isTaskRequest($messageProps[PR_MESSAGE_CLASS])) {
693
				$task = $this->getAssociatedTask(false);
694
				if ($task) {
695
					mapi_setprops($task, $props);
696
					mapi_savechanges($task);
697
				}
698
			}
699
700
			// Set as accepted
701
			mapi_setprops($this->message, $props);
702
703
			// As we copy the all properties from received message we need to remove following
704
			// properties from accept response.
705
			mapi_deleteprops($this->message, [PR_MESSAGE_RECIP_ME, PR_MESSAGE_TO_ME, PR_MESSAGE_CC_ME, PR_PROCESSED]);
0 ignored issues
show
Bug introduced by
The constant PR_MESSAGE_RECIP_ME was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
Bug introduced by
The constant PR_MESSAGE_CC_ME was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
Bug introduced by
The constant PR_PROCESSED was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
Bug introduced by
The constant PR_MESSAGE_TO_ME was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
706
707
			mapi_savechanges($this->message);
708
709
			$this->sendResponse(tdmtTaskAcc, $prefix);
710
711
			return $this->deleteReceivedTR();
712
		}
713
714
		/**
715
		 * Declines a task request and sends the response.
716
		 *
717
		 * Passed message must be a task request message, ie isTaskRequest() must return TRUE.
718
		 *
719
		 * Sends the decline message back to the organizer. The caller is responsible for removing the message.
720
		 *
721
		 * @return array|bool TRUE on success, FALSE on failure
722
		 */
723
		public function doDecline() {
724
			$prefix = _("Task Declined:") . " ";
725
			$messageProps = mapi_getprops($this->message, [$this->props['taskstate']]);
726
727
			if (!isset($messageProps[$this->props['taskstate']]) || $messageProps[$this->props['taskstate']] != tdsOWN) {
728
				return false; // Can only decline assignee task
729
			}
730
731
			$this->setLastUser();
732
			$this->updateTaskRequest();
733
734
			// Set as declined
735
			mapi_setprops($this->message, [
736
				$this->props['taskhistory'] => thDeclined,
737
				$this->props['task_acceptance_state'] => olTaskDelegationDeclined,
738
			]);
739
			mapi_deleteprops($this->message, [PR_MESSAGE_RECIP_ME, PR_MESSAGE_TO_ME, PR_MESSAGE_CC_ME, PR_PROCESSED]);
0 ignored issues
show
Bug introduced by
The constant PR_MESSAGE_CC_ME was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
Bug introduced by
The constant PR_MESSAGE_RECIP_ME was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
Bug introduced by
The constant PR_MESSAGE_TO_ME was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
Bug introduced by
The constant PR_PROCESSED was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
740
			mapi_savechanges($this->message);
741
742
			$this->sendResponse(tdmtTaskDec, $prefix);
743
744
			// Delete the associated task when task request is declined by the assignee.
745
			$task = $this->getAssociatedTask(false);
746
			if ($task) {
747
				$taskFolder = $this->getDefaultTasksFolder();
748
				$props = mapi_getprops($task, [PR_ENTRYID]);
749
				mapi_folder_deletemessages($taskFolder, [$props[PR_ENTRYID]]);
750
			}
751
752
			return $this->deleteReceivedTR();
753
		}
754
755
		/**
756
		 * Sends an update of the task if requested, and sends the Status-On-Completion report if complete and requested.
757
		 *
758
		 * If no updates were requested from the organizer, this function does nothing.
759
		 *
760
		 * @return bool TRUE if the update succeeded, FALSE otherwise
761
		 */
762
		public function doUpdate() {
763
			$messageProps = mapi_getprops($this->message, [$this->props['taskstate'], PR_SUBJECT]);
0 ignored issues
show
Bug introduced by
The constant PR_SUBJECT was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
764
765
			if (!isset($messageProps[$this->props['taskstate']]) || $messageProps[$this->props['taskstate']] != tdsOWN) {
766
				return false; // Can only update assignee task
767
			}
768
769
			$this->setLastUser();
770
			$this->updateTaskRequest();
771
772
			// Set as updated
773
			mapi_setprops($this->message, [$this->props['taskhistory'] => thUpdated]);
774
775
			mapi_savechanges($this->message);
776
777
			$props = mapi_getprops($this->message, [$this->props['taskupdates'], $this->props['tasksoc'], $this->props['recurring'], $this->props['complete']]);
778
			if (!$props[$this->props['complete']] && $props[$this->props['taskupdates']] && !(isset($props[$this->props['recurring']]) && $props[$this->props['recurring']])) {
779
				$this->sendResponse(tdmtTaskUpd, _("Task Updated:") . " ");
780
			}
781
			elseif ($props[$this->props['complete']]) {
782
				$this->sendResponse(tdmtTaskUpd, _("Task Completed:") . " ");
783
			}
784
785
			return true;
786
		}
787
788
		/**
789
		 * Gets the store associated with the task.
790
		 *
791
		 * Normally this will just open the store that the processed message is in. However, if the message is opened
792
		 * by a delegate, this function opens the store that the message was delegated from.
793
		 */
794
		public function getTaskFolderStore() {
795
			$ownerentryid = false;
796
797
			$rcvdprops = mapi_getprops($this->message, [PR_RCVD_REPRESENTING_ENTRYID]);
0 ignored issues
show
Bug introduced by
The constant PR_RCVD_REPRESENTING_ENTRYID was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
798
			if (isset($rcvdprops[PR_RCVD_REPRESENTING_ENTRYID])) {
799
				$ownerentryid = $rcvdprops[PR_RCVD_REPRESENTING_ENTRYID];
800
			}
801
802
			if (!$ownerentryid) {
803
				$store = $this->store;
804
			}
805
			else {
806
				$ab = mapi_openaddressbook($this->session);
807
				if (!$ab) {
808
					return false;
809
				}
810
811
				$mailuser = mapi_ab_openentry($ab, $ownerentryid);
812
				if (!$mailuser) {
813
					return false;
814
				}
815
816
				$mailuserprops = mapi_getprops($mailuser, [PR_EMAIL_ADDRESS]);
0 ignored issues
show
Bug introduced by
The constant PR_EMAIL_ADDRESS was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
817
				if (!isset($mailuserprops[PR_EMAIL_ADDRESS])) {
818
					return false;
819
				}
820
821
				$storeid = mapi_msgstore_createentryid($this->store, $mailuserprops[PR_EMAIL_ADDRESS]);
822
823
				$store = mapi_openmsgstore($this->session, $storeid);
824
			}
825
826
			return $store;
827
		}
828
829
		/**
830
		 * Opens the default task folder for the current user, or the specified user if passed.
831
		 */
832
		public function getDefaultTasksFolder() {
833
			$store = $this->getTaskFolderStore();
834
835
			$inbox = mapi_msgstore_getreceivefolder($store);
836
			$inboxprops = mapi_getprops($inbox, [PR_IPM_TASK_ENTRYID]);
0 ignored issues
show
Bug introduced by
The constant PR_IPM_TASK_ENTRYID was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
837
			if (!isset($inboxprops[PR_IPM_TASK_ENTRYID])) {
838
				return false;
839
			}
840
841
			return mapi_msgstore_openentry($store, $inboxprops[PR_IPM_TASK_ENTRYID]);
842
		}
843
844
		/**
845
		 * Prepares the sent representing properties from given MAPI store.
846
		 *
847
		 * @param mixed $store MAPI store object
848
		 *
849
		 * @return array|bool if store is not mail box owner entryid then
850
		 *                    return false else prepare the sent representing props and return it
851
		 */
852
		public function getSentReprProps($store) {
853
			$storeprops = mapi_getprops($store, [PR_MAILBOX_OWNER_ENTRYID]);
0 ignored issues
show
Bug introduced by
The constant PR_MAILBOX_OWNER_ENTRYID was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
854
			if (!isset($storeprops[PR_MAILBOX_OWNER_ENTRYID])) {
855
				return false;
856
			}
857
858
			$ab = mapi_openaddressbook($this->session);
859
			$mailuser = mapi_ab_openentry($ab, $storeprops[PR_MAILBOX_OWNER_ENTRYID]);
860
			$mailuserprops = mapi_getprops($mailuser, [PR_ADDRTYPE, PR_EMAIL_ADDRESS, PR_DISPLAY_NAME, PR_SEARCH_KEY, PR_ENTRYID]);
0 ignored issues
show
Bug introduced by
The constant PR_DISPLAY_NAME was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
Bug introduced by
The constant PR_EMAIL_ADDRESS was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
Bug introduced by
The constant PR_SEARCH_KEY was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
Bug introduced by
The constant PR_ADDRTYPE was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
861
862
			$props = [];
863
			$props[PR_SENT_REPRESENTING_ADDRTYPE] = $mailuserprops[PR_ADDRTYPE];
0 ignored issues
show
Bug introduced by
The constant PR_SENT_REPRESENTING_ADDRTYPE was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
864
			$props[PR_SENT_REPRESENTING_EMAIL_ADDRESS] = $mailuserprops[PR_EMAIL_ADDRESS];
0 ignored issues
show
Bug introduced by
The constant PR_SENT_REPRESENTING_EMAIL_ADDRESS was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
865
			$props[PR_SENT_REPRESENTING_NAME] = $mailuserprops[PR_DISPLAY_NAME];
0 ignored issues
show
Bug introduced by
The constant PR_SENT_REPRESENTING_NAME was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
866
			$props[PR_SENT_REPRESENTING_SEARCH_KEY] = $mailuserprops[PR_SEARCH_KEY];
0 ignored issues
show
Bug introduced by
The constant PR_SENT_REPRESENTING_SEARCH_KEY was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
867
			$props[PR_SENT_REPRESENTING_ENTRYID] = $mailuserprops[PR_ENTRYID];
0 ignored issues
show
Bug introduced by
The constant PR_SENT_REPRESENTING_ENTRYID was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
868
869
			return $props;
870
		}
871
872
		/**
873
		 * Creates an outgoing message based on the passed message - will set delegate information
874
		 * and sent mail folder.
875
		 */
876
		public function createOutgoingMessage() {
877
			// Open our default store for this user (that's the only store we can submit in)
878
			$store = $this->getDefaultStore();
879
			$storeprops = mapi_getprops($store, [PR_IPM_OUTBOX_ENTRYID, PR_IPM_SENTMAIL_ENTRYID]);
0 ignored issues
show
Bug introduced by
The constant PR_IPM_SENTMAIL_ENTRYID was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
Bug introduced by
The constant PR_IPM_OUTBOX_ENTRYID was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
880
881
			$outbox = mapi_msgstore_openentry($store, $storeprops[PR_IPM_OUTBOX_ENTRYID]);
882
			if (!$outbox) {
883
				return false;
884
			}
885
886
			$outgoing = mapi_folder_createmessage($outbox);
887
			if (!$outgoing) {
888
				return false;
889
			}
890
891
			// Set SENT_REPRESENTING in case we're sending as a delegate
892
			$ownerstore = $this->getTaskFolderStore();
893
			$sentreprprops = $this->getSentReprProps($ownerstore);
894
			mapi_setprops($outgoing, $sentreprprops);
895
896
			mapi_setprops($outgoing, [PR_SENTMAIL_ENTRYID => $storeprops[PR_IPM_SENTMAIL_ENTRYID]]);
0 ignored issues
show
Bug introduced by
The constant PR_SENTMAIL_ENTRYID was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
897
898
			return $outgoing;
899
		}
900
901
		/**
902
		 * Sends a response message (from assignee back to organizer).
903
		 *
904
		 * @param int $type Type of response (tdmtTaskAcc, tdmtTaskDec, tdmtTaskUpd)
905
		 * @param mixed $prefix
906
		 *
907
		 * @return bool TRUE on success
908
		 */
909
		public function sendResponse($type, $prefix) {
910
			// Create a message in our outbox
911
			$outgoing = $this->createOutgoingMessage();
912
			$messageprops = mapi_getprops($this->message, [PR_CONVERSATION_TOPIC, PR_MESSAGE_CLASS, $this->props['complete']]);
0 ignored issues
show
Bug introduced by
The constant PR_MESSAGE_CLASS was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
Bug introduced by
The constant PR_CONVERSATION_TOPIC was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
913
914
			$attach = mapi_message_createattach($outgoing);
915
			mapi_setprops($attach, [PR_ATTACH_METHOD => ATTACH_EMBEDDED_MSG, PR_DISPLAY_NAME => $messageprops[PR_CONVERSATION_TOPIC], PR_ATTACHMENT_HIDDEN => true]);
0 ignored issues
show
Bug introduced by
The constant PR_ATTACHMENT_HIDDEN was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
Bug introduced by
The constant PR_ATTACH_METHOD was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
Bug introduced by
The constant PR_DISPLAY_NAME was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
916
			$sub = mapi_attach_openproperty($attach, PR_ATTACH_DATA_OBJ, IID_IMessage, 0, MAPI_CREATE | MAPI_MODIFY);
0 ignored issues
show
Bug introduced by
The constant PR_ATTACH_DATA_OBJ was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
917
918
			$message = !$this->isTaskRequest() ? $this->message : $this->getAssociatedTask(false);
919
920
			$ignoreProps = [PR_ICON_INDEX, $this->props["categories"], PR_SENT_REPRESENTING_NAME, PR_SENT_REPRESENTING_EMAIL_ADDRESS, PR_SENT_REPRESENTING_ADDRTYPE, PR_SENT_REPRESENTING_ENTRYID, PR_SENT_REPRESENTING_SEARCH_KEY];
0 ignored issues
show
Bug introduced by
The constant PR_SENT_REPRESENTING_ENTRYID was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
Bug introduced by
The constant PR_SENT_REPRESENTING_SEARCH_KEY was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
Bug introduced by
The constant PR_SENT_REPRESENTING_EMAIL_ADDRESS was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
Bug introduced by
The constant PR_ICON_INDEX was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
Bug introduced by
The constant PR_SENT_REPRESENTING_ADDRTYPE was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
Bug introduced by
The constant PR_SENT_REPRESENTING_NAME was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
921
922
			mapi_copyto($message, [], $ignoreProps, $outgoing);
923
			mapi_copyto($message, [], [], $sub);
924
925
			if (!$this->setRecipientsForResponse($outgoing, $type)) {
926
				return false;
927
			}
928
929
			$props = [];
930
931
			switch ($type) {
932
				case tdmtTaskAcc:
933
					$props[PR_MESSAGE_CLASS] = "IPM.TaskRequest.Accept";
934
					mapi_setprops($sub, [PR_ICON_INDEX => ICON_TASK_ASSIGNER]);
935
					break;
936
937
				case tdmtTaskDec:
938
					$props[PR_MESSAGE_CLASS] = "IPM.TaskRequest.Decline";
939
					mapi_setprops($sub, [PR_ICON_INDEX => ICON_TASK_DECLINE]);
940
					break;
941
942
				case tdmtTaskUpd:
943
					mapi_setprops($sub, [PR_ICON_INDEX => ICON_TASK_ASSIGNER]);
944
					if ($messageprops[$this->props['complete']]) {
945
						$props[PR_MESSAGE_CLASS] = "IPM.TaskRequest.Complete";
946
					}
947
					else {
948
						$props[PR_MESSAGE_CLASS] = "IPM.TaskRequest.Update";
949
					}
950
951
					break;
952
			}
953
954
			mapi_savechanges($sub);
955
			mapi_savechanges($attach);
956
957
			$props[PR_SUBJECT] = $prefix . $messageprops[PR_CONVERSATION_TOPIC];
0 ignored issues
show
Bug introduced by
The constant PR_SUBJECT was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
958
			$props[$this->props['taskmode']] = $type;
959
			$props[$this->props['task_assigned_time']] = time();
960
961
			mapi_setprops($outgoing, $props);
962
963
			// taskCommentsInfo contains some comments which added by assignee while
964
			// edit response before sending task response.
965
			if ($this->taskCommentsInfo) {
966
				$comments = $this->getTaskCommentsInfo();
967
				$stream = mapi_openproperty($outgoing, PR_BODY, IID_IStream, STGM_TRANSACTED, MAPI_CREATE | MAPI_MODIFY);
0 ignored issues
show
Bug introduced by
The constant PR_BODY was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
968
				mapi_stream_setsize($stream, strlen($comments));
0 ignored issues
show
Bug introduced by
$comments of type true is incompatible with the type string expected by parameter $string of strlen(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

968
				mapi_stream_setsize($stream, strlen(/** @scrutinizer ignore-type */ $comments));
Loading history...
969
				mapi_stream_write($stream, $comments);
970
				mapi_stream_commit($stream);
971
			}
972
973
			mapi_savechanges($outgoing);
974
			mapi_message_submitmessage($outgoing);
975
976
			return true;
977
		}
978
979
		public function getDefaultStore() {
980
			$table = mapi_getmsgstorestable($this->session);
981
			$rows = mapi_table_queryallrows($table, [PR_DEFAULT_STORE, PR_ENTRYID]);
0 ignored issues
show
Bug introduced by
The constant PR_DEFAULT_STORE was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
982
983
			foreach ($rows as $row) {
984
				if ($row[PR_DEFAULT_STORE]) {
985
					return mapi_openmsgstore($this->session, $row[PR_ENTRYID]);
986
				}
987
			}
988
989
			return false;
990
		}
991
992
		/**
993
		 * Creates a new TaskGlobalObjId.
994
		 *
995
		 * Just 16 bytes of random data
996
		 */
997
		public function createTGOID() {
998
			$goid = "";
999
			for ($i = 0; $i < 16; ++$i) {
1000
				$goid .= chr(rand(0, 255));
1001
			}
1002
1003
			return $goid;
1004
		}
1005
1006
		/**
1007
		 * Gets the embedded task of task request. Further used to
1008
		 * create/update associated task of assigner/assignee.
1009
		 *
1010
		 * @return resource|bool embedded task if found else false
1011
		 */
1012
		public function getEmbeddedTask() {
1013
			$task = false;
1014
			$goid = mapi_getprops($this->message, [$this->props["task_goid"]]);
1015
			$attachmentTable = mapi_message_getattachmenttable($this->message);
1016
			$restriction = [RES_PROPERTY,
1017
				[RELOP => RELOP_EQ,
1018
					ULPROPTAG => PR_ATTACH_METHOD,
0 ignored issues
show
Bug introduced by
The constant PR_ATTACH_METHOD was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
1019
					VALUE => ATTACH_EMBEDDED_MSG, ],
1020
			];
1021
			$rows = mapi_table_queryallrows($attachmentTable, [PR_ATTACH_NUM], $restriction);
0 ignored issues
show
Bug introduced by
The constant PR_ATTACH_NUM was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
1022
1023
			if (empty($rows)) {
1024
				return $task;
1025
			}
1026
1027
			foreach ($rows as $row) {
1028
				try {
1029
					$attach = mapi_message_openattach($this->message, $row[PR_ATTACH_NUM]);
1030
					$task = mapi_attach_openobj($attach);
1031
				}
1032
				catch (MAPIException $e) {
1033
					continue;
1034
				}
1035
1036
				$taskGoid = mapi_getprops($task, [$this->props["task_goid"]]);
1037
				if ($goid[$this->props["task_goid"]] === $taskGoid[$this->props["task_goid"]]) {
1038
					mapi_setprops($attach, [PR_ATTACHMENT_HIDDEN => true]);
0 ignored issues
show
Bug introduced by
The constant PR_ATTACHMENT_HIDDEN was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
1039
					mapi_savechanges($attach);
1040
					mapi_savechanges($this->message);
1041
					break;
1042
				}
1043
			}
1044
1045
			return $task;
1046
		}
1047
1048
		/**
1049
		 * Sets the user name who has last used this task. Update the
1050
		 * tasklastdelegate and task_assigned_time.
1051
		 */
1052
		public function setLastUser() {
1053
			$delegatestore = $this->getDefaultStore();
1054
			$taskstore = $this->getTaskFolderStore();
1055
1056
			$delegateprops = mapi_getprops($delegatestore, [PR_MAILBOX_OWNER_NAME]);
0 ignored issues
show
Bug introduced by
The constant PR_MAILBOX_OWNER_NAME was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
1057
			$taskprops = mapi_getprops($taskstore, [PR_MAILBOX_OWNER_NAME]);
1058
1059
			// The owner of the task
1060
			$username = $delegateprops[PR_MAILBOX_OWNER_NAME];
1061
			// This is me (the one calling the script)
1062
			$delegate = $taskprops[PR_MAILBOX_OWNER_NAME];
1063
1064
			if ($this->isTaskRequest()) {
1065
				$task = $this->getAssociatedTask(false);
1066
				mapi_setprops($task, [
1067
					$this->props["tasklastuser"] => $username,
1068
					$this->props["tasklastdelegate"] => $delegate,
1069
					$this->props['task_assigned_time'] => time(),
1070
				]);
1071
				mapi_savechanges($task);
1072
			}
1073
			mapi_setprops($this->message, [
1074
				$this->props["tasklastuser"] => $username,
1075
				$this->props["tasklastdelegate"] => $delegate,
1076
				$this->props['task_assigned_time'] => time(),
1077
			]);
1078
		}
1079
1080
		/**
1081
		 * Sets assignee as owner in the assignor's copy of task.
1082
		 * Assignee becomes the owner when a user/assignor assigns any task to someone.
1083
		 * There can be more than one assignee.
1084
		 */
1085
		public function setOwnerForAssignor() {
1086
			$recipTable = mapi_message_getrecipienttable($this->message);
1087
			$recips = mapi_table_queryallrows($recipTable, [PR_DISPLAY_NAME]);
0 ignored issues
show
Bug introduced by
The constant PR_DISPLAY_NAME was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
1088
1089
			if (!empty($recips)) {
1090
				$owner = [];
1091
				foreach ($recips as $value) {
1092
					$owner[] = $value[PR_DISPLAY_NAME];
1093
				}
1094
1095
				$props = [$this->props['owner'] => implode("; ", $owner)];
1096
				mapi_setprops($this->message, $props);
1097
			}
1098
		}
1099
1100
		/**
1101
		 * Sets assignor as recipients in assignee's copy of task.
1102
		 *
1103
		 * If assignor has requested task updates then the assignor is added as recipient type MAPI_CC.
1104
		 *
1105
		 * Also if assignor has request SOC then the assignor is also add as recipient type MAPI_BCC
1106
		 *
1107
		 * @param mixed $task assignee's copy of task
1108
		 */
1109
		public function setAssignorInRecipients($task) {
1110
			$recipTable = mapi_message_getrecipienttable($task);
1111
1112
			// Delete all MAPI_TO recipients
1113
			$recips = mapi_table_queryallrows($recipTable, [PR_ROWID], [
0 ignored issues
show
Bug introduced by
The constant PR_ROWID was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
1114
				RES_PROPERTY,
1115
				[
1116
					RELOP => RELOP_EQ,
1117
					ULPROPTAG => PR_RECIPIENT_TYPE,
0 ignored issues
show
Bug introduced by
The constant PR_RECIPIENT_TYPE was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
1118
					VALUE => MAPI_TO,
1119
				],
1120
			]);
1121
			foreach ($recips as $recip) {
1122
				mapi_message_modifyrecipients($task, MODRECIP_REMOVE, [$recip]);
1123
			}
1124
1125
			$recips = [];
1126
			$taskReqProps = mapi_getprops($this->message, [
1127
				PR_SENT_REPRESENTING_NAME,
0 ignored issues
show
Bug introduced by
The constant PR_SENT_REPRESENTING_NAME was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
1128
				PR_SENT_REPRESENTING_EMAIL_ADDRESS,
0 ignored issues
show
Bug introduced by
The constant PR_SENT_REPRESENTING_EMAIL_ADDRESS was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
1129
				PR_SENT_REPRESENTING_ENTRYID,
0 ignored issues
show
Bug introduced by
The constant PR_SENT_REPRESENTING_ENTRYID was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
1130
				PR_SENT_REPRESENTING_ADDRTYPE,
0 ignored issues
show
Bug introduced by
The constant PR_SENT_REPRESENTING_ADDRTYPE was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
1131
				PR_SENT_REPRESENTING_SEARCH_KEY,
0 ignored issues
show
Bug introduced by
The constant PR_SENT_REPRESENTING_SEARCH_KEY was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
1132
			]);
1133
			$associatedTaskProps = mapi_getprops($task, [
1134
				$this->props['taskupdates'],
1135
				$this->props['tasksoc'],
1136
				$this->props['taskmultrecips'],
1137
			]);
1138
1139
			// Build assignor info
1140
			$assignor = [
1141
				PR_ENTRYID => $taskReqProps[PR_SENT_REPRESENTING_ENTRYID],
1142
				PR_DISPLAY_NAME => $taskReqProps[PR_SENT_REPRESENTING_NAME],
0 ignored issues
show
Bug introduced by
The constant PR_DISPLAY_NAME was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
1143
				PR_EMAIL_ADDRESS => $taskReqProps[PR_SENT_REPRESENTING_EMAIL_ADDRESS],
0 ignored issues
show
Bug introduced by
The constant PR_EMAIL_ADDRESS was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
1144
				PR_RECIPIENT_DISPLAY_NAME => $taskReqProps[PR_SENT_REPRESENTING_NAME],
0 ignored issues
show
Bug introduced by
The constant PR_RECIPIENT_DISPLAY_NAME was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
1145
				PR_ADDRTYPE => empty($taskReqProps[PR_SENT_REPRESENTING_ADDRTYPE]) ? 'SMTP' : $taskReqProps[PR_SENT_REPRESENTING_ADDRTYPE],
0 ignored issues
show
Bug introduced by
The constant PR_ADDRTYPE was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
1146
				PR_RECIPIENT_FLAGS => recipSendable,
0 ignored issues
show
Bug introduced by
The constant PR_RECIPIENT_FLAGS was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
1147
				PR_SEARCH_KEY => $taskReqProps[PR_SENT_REPRESENTING_SEARCH_KEY],
0 ignored issues
show
Bug introduced by
The constant PR_SEARCH_KEY was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
1148
			];
1149
1150
			// Assignor has requested task updates, so set him/her as MAPI_CC in recipienttable.
1151
			if ((isset($associatedTaskProps[$this->props['taskupdates']]) && $associatedTaskProps[$this->props['taskupdates']]) &&
1152
				!(isset($associatedTaskProps[$this->props['taskmultrecips']]) && $associatedTaskProps[$this->props['taskmultrecips']] == tmrReceived)) {
1153
				$assignor[PR_RECIPIENT_TYPE] = MAPI_CC;
1154
				$recips[] = $assignor;
1155
			}
1156
1157
			// Assignor wants to receive an email report when task is mark as 'Complete', so in recipients as MAPI_BCC
1158
			if ($associatedTaskProps[$this->props['tasksoc']]) {
1159
				$assignor[PR_RECIPIENT_TYPE] = MAPI_BCC;
1160
				$recips[] = $assignor;
1161
			}
1162
1163
			if (!empty($recips)) {
1164
				mapi_message_modifyrecipients($task, MODRECIP_ADD, $recips);
1165
			}
1166
		}
1167
1168
		/**
1169
		 * Deletes incoming task request from Inbox.
1170
		 *
1171
		 * @returns array|bool PR_ENTRYID, PR_STORE_ENTRYID and PR_PARENT_ENTRYID of the deleted task request
1172
		 */
1173
		public function deleteReceivedTR() {
1174
			$store = $this->getTaskFolderStore();
1175
			$storeType = mapi_getprops($store, [PR_MDB_PROVIDER]);
0 ignored issues
show
Bug introduced by
The constant PR_MDB_PROVIDER was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
1176
			if ($storeType[PR_MDB_PROVIDER] === ZARAFA_STORE_PUBLIC_GUID) {
1177
				$store = $this->getDefaultStore();
1178
			}
1179
			$inbox = mapi_msgstore_getreceivefolder($store);
1180
1181
			$storeProps = mapi_getprops($store, [PR_IPM_WASTEBASKET_ENTRYID]);
0 ignored issues
show
Bug introduced by
The constant PR_IPM_WASTEBASKET_ENTRYID was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
1182
			$props = mapi_getprops($this->message, [$this->props['task_goid']]);
1183
			$goid = $props[$this->props['task_goid']];
1184
1185
			// Find the task by looking for the task_goid
1186
			$restriction = [
1187
				RES_PROPERTY,
1188
				[
1189
					RELOP => RELOP_EQ,
1190
					ULPROPTAG => $this->props['task_goid'],
1191
					VALUE => $goid,
1192
				],
1193
			];
1194
1195
			$contents = mapi_folder_getcontentstable($inbox);
1196
1197
			$rows = mapi_table_queryallrows($contents, [PR_ENTRYID, PR_PARENT_ENTRYID, PR_STORE_ENTRYID], $restriction);
0 ignored issues
show
Bug introduced by
The constant PR_PARENT_ENTRYID was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
Bug introduced by
The constant PR_STORE_ENTRYID was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
1198
1199
			if (!empty($rows)) {
1200
				// If there are multiple, just use the first
1201
				$entryid = $rows[0][PR_ENTRYID];
1202
				$wastebasket = mapi_msgstore_openentry($store, $storeProps[PR_IPM_WASTEBASKET_ENTRYID]);
1203
				mapi_folder_copymessages($inbox, [$entryid], $wastebasket, MESSAGE_MOVE);
1204
1205
				return [PR_ENTRYID => $entryid, PR_PARENT_ENTRYID => $rows[0][PR_PARENT_ENTRYID], PR_STORE_ENTRYID => $rows[0][PR_STORE_ENTRYID]];
1206
			}
1207
1208
			return false;
1209
		}
1210
1211
		/**
1212
		 * Sets recipients for the outgoing message according to type of the response.
1213
		 *
1214
		 * If it is a task update, then only recipient type MAPI_CC are taken from the task message.
1215
		 *
1216
		 * If it is accept/decline response, then PR_SENT_REPRESENTATING_XXXX are taken as recipient.
1217
		 *
1218
		 * @param mixed $outgoing outgoing mapi message
1219
		 * @param int $responseType response type (tdmtTaskAcc, tdmtTaskDec, tdmtTaskUpd)
1220
		 */
1221
		public function setRecipientsForResponse($outgoing, $responseType) {
1222
			// Clear recipients from outgoing msg
1223
			$this->deleteAllRecipients($outgoing);
1224
1225
			// If it is a task update then get MAPI_CC recipients which are assignors who has asked for task update.
1226
			if ($responseType == tdmtTaskUpd) {
1227
				$props = mapi_getprops($this->message, [$this->props['complete']]);
1228
				$isComplete = $props[$this->props['complete']];
1229
1230
				$recipTable = mapi_message_getrecipienttable($this->message);
1231
				$recips = mapi_table_queryallrows($recipTable, $this->recipProps, [
1232
					RES_PROPERTY,
1233
					[
1234
						RELOP => RELOP_EQ,
1235
						ULPROPTAG => PR_RECIPIENT_TYPE,
0 ignored issues
show
Bug introduced by
The constant PR_RECIPIENT_TYPE was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
1236
						VALUE => ($isComplete ? MAPI_BCC : MAPI_CC),
1237
					],
1238
				]);
1239
1240
				// No recipients found, return error
1241
				if (empty($recips)) {
1242
					return false;
1243
				}
1244
1245
				foreach ($recips as $recip) {
1246
					$recip[PR_RECIPIENT_TYPE] = MAPI_TO;	// Change recipient type to MAPI_TO
1247
					mapi_message_modifyrecipients($outgoing, MODRECIP_ADD, [$recip]);
1248
				}
1249
1250
				return true;
1251
			}
1252
1253
			$orgprops = mapi_getprops($this->message, [
1254
				PR_SENT_REPRESENTING_NAME,
0 ignored issues
show
Bug introduced by
The constant PR_SENT_REPRESENTING_NAME was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
1255
				PR_SENT_REPRESENTING_EMAIL_ADDRESS,
0 ignored issues
show
Bug introduced by
The constant PR_SENT_REPRESENTING_EMAIL_ADDRESS was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
1256
				PR_SENT_REPRESENTING_ADDRTYPE,
0 ignored issues
show
Bug introduced by
The constant PR_SENT_REPRESENTING_ADDRTYPE was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
1257
				PR_SENT_REPRESENTING_ENTRYID,
0 ignored issues
show
Bug introduced by
The constant PR_SENT_REPRESENTING_ENTRYID was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
1258
				PR_SUBJECT,
0 ignored issues
show
Bug introduced by
The constant PR_SUBJECT was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
1259
			]);
1260
1261
			$recip = [
1262
				PR_DISPLAY_NAME => $orgprops[PR_SENT_REPRESENTING_NAME],
0 ignored issues
show
Bug introduced by
The constant PR_DISPLAY_NAME was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
1263
				PR_EMAIL_ADDRESS => $orgprops[PR_SENT_REPRESENTING_EMAIL_ADDRESS],
0 ignored issues
show
Bug introduced by
The constant PR_EMAIL_ADDRESS was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
1264
				PR_ADDRTYPE => $orgprops[PR_SENT_REPRESENTING_ADDRTYPE],
0 ignored issues
show
Bug introduced by
The constant PR_ADDRTYPE was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
1265
				PR_ENTRYID => $orgprops[PR_SENT_REPRESENTING_ENTRYID],
1266
				PR_RECIPIENT_TYPE => MAPI_TO, ];
1267
1268
			mapi_message_modifyrecipients($outgoing, MODRECIP_ADD, [$recip]);
1269
1270
			return true;
1271
		}
1272
1273
		/**
1274
		 * Deletes all recipients from given message object.
1275
		 *
1276
		 * @param mixed $message MAPI message from which recipients are to be removed
1277
		 */
1278
		public function deleteAllRecipients($message) {
1279
			$recipTable = mapi_message_getrecipienttable($message);
1280
			$recipRows = mapi_table_queryallrows($recipTable, [PR_ROWID]);
0 ignored issues
show
Bug introduced by
The constant PR_ROWID was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
1281
1282
			foreach ($recipRows as $recipient) {
1283
				mapi_message_modifyrecipients($message, MODRECIP_REMOVE, [$recipient]);
1284
			}
1285
		}
1286
1287
		/**
1288
		 * Marks the record to complete and send complete update
1289
		 * notification to assigner.
1290
		 *
1291
		 * @return bool TRUE if the update succeeded, FALSE otherwise
1292
		 */
1293
		public function sendCompleteUpdate() {
1294
			$messageprops = mapi_getprops($this->message, [$this->props['taskstate']]);
1295
1296
			if (!isset($messageprops[$this->props['taskstate']]) || $messageprops[$this->props['taskstate']] != tdsOWN) {
1297
				return false; // Can only decline assignee task
1298
			}
1299
1300
			mapi_setprops($this->message, [
1301
				$this->props['complete'] => true,
1302
				$this->props['datecompleted'] => time(),
1303
				$this->props['status'] => 2,
1304
				$this->props['percent_complete'] => 1,
1305
			]);
1306
1307
			return $this->doUpdate();
1308
		}
1309
1310
		/**
1311
		 * Returns extra info about task request comments along with message body
1312
		 * which will be included in body while sending task request/response.
1313
		 *
1314
		 * @return string|bool info about task request comments along with message body
1315
		 */
1316
		public function getTaskCommentsInfo() {
1317
			return $this->taskCommentsInfo;
1318
		}
1319
1320
		/**
1321
		 * Sets an extra info about task request comments along with message body
1322
		 * which will be included in body while sending task request/response.
1323
		 *
1324
		 * @param string $taskCommentsInfo info about task request comments along with message body
1325
		 */
1326
		public function setTaskCommentsInfo($taskCommentsInfo) {
1327
			$this->taskCommentsInfo = $taskCommentsInfo;
1328
		}
1329
1330
		public function getSubProperties() {
1331
			$subProperties = [];
1332
			$subProperties["subject"] = PR_SUBJECT;
0 ignored issues
show
Bug introduced by
The constant PR_SUBJECT was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
1333
			$subProperties["convtopic"] = PR_CONVERSATION_TOPIC;
0 ignored issues
show
Bug introduced by
The constant PR_CONVERSATION_TOPIC was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
1334
			$subProperties["complete"] = "PT_BOOLEAN:PSETID_Task:" . PidLidTaskComplete;
0 ignored issues
show
Bug introduced by
The constant PidLidTaskComplete was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
1335
			$subProperties["datecompleted"] = "PT_SYSTIME:PSETID_Task:" . PidLidTaskDateCompleted;
0 ignored issues
show
Bug introduced by
The constant PidLidTaskDateCompleted was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
1336
			$subProperties["recurring"] = "PT_BOOLEAN:PSETID_Task:0x8126";
1337
			$subProperties["startdate"] = "PT_SYSTIME:PSETID_Task:" . PidLidTaskStartDate;
0 ignored issues
show
Bug introduced by
The constant PidLidTaskStartDate was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
1338
			$subProperties["duedate"] = "PT_SYSTIME:PSETID_Task:" . PidLidTaskDueDate;
0 ignored issues
show
Bug introduced by
The constant PidLidTaskDueDate was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
1339
			$subProperties["status"] = "PT_LONG:PSETID_Task:" . PidLidTaskStatus;
0 ignored issues
show
Bug introduced by
The constant PidLidTaskStatus was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
1340
			$subProperties["percent_complete"] = "PT_DOUBLE:PSETID_Task:" . PidLidPercentComplete;
0 ignored issues
show
Bug introduced by
The constant PidLidPercentComplete was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
1341
			$subProperties["totalwork"] = "PT_LONG:PSETID_Task:0x8111";
1342
			$subProperties["actualwork"] = "PT_LONG:PSETID_Task:0x8110";
1343
			$subProperties["categories"] = "PT_MV_STRING8:PS_PUBLIC_STRINGS:Keywords";
1344
			$subProperties["companies"] = "PT_MV_STRING8:PSETID_Common:0x8539";
1345
			$subProperties["mileage"] = "PT_STRING8:PSETID_Common:0x8534";
1346
			$subProperties["billinginformation"] = "PT_STRING8:PSETID_Common:0x8535";
1347
1348
			return getPropIdsFromStrings($this->store, $subProperties);
1349
		}
1350
	}
1351