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

ReminderListModule::createReminderFolder()   D

Complexity

Conditions 13
Paths 256

Size

Total Lines 96
Code Lines 64

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 13
eloc 64
nc 256
nop 1
dl 0
loc 96
rs 4.8521
c 0
b 0
f 0

How to fix   Long Method    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
	/**
3
	* Reminder Module
4
	*
5
	* TODO: add description
6
	*
7
	*/
8
	class ReminderListModule extends ListModule
9
	{
10
		/**
11
		* Constructor
12
		* @param int $id unique id.
13
		* @param array $data list of all actions.
14
		*/
15
		function __construct($id, $data)
16
		{
17
			parent::__construct($id, $data);
18
19
			$this->properties = $GLOBALS["properties"]->getReminderProperties();		
20
		}
21
22
		function execute()
23
		{
24
			foreach($this->data as $actionType => $action)
25
			{
26
				$store = $GLOBALS["mapisession"]->getDefaultMessageStore();
27
				$this->reminderEntryId = $this->getReminderFolderEntryId($store);
0 ignored issues
show
Bug Best Practice introduced by
The property reminderEntryId does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
28
29
				if(isset($actionType)) {
30
					try {
31
						switch($actionType)
32
						{
33
							case "list":
34
								$this->getReminders();
35
								break;
36
							default:
37
								$this->handleUnknownActionType($actionType);
38
						}
39
					} catch (MAPIException $e) {
40
						$this->processException($e, $actionType, $store, null, null, $action);
41
					}
42
				}
43
			}
44
		}
45
46
		function getReminderFolderEntryId($store)
47
		{
48
			$root = mapi_msgstore_openentry($store, null);
49
			$rootProps = mapi_getprops($root, array(PR_REM_ONLINE_ENTRYID));
50
			if (isset($rootProps[PR_REM_ONLINE_ENTRYID])){
51
				return $rootProps[PR_REM_ONLINE_ENTRYID];
52
			}
53
54
			// Reminder folder didn't exist, create one
55
			$entryid = $this->createReminderFolder($store);
56
			return $entryid;
57
		}
58
59
		function createReminderFolder($store)
60
		{
61
			$storeProps = mapi_getprops($store, array(PR_IPM_OUTBOX_ENTRYID, PR_IPM_WASTEBASKET_ENTRYID, PR_IPM_SUBTREE_ENTRYID));
62
			$root = mapi_msgstore_openentry($store, null);
63
			$rootProps = mapi_getprops($root, array(PR_ADDITIONAL_REN_ENTRYIDS, PR_IPM_DRAFTS_ENTRYID));
64
65
66
			$folders = array();
67
			if (isset($storeProps[PR_IPM_WASTEBASKET_ENTRYID]))
68
				$folders[] = $storeProps[PR_IPM_WASTEBASKET_ENTRYID];
69
			if (isset($rootProps[PR_ADDITIONAL_REN_ENTRYIDS])&&!empty($rootProps[PR_ADDITIONAL_REN_ENTRYIDS][4]))
70
				$folders[] = $rootProps[PR_ADDITIONAL_REN_ENTRYIDS][4]; // junk mail
71
			if (isset($rootProps[PR_IPM_DRAFTS_ENTRYID]))
72
				$folders[] = $rootProps[PR_IPM_DRAFTS_ENTRYID];
73
			if (isset($storeProps[PR_IPM_OUTBOX_ENTRYID]))
74
				$folders[] = $storeProps[PR_IPM_OUTBOX_ENTRYID];
75
			if (isset($rootProps[PR_ADDITIONAL_REN_ENTRYIDS])&&!empty($rootProps[PR_ADDITIONAL_REN_ENTRYIDS][0]))
76
				$folders[] = $rootProps[PR_ADDITIONAL_REN_ENTRYIDS][0]; // conflicts
77
			if (isset($rootProps[PR_ADDITIONAL_REN_ENTRYIDS])&&!empty($rootProps[PR_ADDITIONAL_REN_ENTRYIDS][2]))
78
				$folders[] = $rootProps[PR_ADDITIONAL_REN_ENTRYIDS][2]; // local failures
79
			if (isset($rootProps[PR_ADDITIONAL_REN_ENTRYIDS])&&!empty($rootProps[PR_ADDITIONAL_REN_ENTRYIDS][1]))
80
				$folders[] = $rootProps[PR_ADDITIONAL_REN_ENTRYIDS][1]; // sync issues
81
82
			$folderRestriction = array();
83
			foreach($folders as $folder){
84
				$folderRestriction[] = 	array(RES_PROPERTY,
85
											array(
86
												RELOP		=>	RELOP_NE,
87
												ULPROPTAG	=>	$this->properties["parent_entryid"],
88
												VALUE		=>	array($this->properties["parent_entryid"]	=>	$folder)
89
											)
90
										);
91
			}
92
93
			$res =
94
				array(RES_AND,
95
					array(
96
						array(RES_AND,
97
							$folderRestriction
98
						),
99
						array(RES_AND,
100
							array(
101
								array(RES_NOT,
102
									array(
103
										array(RES_AND,
104
											array(
105
												array(RES_EXIST,
106
													array(
107
														ULPROPTAG	=>	$this->properties["message_class"]
108
													)
109
												),
110
												array(RES_CONTENT,
111
													array(
112
														FUZZYLEVEL	=>	FL_PREFIX,
113
														ULPROPTAG	=>	$this->properties["message_class"],
114
														VALUE		=>	array($this->properties["message_class"]	=>	"IPM.Schedule")
115
													)
116
												)
117
											)
118
										)
119
									)
120
								),
121
								array(RES_BITMASK,
122
									array(
123
										ULTYPE		=>	BMR_EQZ,
124
										ULPROPTAG	=>	$this->properties["message_flags"],
125
										ULMASK		=>	MSGFLAG_SUBMIT
126
									)
127
								),
128
								array(RES_OR,
129
									array(
130
										array(RES_PROPERTY,
131
											array(
132
												RELOP		=>	RELOP_EQ,
133
												ULPROPTAG	=>	$this->properties["reminder"],
134
												VALUE		=>	array($this->properties["reminder"]	=>	true)
135
											)
136
										),
137
									)
138
								)
139
							)
140
						)
141
					)
142
				);
143
144
			$folder = mapi_folder_createfolder($root, _("Reminders"), "", OPEN_IF_EXISTS, FOLDER_SEARCH);
145
			mapi_setprops($folder, array(PR_CONTAINER_CLASS	=>	"Outlook.Reminder"));
146
			mapi_savechanges($folder);
147
148
			mapi_folder_setsearchcriteria($folder, $res, array($storeProps[PR_IPM_SUBTREE_ENTRYID]), RECURSIVE_SEARCH);
149
			$folderProps = mapi_getprops($folder, array(PR_ENTRYID));
150
151
			mapi_setprops($root, array(PR_REM_ONLINE_ENTRYID	=>	$folderProps[PR_ENTRYID]));
152
			mapi_savechanges($root);
153
154
			return $folderProps[PR_ENTRYID];
155
		}
156
157
		function getReminders()
158
		{
159
			$data = array();
160
161
			$store = $GLOBALS["mapisession"]->getDefaultMessageStore();
162
163
			$restriction = 	array(RES_AND,
164
								array(
165
									array(RES_PROPERTY,
166
										array(
167
											RELOP		=>	RELOP_LT,
168
											ULPROPTAG	=>	$this->properties["flagdueby"],
169
											VALUE		=>	array($this->properties["flagdueby"] =>	time())
170
										)
171
									),
172
									array(RES_PROPERTY,
173
										array(
174
											RELOP		=>	RELOP_EQ,
175
											ULPROPTAG	=>	$this->properties["reminder"],
176
											VALUE		=>	true
177
										)
178
									),
179
									array(RES_PROPERTY,
180
										array(
181
											RELOP		=>	RELOP_NE,
182
											ULPROPTAG	=>	$this->properties["message_class"],
183
											VALUE		=>	"IPM.TaskRequest"
184
										)
185
									),
186
									array(RES_PROPERTY,
187
										array(
188
											RELOP		=>	RELOP_NE,
189
											ULPROPTAG	=>	$this->properties["message_class"],
190
											VALUE		=>	"IPM.TaskRequest.Cancel"
191
										)
192
									),
193
									array(RES_PROPERTY,
194
										array(
195
											RELOP		=>	RELOP_NE,
196
											ULPROPTAG	=>	$this->properties["message_class"],
197
											VALUE		=>	"IPM.TaskRequest.Accept"
198
										)
199
									),
200
									array(RES_PROPERTY,
201
										array(
202
											RELOP		=>	RELOP_NE,
203
											ULPROPTAG	=>	$this->properties["message_class"],
204
											VALUE		=>	"IPM.TaskRequest.Update"
205
										)
206
									),
207
									array(RES_PROPERTY,
208
										array(
209
											RELOP		=>	RELOP_NE,
210
											ULPROPTAG	=>	$this->properties["message_class"],
211
											VALUE		=>	"IPM.TaskRequest.Complete"
212
										)
213
									)
214
								)
215
			);
216
217
			try {
218
				$reminderfolder = mapi_msgstore_openentry($store, $this->reminderEntryId);
219
			} catch (MAPIException $e) {
220
				// if the reminder folder does not exist, try to recreate it.
221
				if($e->getCode() == MAPI_E_NOT_FOUND) {
222
					$e->setHandled();
223
224
					$this->reminderEntryId = $this->createReminderFolder($store);
0 ignored issues
show
Bug Best Practice introduced by
The property reminderEntryId does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
225
					$reminderfolder = mapi_msgstore_openentry($store, $this->reminderEntryId);
226
				}
227
			}
228
229
			$remindertable = mapi_folder_getcontentstable($reminderfolder, MAPI_DEFERRED_ERRORS);
230
			if(!$remindertable)
231
				return false;
232
233
			mapi_table_restrict($remindertable, $restriction, TBL_BATCH);
234
			mapi_table_sort($remindertable, array($this->properties["flagdueby"] => TABLE_SORT_DESCEND), TBL_BATCH);
235
236
			// reminder store hold only 99 records as
237
			// we show 99 notification on client side.
238
			$rows = mapi_table_queryrows($remindertable, $this->properties, 0, MAX_NUM_REMINDERS);
239
			$data["item"] = array();
240
241
			foreach($rows as $row) {
242
				if(isset($row[$this->properties["appointment_recurring"]]) && $row[$this->properties["appointment_recurring"]]) {
243
					$recur = new Recurrence($store, $row);
244
245
					/**
246
					 * FlagDueBy == PidLidReminderSignalTime.
247
					 * FlagDueBy handles whether we should be showing the item; if now() is after FlagDueBy, then we should show a reminder
248
					 * for this recurrence. However, the item we will show is either the last passed occurrence (overdue), or the next occurrence, depending
249
					 * on whether we have reached the next occurrence yet (the reminder_time of the next item is ignored).
250
					 *
251
					 * The way we handle this is to get all occurrences between the 'flagdueby' moment and the current time. This will
252
					 * yield N items (may be a lot of it was not dismissed for a long time). We can then take the last item in this list, and this is the item
253
					 * we will show to the user. The idea here is:
254
					 *
255
					 * The item we want to show is the last item in that list (new occurrences that have started uptil now should override old ones)
256
					 *
257
					 * Add the reminder_minutes (default 15 minutes for calendar, 0 for tasks) to check over the gap between FlagDueBy and the start time of the
258
					 * occurrence, if "now" would be in between these values.
259
					 */
260
					$remindertimeinseconds = $row[$this->properties["reminder_minutes"]] * 60;
261
					$occurrences = $recur->getItems($row[$this->properties["flagdueby"]], time() + ($remindertimeinseconds), 0, true);
0 ignored issues
show
Bug introduced by
time() + $remindertimeinseconds of type integer is incompatible with the type date expected by parameter $end of BaseRecurrence::getItems(). ( Ignorable by Annotation )

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

261
					$occurrences = $recur->getItems($row[$this->properties["flagdueby"]], /** @scrutinizer ignore-type */ time() + ($remindertimeinseconds), 0, true);
Loading history...
262
263
					if(empty($occurrences))
264
						continue;
265
266
				    // More than one occurrence, use the last one instead of the first one after flagdueby
267
                    $occ = $occurrences[count($occurrences)-1];
268
269
                    // Bydefault, on occurrence reminder is true but if reminder value is set to false then we don't send popup reminder for this occurrence
270
                    if (!(isset($occ[$this->properties['reminder']]) && $occ[$this->properties['reminder']] == 0)) {
271
                        $row[$this->properties["reminder_time"]] = $occ[$this->properties["appointment_startdate"]];
272
                        $row[$this->properties["appointment_startdate"]] = $occ[$this->properties["appointment_startdate"]];
273
                        $row[$this->properties["appointment_enddate"]] = $occ[$this->properties["appointment_startdate"]];
274
                    }
275
				}
276
277
				// Add the non-bogus rows
278
				 array_push($data["item"], Conversion::mapMAPI2XML($this->properties, $row));
279
			}
280
281
			$this->addActionData("list", $data);
282
			$GLOBALS["bus"]->addData($this->getResponseData());
283
284
			// Trigger the newmailnotifier
285
			$GLOBALS["bus"]->notify(REQUEST_ENTRYID, HIERARCHY_UPDATE, ['', '']);
286
287
			return true;
288
		}
289
	}
290
?>
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...
291