Test Failed
Push — master ( 647c72...cd42b5 )
by
unknown
10:25
created

server/includes/modules/class.taskitemmodule.php (1 issue)

Severity
1
<?php
2
	include_once(__DIR__ . '/../mapi/class.taskrecurrence.php');
3
	include_once(__DIR__ . '/../mapi/class.taskrequest.php');
4
5
	/**
6
	 * Task ItemModule
7
	 * Module which openes, creates, saves and deletes an item. It
8
	 * extends the Module class.
9
	 */
10
	class TaskItemModule extends ItemModule
11
	{
12
		/**
13
		 * Constructor
14
		 * @param int $id unique id.
15
		 * @param array $data list of all actions.
16
		 */
17
		function __construct($id, $data)
18
		{
19
			parent::__construct($id, $data);
20
21
			$this->properties = $GLOBALS["properties"]->getTaskProperties();
22
23
			$this->plaintext = true;
24
		}
25
26
		function open($store, $entryid, $action)
27
		{
28
			$data = array();
29
30
			$message = $GLOBALS['operations']->openMessage($store, $entryid);
31
32
			if(empty($message)) {
33
				return;
34
			}
35
36
			// Open embedded message if requested
37
			$attachNum = !empty($action['attach_num']) ? $action['attach_num'] : false;
38
			if($attachNum) {
39
				// get message props of sub message
40
				$parentMessage = $message;
41
				$message = $GLOBALS['operations']->openMessage($store, $entryid, $attachNum);
42
43
				if(empty($message)) {
44
					return;
45
				}
46
47
				$data['item'] = $GLOBALS['operations']->getEmbeddedMessageProps($store, $message, $this->properties, $parentMessage, $attachNum);
48
			} else {
49
				$data['item'] = $GLOBALS['operations']->getMessageProps($store, $message, $this->properties, $this->plaintext);
50
51
				$tr = new TaskRequest($store, $message, $GLOBALS['mapisession']->getSession());
52
				if ($tr->isTaskRequest() || $tr->isTaskRequestResponse()) {
53
					$tr->isTaskRequest() ? $tr->processTaskRequest() : $tr->processTaskResponse();
54
					$task = $tr->getAssociatedTask(false);
55
					$action["message_action"]["open_task"] = true;
56
					$data = $this->getMessageProps($store, $entryid, $action, $task);
57
					$data['item']['props']['task_not_found'] = ($task === false);
58
				}
59
			}
60
61
			$this->addActionData('item', $data);
62
			$GLOBALS['bus']->addData($this->getResponseData());
63
		}
64
65
		/**
66
		 * Function which used to open and get the all properties of the message. if message_action
67
		 * "open_task" is true then it will open the associated task of task request and return its data item
68
		 * else return the task request data item.
69
		 *
70
		 * @param object $store MAPI Message Store Object
71
		 * @param string $entryid entryid of the message
72
		 * @param object $task associated task of task request
73
		 *
74
		 * @return array $data item properties of given message.
75
		 */
76
		function getMessageProps($store, $entryid, $action, $task)
77
		{
78
			if(isset($action["message_action"]["open_task"]) && $action["message_action"]["open_task"] && $task !== false) {
79
				$taskProps = mapi_getprops($task, array(PR_ENTRYID, PR_PARENT_ENTRYID,PR_STORE_ENTRYID));
80
				$message = $GLOBALS['operations']->openMessage($store, $taskProps[PR_ENTRYID]);
81
			} else {
82
				$message = $GLOBALS['operations']->openMessage($store, $entryid);
83
			}
84
			$data['item'] = $GLOBALS['operations']->getMessageProps($store, $message, $this->properties, $this->plaintext);
85
			return $data;
86
		}
87
88
		/**
89
		 * Function which saves an item.
90
		 * @param object $store MAPI Message Store Object
91
		 * @param string $parententryid parent entryid of the message
92
		 * @param array $action the action data, sent by the client
93
		 * @return boolean true on success or false on failure
94
		 */
95
		function save($store, $parententryid, $entryid, $action)
96
		{
97
			if(isset($action["props"])) {
98
				if(!$store && !$parententryid) {
99
					if(isset($action["props"]["message_class"])) {
100
						$store = $GLOBALS["mapisession"]->getDefaultMessageStore();
101
						$parententryid = $this->getDefaultFolderEntryID($store, $action["props"]["message_class"]);
102
					}
103
				}
104
105
				if ($store && $parententryid) {
106
					// Set the message flag for the item
107
					if(isset($action['props']['message_flags']) && $entryid) {
108
						$GLOBALS['operations']->setMessageFlag($store, $entryid, $action['props']['message_flags']);
109
					}
110
111
					$messageProps = $this->saveTask($store, $parententryid, $entryid, $action);
112
113
					if($messageProps) {
114
						$send = isset($action["message_action"]["send"]) ? $action["message_action"]["send"] : false;
115
						$message = $GLOBALS['operations']->openMessage($store, $messageProps[PR_ENTRYID]);
116
						$data = $GLOBALS['operations']->getMessageProps($store, $message, $this->properties, $this->plaintext);
117
118
						// taskupdates property true if assigner as checked "Keep copy of task in task list" checkbox.
119
						// if it is not checked then it means user don't want assigned task copy in his task list.
120
						if($send && isset($data["props"]['taskupdates']) && $data["props"]['taskupdates'] === false) {
121
							// Hard delete the task if taskupdates property is not true.
122
							$folder = mapi_msgstore_openentry($store, $parententryid);
123
							mapi_folder_deletemessages($folder, array($messageProps[PR_ENTRYID]), DELETE_HARD_DELETE);
124
125
							$data = Conversion::mapMAPI2XML($this->properties , $messageProps);
126
							$GLOBALS["bus"]->notify(bin2hex($parententryid), TABLE_DELETE, $messageProps);
127
						} else {
128
							$GLOBALS["bus"]->notify(bin2hex($parententryid), TABLE_SAVE, $messageProps);
129
						}
130
						// Notify To-Do list folder as new task item was created.
131
						$GLOBALS["bus"]->notify(bin2hex(TodoList::getEntryId()), OBJECT_SAVE, $messageProps);
132
						$this->addActionData("update", array("item" => $data));
133
						$GLOBALS["bus"]->addData($this->getResponseData());
134
					}
135
				}
136
			}
137
		}
138
139
		/**
140
		 * Function which deletes an item.
141
		 * @param object $store MAPI Message Store Object
142
		 * @param string $parententryid parent entryid of the message
143
		 * @param string $entryid entryid of the message
144
		 * @param array $action the action data, sent by the client
145
		 * @return boolean true on success or false on failure
146
		 */
147
		function delete($store, $parententryid, $entryids, $action)
148
		{
149
			if($store && $parententryid) {
150
				$props = array();
151
				$props[PR_PARENT_ENTRYID] = $parententryid;
152
				$props[PR_ENTRYID] = $entryids;
153
154
				$storeprops = mapi_getprops($store, array(PR_ENTRYID));
155
				$props[PR_STORE_ENTRYID] = $storeprops[PR_ENTRYID];
156
157
				$result = $this->deleteTask($store, $parententryid, $entryids, $action);
158
159
				if ($result) {
160
					if (isset($result['occurrenceDeleted']) && $result['occurrenceDeleted']) {
161
						// Occurrence deleted, update item
162
						$GLOBALS["bus"]->notify(bin2hex($parententryid), TABLE_SAVE, $props);
163
					} else {
164
						$GLOBALS["bus"]->notify(bin2hex($parententryid), TABLE_DELETE, $props);
165
					}
166
					$this->sendFeedback(true);
167
				}
168
			}
169
		}
170
171
		/**
172
		 * Deletes a task.
173
		 *
174
		 * deletes occurrence if task is a recurring item.
175
		 * @param mapistore $store MAPI Message Store Object
176
		 * @param string $parententryid parent entryid of the messages to be deleted
177
		 * @param array $entryids a list of entryids which will be deleted
178
		 * @param boolean $softDelete flag for soft-deleting (when user presses Shift+Del)
179
		 * @return boolean true if action succeeded, false if not
180
		 */
181
		function deleteTask($store, $parententryid, $entryids, $action)
182
		{
183
			$result = false;
184
			$message = mapi_msgstore_openentry($store, $entryids);
185
			$messageAction = isset($action["message_action"]["action_type"]) ? $action["message_action"]["action_type"] : false;
186
			// If user wants to delete only occurrence then delete this occurrence
187
			if (!is_array($entryids) && $messageAction) {
188
				if ($message) {
189
					if ($messageAction == 'occurrence') {
190
						$recur = new TaskRecurrence($store, $message);
191
						$occurrenceDeleted = $recur->deleteOccurrence($action);
192
					} else if ($messageAction == 'declineAndDelete' || $messageAction == 'completeAndDelete') {
193
						$taskReq = new TaskRequest($store, $message, $GLOBALS["mapisession"]->getSession());
194
						if ($messageAction == 'declineAndDelete') {
195
							$taskReq->doDecline();
196
						} else if ($messageAction == 'completeAndDelete') {
197
							$taskReq->sendCompleteUpdate();
198
						}
199
					}
200
				}
201
			}
202
203
			// Deleting occurrence failed, maybe that was its last occurrence, so now we delete whole series.
204
			if (!isset($occurrenceDeleted) || !$occurrenceDeleted) {
205
				$properties = $GLOBALS["properties"]->getTaskProperties();
206
				$goid = mapi_getprops($message, array($properties["task_goid"]));
207
				// If task is assigned task to assignee and user is trying to delete the task.
208
				// then we have to remove respective task request(IPM.TaskRequest.Accept/Decline/Update)
209
				// notification mail from inbox.
210
				if(isset($goid[$properties["task_goid"]]) && !empty($goid[$properties["task_goid"]])) {
211
					$taskReq = new TaskRequest($store, $message, $GLOBALS["mapisession"]->getSession());
212
					$result = $taskReq->deleteReceivedTR();
213
					if($result) {
214
						$GLOBALS["bus"]->notify(bin2hex($result[PR_PARENT_ENTRYID]), TABLE_DELETE, $result);
215
					}
216
				}
217
218
				// If softdelete is set then set it in softDelete variable and pass it for deleting message.
219
				$softDelete = isset($action['message_action']['soft_delete']) ? $action['message_action']['soft_delete'] : false;
220
				$result = $GLOBALS["operations"]->deleteMessages($store, $parententryid, $entryids, $softDelete);
221
			} else {
222
				$result = array('occurrenceDeleted' => true);
223
			}
224
225
			return $result;
226
		}
227
228
		/**
229
		 * Save task item.
230
		 *
231
		 * just one step more before saving task message that to support recurrence and task request here. We need
232
		 * to regenerate task if it is recurring and client has changed either set as complete or delete or
233
		 * given new start or end date.
234
		 *
235
		 * @param mapistore $store MAPI store of the message
236
		 * @param string $parententryid Parent entryid of the message (folder entryid, NOT message entryid)
237
		 * @param array $action Action array containing XML request
238
		 * @return array of PR_ENTRYID, PR_PARENT_ENTRYID and PR_STORE_ENTRYID properties of modified item
239
		 */
240
		function saveTask($store, $parententryid, $entryid, $action)
241
		{
242
			$properties = $this->properties;
243
			$messageProps = array();
244
			$send = isset($action["message_action"]["send"]) ? $action["message_action"]["send"] : false;
245
246
			if($store && $parententryid) {
247
				if(isset($action["props"])) {
248
249
					if (isset($action["entryid"]) && empty($action["entryid"])) {
250
						$GLOBALS["operations"]->setSenderAddress($store, $action);
251
					}
252
253
					$props = $action["props"];
254
					$recips = array();
255
					if(isset($action["recipients"]) && is_array($action["recipients"])) {
256
						$recips = $action["recipients"];
257
					}
258
259
					if (isset($action["entryid"]) && !empty($action["entryid"])) {
260
						$message = mapi_msgstore_openentry($store, hex2bin($action["entryid"]));
261
						if ($message) {
262
							$messageProps = mapi_getprops($message, array(PR_ENTRYID, PR_PARENT_ENTRYID, PR_STORE_ENTRYID, $properties['recurring']));
263
264
							if ((isset($messageProps[$properties['recurring']]) && $messageProps[$properties['recurring']]) ||
265
								(isset($props['recurring']) && $props['recurring'])) {
266
								$recur = new TaskRecurrence($store, $message);
267
268
								if (isset($props['recurring_reset']) && $props['recurring_reset'] == 1) {
269
									$msgProps = $recur->setRecurrence($props);
270
								} else if ((isset($props['complete']) && $props['complete'] == 1)) {
271
									$msgProps = $recur->markOccurrenceComplete($props);
272
								}
273
							}
274
							mapi_savechanges($message);
275
276
							$messageProps = Conversion::mapXML2MAPI($properties, $props);
277
278
							$message = $GLOBALS["operations"]->saveMessage($store, $entryid, $parententryid, $messageProps, $messageProps, $recips, isset($action['attachments']) ? $action['attachments'] : array(), array());
279
280
							if (isset($msgProps) && $msgProps) {
281
								$messageProps = $msgProps;
282
							}
283
						}
284
					} else {
285
						$messageProps = Conversion::mapXML2MAPI($properties, $props);
286
						//New message
287
288
						$copyAttachments = false;
289
						$copyFromMessage = false;
290
291
						// we need to copy the original attachments when create task from message.
292
						if (isset($action['message_action']) && isset($action['message_action']['source_entryid'])) {
293
							$copyFromMessage = hex2bin($action['message_action']['source_entryid']);
294
							$copyFromStore = hex2bin($action['message_action']['source_store_entryid']);
295
							$copyAttachments = true;
296
297
							// get resources of store and message
298
							$copyFromStore = $GLOBALS['mapisession']->openMessageStore($copyFromStore);
299
							$copyFromMessage = $GLOBALS['operations']->openMessage($copyFromStore, $copyFromMessage);
300
						}
301
302
						$message = $GLOBALS["operations"]->saveMessage($store, $entryid, $parententryid, $messageProps, $messageProps, $recips, isset($action['attachments']) ? $action['attachments'] : array(), array(), $copyFromMessage, $copyAttachments, false, false, false);
303
304
						// Set recurrence
305
						if (isset($action['props']['recurring']) && $action['props']['recurring'] == 1) {
306
							$recur = new TaskRecurrence($store, $message);
307
							$recur->setRecurrence($props);
308
						}
309
					}
310
311
					if ($message) {
312
						$tr = new TaskRequest($store, $message, $GLOBALS["mapisession"]->getSession());
313
						if ($send) {
314
							$tr->sendTaskRequest(_("Task Request:") . " ");
315
316
							return $messageProps;
317
						} else if (isset($action["message_action"]["response_type"]) && $action["message_action"]["response_type"] === tdmtTaskUpd) {
318
							$tr->doUpdate();
319
320
							return $messageProps;
321
						} else if (isset($action["message_action"]["action_type"]) && $action["message_action"]["action_type"] === "restoreToTaskList") {
322
							$deleteTRProps = $tr->deleteReceivedTR();
323
							if ($deleteTRProps) {
324
								$GLOBALS["bus"]->notify(bin2hex($deleteTRProps[PR_PARENT_ENTRYID]), TABLE_DELETE, $deleteTRProps);
325
							}
326
							return $messageProps;
327
						}
328
					}
329
330
					mapi_savechanges($message);
331
				}
332
			}
333
334
			// Return message properties that can be sent to the bus to notify changes
335
			return $messageProps;
336
		}
337
	}
338
?>
0 ignored issues
show
It is not recommended to use PHP's closing tag ?> in files other than templates.

Using a closing tag in PHP files that only contain PHP code is not recommended as you might accidentally add whitespace after the closing tag which would then be output by PHP. This can cause severe problems, for example headers cannot be sent anymore.

A simple precaution is to leave off the closing tag as it is not required, and it also has no negative effects whatsoever.

Loading history...
339