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

TaskItemModule::deleteTask()   C

Complexity

Conditions 16
Paths 98

Size

Total Lines 45
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 16
eloc 27
nc 98
nop 4
dl 0
loc 45
rs 5.5666
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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();
0 ignored issues
show
Bug Best Practice introduced by
The property properties does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
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);
0 ignored issues
show
Bug introduced by
It seems like $task can also be of type false; however, parameter $task of TaskItemModule::getMessageProps() does only seem to accept object, maybe add an additional type check? ( Ignorable by Annotation )

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

56
					$data = $this->getMessageProps($store, $entryid, $action, /** @scrutinizer ignore-type */ $task);
Loading history...
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);
0 ignored issues
show
Comprehensibility Best Practice introduced by
$data was never initialized. Although not strictly required by PHP, it is generally a good practice to add $data = array(); before regardless.
Loading history...
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) {
0 ignored issues
show
introduced by
$store is of type object, thus it always evaluated to true.
Loading history...
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
0 ignored issues
show
Bug introduced by
The type mapistore was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
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) {
0 ignored issues
show
introduced by
The condition is_array($entryids) is always true.
Loading history...
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
Best Practice introduced by
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