AdvancedSearchListModule::search()   F
last analyzed

Complexity

Conditions 33
Paths 8652

Size

Total Lines 205
Code Lines 115

Duplication

Lines 0
Ratio 0 %

Importance

Changes 5
Bugs 2 Features 0
Metric Value
cc 33
eloc 115
c 5
b 2
f 0
nc 8652
nop 4
dl 0
loc 205
rs 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
require_once BASE_PATH . 'server/includes/core/class.indexsqlite.php';
4
5
class AdvancedSearchListModule extends ListModule {
6
	/**
7
	 * Constructor.
8
	 *
9
	 * @param int   $id   unique id
10
	 * @param array $data list of all actions
11
	 */
12
	public function __construct($id, $data) {
13
		parent::__construct($id, $data);
14
		// TODO: create a new method in Properties class that will return only the properties we
15
		// need for search list (and perhaps for preview???)
16
		$this->properties = $GLOBALS["properties"]->getMailListProperties();
17
		$this->properties = array_merge($this->properties, $GLOBALS["properties"]->getAppointmentListProperties());
18
		$this->properties = array_merge($this->properties, $GLOBALS["properties"]->getContactListProperties());
19
		$this->properties = array_merge($this->properties, $GLOBALS["properties"]->getStickyNoteListProperties());
20
		$this->properties = array_merge($this->properties, $GLOBALS["properties"]->getTaskListProperties());
21
		$this->properties = array_merge($this->properties, [
22
			'body' => PR_BODY,
23
			'html_body' => PR_HTML,
24
			'startdate' => "PT_SYSTIME:PSETID_Appointment:" . PidLidAppointmentStartWhole,
25
			'duedate' => "PT_SYSTIME:PSETID_Appointment:" . PidLidAppointmentEndWhole,
26
			'creation_time' => PR_CREATION_TIME,
27
			"task_duedate" => "PT_SYSTIME:PSETID_Task:" . PidLidTaskDueDate,
28
		]);
29
		$this->properties = getPropIdsFromStrings($GLOBALS["mapisession"]->getDefaultMessageStore(), $this->properties);
30
		$this->sort = [
31
			PR_MESSAGE_DELIVERY_TIME => TABLE_SORT_DESCEND,
32
		];
33
	}
34
35
	/**
36
	 * Executes all the actions in the $data variable.
37
	 */
38
	#[Override]
39
	public function execute() {
40
		foreach ($this->data as $actionType => $action) {
41
			if (isset($actionType)) {
42
				try {
43
					$store = $this->getActionStore($action);
44
					$parententryid = $this->getActionParentEntryID($action);
0 ignored issues
show
Unused Code introduced by
The assignment to $parententryid is dead and can be removed.
Loading history...
45
					$entryid = $this->getActionEntryID($action);
46
47
					switch ($actionType) {
48
						case "list":
49
						case "updatelist":
50
							$this->getDelegateFolderInfo($store);
0 ignored issues
show
Bug introduced by
$store of type object is incompatible with the type resource expected by parameter $store of ListModule::getDelegateFolderInfo(). ( Ignorable by Annotation )

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

50
							$this->getDelegateFolderInfo(/** @scrutinizer ignore-type */ $store);
Loading history...
51
							$this->messageList($store, $entryid, $action, $actionType);
52
							break;
53
54
						case "search":
55
							$this->search($store, $entryid, $action, $actionType);
56
							break;
57
58
						case "updatesearch":
59
							$this->updatesearch($store, $entryid, $action);
60
							break;
61
62
						case "stopsearch":
63
							$this->stopSearch($store, $entryid, $action);
64
							break;
65
66
						case "delete_searchfolder":
67
							$this->deleteSearchFolder($store, $entryid, $action);
68
							break;
69
					}
70
				}
71
				catch (MAPIException $e) {
72
					// This is a very nasty hack that makes sure that grommunio Web doesn't show an error message when
73
					// search wants to throw an error. This is only done because a proper fix for this bug has not
74
					// been found yet. When WA-9161 is really solved, this should be removed again.
75
					if ($actionType !== 'search' && $actionType !== 'updatesearch' && $actionType !== 'stopsearch') {
76
						$this->processException($e, $actionType);
77
					}
78
					else {
79
						if (DEBUG_LOADER === 0) {
80
							// Log all info we can get about this error to the error log of the web server
81
							error_log("Error in search: \n" . var_export($e, true) . "\n\n" . var_export(debug_backtrace(), true));
82
						}
83
						// Send success feedback without data, as if nothing strange happened...
84
						$this->sendFeedback(true);
85
					}
86
				}
87
			}
88
		}
89
	}
90
91
	/**
92
	 * Function which retrieves a list of messages in a folder.
93
	 *
94
	 * @param object $store      MAPI Message Store Object
95
	 * @param string $entryid    entryid of the folder
96
	 * @param array  $action     the action data, sent by the client
97
	 * @param string $actionType the action type, sent by the client
98
	 */
99
	#[Override]
100
	public function messageList($store, $entryid, $action, $actionType) {
101
		$this->searchFolderList = false; // Set to indicate this is not the search result, but a normal folder content
102
		$data = [];
103
104
		if ($store && $entryid) {
105
			// Restriction
106
			$this->parseRestriction($action);
0 ignored issues
show
Bug introduced by
$action of type array is incompatible with the type object expected by parameter $action of ListModule::parseRestriction(). ( Ignorable by Annotation )

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

106
			$this->parseRestriction(/** @scrutinizer ignore-type */ $action);
Loading history...
107
108
			// Sort
109
			$this->parseSortOrder($action, null, true);
110
111
			$limit = $action['restriction']['limit'] ?? 1000;
112
113
			$isSearchFolder = isset($action['search_folder_entryid']);
114
			$entryid = $isSearchFolder ? hex2bin((string) $action['search_folder_entryid']) : $entryid;
115
116
			if ($actionType == 'search') {
117
				$rows = [[PR_ENTRYID => $entryid]];
118
				if (isset($action['subfolders']) && $action['subfolders']) {
119
					$folder = mapi_msgstore_openentry($store, $entryid);
120
					$htable = mapi_folder_gethierarchytable($folder, CONVENIENT_DEPTH | MAPI_DEFERRED_ERRORS);
121
					$rows = mapi_table_queryallrows($htable, [PR_ENTRYID]);
122
				}
123
				$data['item'] = [];
124
				foreach ($rows as $row) {
125
					$items = $GLOBALS["operations"]->getTable($store, $row[PR_ENTRYID], $this->properties, $this->sort, $this->start, $limit, $this->restriction);
126
					$data['item'] = array_merge($data['item'], $items['item']);
127
					if (count($data['item']) >= $limit) {
128
						break;
129
					}
130
				}
131
				$data['page'] = [];
132
				$data['page']['start'] = 0;
133
				$data['page']['rowcount'] = 0;
134
				$data['page']['totalrowcount'] = count($data['item']);
135
				$data['search_meta'] = [];
136
				$data['search_meta']['searchfolder_entryid'] = null;
137
				$data['search_meta']['search_store_entryid'] = $action['store_entryid'];
138
				$data['search_meta']['searchstate'] = null;
139
				$data['search_meta']['results'] = count($data['item']);
140
				$data['folder'] = [];
141
				$data['folder']['content_count'] = count($data['item']);
142
				$data['folder']['content_unread'] = 0;
143
			}
144
			else {
145
				// Get the table and merge the arrays
146
				$data = $GLOBALS["operations"]->getTable($store, $entryid, $this->properties, $this->sort, $this->start, $limit, $this->restriction);
147
			}
148
149
			// If the request come from search folder then no need to send folder information
150
			if (!$isSearchFolder && !isset($data['folder'])) {
151
				// Open the folder.
152
				$folder = mapi_msgstore_openentry($store, $entryid);
153
				$data["folder"] = [];
154
155
				// Obtain some statistics from the folder contents
156
				$contentcount = mapi_getprops($folder, [PR_CONTENT_COUNT, PR_CONTENT_UNREAD]);
157
				if (isset($contentcount[PR_CONTENT_COUNT])) {
158
					$data["folder"]["content_count"] = $contentcount[PR_CONTENT_COUNT];
159
				}
160
161
				if (isset($contentcount[PR_CONTENT_UNREAD])) {
162
					$data["folder"]["content_unread"] = $contentcount[PR_CONTENT_UNREAD];
163
				}
164
			}
165
166
			$data = $this->filterPrivateItems($data);
167
168
			// Allowing to hook in just before the data sent away to be sent to the client
169
			$GLOBALS['PluginManager']->triggerHook('server.module.listmodule.list.after', [
170
				'moduleObject' => &$this,
171
				'store' => $store,
172
				'entryid' => $entryid,
173
				'action' => $action,
174
				'data' => &$data,
175
			]);
176
177
			// unset will remove the value but will not regenerate array keys, so we need to
178
			// do it here
179
			$data["item"] = array_values($data["item"]);
180
			$this->addActionData($actionType, $data);
181
			$GLOBALS["bus"]->addData($this->getResponseData());
182
		}
183
	}
184
185
	private function parsePatterns($restriction, &$patterns) {
186
		if (empty($restriction)) {
187
			return;
188
		}
189
		$type = $restriction[0];
190
		if ($type == RES_CONTENT) {
191
			$subres = $restriction[1];
192
193
			switch ($subres[ULPROPTAG]) {
194
				case PR_SUBJECT:
195
					$patterns['subject'] = $subres[VALUE][$subres[ULPROPTAG]];
196
					break;
197
198
				case PR_BODY:
199
					$patterns['content'] = $subres[VALUE][$subres[ULPROPTAG]];
200
					$patterns['attachments'] = $subres[VALUE][$subres[ULPROPTAG]];
201
					break;
202
203
				case PR_SENDER_NAME:
204
					$patterns['sender'] = $subres[VALUE][$subres[ULPROPTAG]];
205
					break;
206
207
				case PR_SENT_REPRESENTING_NAME:
208
					$patterns['sending'] = $subres[VALUE][$subres[ULPROPTAG]];
209
					break;
210
211
				case PR_DISPLAY_TO:
212
				case PR_DISPLAY_CC:
213
					$patterns['recipients'] = $subres[VALUE][$subres[ULPROPTAG]];
214
					break;
215
216
				case PR_MESSAGE_CLASS:
217
					if (empty($patterns['message_classes'])) {
218
						$patterns['message_classes'] = [];
219
					}
220
					$patterns['message_classes'][] = $subres[VALUE][$subres[ULPROPTAG]];
221
					break;
222
223
				case PR_DISPLAY_NAME:
224
					$patterns['others'] = $subres[VALUE][$subres[ULPROPTAG]];
225
					break;
226
227
				case $this->properties['categories']:
228
					if (!isset($patterns['categories'])) {
229
						$patterns['categories'] = [];
230
					}
231
					if (isset($subres[VALUE][$subres[ULPROPTAG]][0])) {
232
						$patterns['categories'][] = $subres[VALUE][$subres[ULPROPTAG]][0];
233
					}
234
					break;
235
			}
236
		}
237
		elseif ($type == RES_AND || $type == RES_OR) {
238
			foreach ($restriction[1] as $subres) {
239
				$this->parsePatterns($subres, $patterns);
240
			}
241
		}
242
		elseif ($type == RES_BITMASK) {
243
			$subres = $restriction[1];
244
			if ($subres[ULPROPTAG] == PR_MESSAGE_FLAGS && $subres[ULTYPE] == BMR_EQZ) {
245
				$patterns['unread'] = MSGFLAG_READ & $subres[ULMASK];
246
			}
247
		}
248
		elseif ($type == RES_PROPERTY) {
249
			$subres = $restriction[1];
250
			if ($subres[ULPROPTAG] == PR_MESSAGE_DELIVERY_TIME ||
251
				$subres[ULPROPTAG] == PR_LAST_MODIFICATION_TIME) {
252
				if ($subres[RELOP] == RELOP_LT ||
253
					$subres[RELOP] == RELOP_LE) {
254
					$patterns['date_end'] = $subres[VALUE][$subres[ULPROPTAG]];
255
				}
256
				elseif ($subres[RELOP] == RELOP_GT ||
257
					$subres[RELOP] == RELOP_GE) {
258
					$patterns['date_start'] = $subres[VALUE][$subres[ULPROPTAG]];
259
				}
260
			}
261
		}
262
		elseif ($type == RES_SUBRESTRICTION) {
263
			$subres = $restriction[1];
264
			$patterns['has_attachments'] = $subres[ULPROPTAG] == PR_MESSAGE_ATTACHMENTS;
265
		}
266
	}
267
268
	/**
269
	 *	Function will set search restrictions on search folder and start search process
270
	 *	and it will also parse visible columns and sorting data when sending results to client.
271
	 *
272
	 * @param object $store      MAPI Message Store Object
273
	 * @param string $entryid    entryid of the folder
274
	 * @param object $action     the action data, sent by the client
275
	 * @param string $actionType the action type, sent by the client
276
	 */
277
	#[Override]
278
	public function search($store, $entryid, $action, $actionType) {
279
		$useSearchFolder = $action["use_searchfolder"] ?? false;
280
		if (!$useSearchFolder) {
281
			/*
282
			 * store doesn't support search folders so we can't use this
283
			 * method instead we will pass restriction to messageList and
284
			 * it will give us the restricted results
285
			 */
286
			return parent::messageList($store, $entryid, $action, "list");
0 ignored issues
show
Bug introduced by
Are you sure the usage of parent::messageList($sto...tryid, $action, 'list') targeting ListModule::messageList() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
Bug introduced by
$action of type object is incompatible with the type array expected by parameter $action of ListModule::messageList(). ( Ignorable by Annotation )

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

286
			return parent::messageList($store, $entryid, /** @scrutinizer ignore-type */ $action, "list");
Loading history...
287
		}
288
		$store_props = mapi_getprops($store, [PR_MDB_PROVIDER, PR_DEFAULT_STORE, PR_IPM_SUBTREE_ENTRYID]);
289
		if ($store_props[PR_MDB_PROVIDER] == ZARAFA_STORE_PUBLIC_GUID) {
290
			// public store does not support search folders
291
			return parent::messageList($store, $entryid, $action, "search");
0 ignored issues
show
Bug introduced by
Are you sure the usage of parent::messageList($sto...yid, $action, 'search') targeting ListModule::messageList() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
292
		}
293
		if ($GLOBALS['entryid']->compareEntryIds(bin2hex($entryid), bin2hex(TodoList::getEntryId()))) {
294
			// todo list do not need to perform full text index search
295
			return parent::messageList($store, $entryid, $action, "list");
0 ignored issues
show
Bug introduced by
Are you sure the usage of parent::messageList($sto...tryid, $action, 'list') targeting ListModule::messageList() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
296
		}
297
298
		$this->searchFolderList = true; // Set to indicate this is not the normal folder, but a search folder
299
		$this->restriction = false;
0 ignored issues
show
Documentation Bug introduced by
It seems like false of type false is incompatible with the declared type array of property $restriction.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
300
301
		// Parse Restriction
302
		$this->parseRestriction($action);
303
		if ($this->restriction == false) {
304
			// if error in creating restriction then send error to client
305
			$errorInfo = [];
306
			$errorInfo["error_message"] = _("Error in search, please try again") . ".";
307
			$errorInfo["original_error_message"] = "Error in parsing restrictions.";
308
309
			return $this->sendSearchErrorToClient($store, $entryid, $action, $errorInfo);
0 ignored issues
show
Bug introduced by
$errorInfo of type array is incompatible with the type object expected by parameter $errorInfo of ListModule::sendSearchErrorToClient(). ( Ignorable by Annotation )

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

309
			return $this->sendSearchErrorToClient($store, $entryid, $action, /** @scrutinizer ignore-type */ $errorInfo);
Loading history...
Bug introduced by
$entryid of type string is incompatible with the type hexString expected by parameter $entryid of ListModule::sendSearchErrorToClient(). ( Ignorable by Annotation )

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

309
			return $this->sendSearchErrorToClient($store, /** @scrutinizer ignore-type */ $entryid, $action, $errorInfo);
Loading history...
310
		}
311
312
		$isSetSearchFolderEntryId = isset($action['search_folder_entryid']);
313
		if ($isSetSearchFolderEntryId) {
314
			$this->sessionData['searchFolderEntryId'] = $action['search_folder_entryid'];
315
		}
316
317
		if (isset($action['forceCreateSearchFolder']) && $action['forceCreateSearchFolder']) {
318
			$isSetSearchFolderEntryId = false;
319
		}
320
321
		// create or open search folder
322
		$searchFolder = $this->createSearchFolder($store, $isSetSearchFolderEntryId);
323
		if ($searchFolder === false) {
324
			if ($store_props[PR_MDB_PROVIDER] == ZARAFA_STORE_DELEGATE_GUID) {
325
				$this->messageList($store, $entryid, $action, "search");
326
327
				return true;
328
			}
329
			// if error in creating search folder then send error to client
330
			$errorInfo = [];
331
332
			$errorInfo["error_message"] = match (mapi_last_hresult()) {
333
				MAPI_E_NO_ACCESS => _("Unable to perform search query, no permissions to create search folder."),
334
				MAPI_E_NOT_FOUND => _("Unable to perform search query, search folder not found."),
335
				default => _("Unable to perform search query, store might not support searching."),
336
			};
337
338
			$errorInfo["original_error_message"] = _("Error in creating search folder.");
339
340
			return $this->sendSearchErrorToClient($store, $entryid, $action, $errorInfo);
0 ignored issues
show
Bug introduced by
$errorInfo of type array is incompatible with the type object expected by parameter $errorInfo of ListModule::sendSearchErrorToClient(). ( Ignorable by Annotation )

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

340
			return $this->sendSearchErrorToClient($store, $entryid, $action, /** @scrutinizer ignore-type */ $errorInfo);
Loading history...
341
		}
342
343
		$subfolder_flag = 0;
344
		$recursive = false;
345
		if (isset($action["subfolders"]) && $action["subfolders"] == "true") {
346
			$recursive = true;
347
			$subfolder_flag = RECURSIVE_SEARCH;
348
		}
349
350
		if (!is_array($entryid)) {
0 ignored issues
show
introduced by
The condition is_array($entryid) is always false.
Loading history...
351
			$entryids = [$entryid];
352
		}
353
		else {
354
			$entryids = $entryid;
355
		}
356
357
		$searchFolderEntryId = $this->sessionData['searchFolderEntryId'];
358
359
		// check if searchcriteria has changed
360
		$restrictionCheck = md5(serialize($this->restriction) . $searchFolderEntryId . $subfolder_flag);
361
362
		// check if there is need to set searchcriteria again
363
		if (!isset($this->sessionData['searchCriteriaCheck']) || $restrictionCheck != $this->sessionData['searchCriteriaCheck']) {
364
			if (!empty($this->sessionData['searchOriginalEntryids']) &&
365
				isset($action['entryid']) &&
366
				in_array($action['entryid'], $this->sessionData['searchOriginalEntryids'])
367
			) {
368
				// get entryids of original folders, and use it to set new search criteria
369
				$entryids = [];
370
				$entryIdsCount = count($this->sessionData['searchOriginalEntryids']);
371
				for ($index = 0; $index < $entryIdsCount; ++$index) {
372
					$entryids[] = hex2bin((string) $this->sessionData['searchOriginalEntryids'][$index]);
373
				}
374
			}
375
			else {
376
				// store entryids of original folders, so that can be used for re-setting the search criteria if needed
377
				$this->sessionData['searchOriginalEntryids'] = [];
378
				for ($index = 0, $len = count($entryids); $index < $len; ++$index) {
379
					$this->sessionData['searchOriginalEntryids'][] = bin2hex($entryids[$index]);
380
				}
381
			}
382
			// we never start the search folder because we will populate the search folder by ourselves
383
			mapi_folder_setsearchcriteria($searchFolder, $this->restriction, $entryids, $subfolder_flag | STOP_SEARCH);
384
			$this->sessionData['searchCriteriaCheck'] = $restrictionCheck;
385
		}
386
387
		if (isset($this->sessionData['searchCriteriaCheck']) || $restrictionCheck == $this->sessionData['searchCriteriaCheck']) {
388
			$folderEntryid = bin2hex($entryid);
389
			if ($this->sessionData['searchOriginalEntryids'][0] !== $folderEntryid) {
390
				$this->sessionData['searchOriginalEntryids'][0] = $folderEntryid;
391
				// we never start the search folder because we will populate the search folder by ourselves
392
				mapi_folder_setsearchcriteria($searchFolder, $this->restriction, [$entryid], $subfolder_flag | STOP_SEARCH);
393
			}
394
		}
395
396
		// Sort
397
		$this->parseSortOrder($action);
398
		// Initialize search patterns with default values
399
		$search_patterns = array_fill_keys(
400
			['sender', 'sending', 'recipients',
401
				'subject', 'content', 'attachments', 'others', 'message_classes',
402
				'date_start', 'date_end', 'unread', 'has_attachments', 'categories'],
403
			null
404
		);
405
		$this->parsePatterns($this->restriction, $search_patterns);
406
		if (isset($search_patterns['message_classes']) &&
407
			count($search_patterns['message_classes']) >= 7) {
408
			$search_patterns['message_classes'] = null;
409
		}
410
411
		if ($store_props[PR_MDB_PROVIDER] == ZARAFA_STORE_DELEGATE_GUID) {
412
			$eidObj = $GLOBALS["entryid"]->createMsgStoreEntryIdObj(hex2bin((string) $action['store_entryid']));
413
			$username = $eidObj['ServerShortname'];
414
			$session = $GLOBALS["mapisession"]->getSession();
415
416
			if ($username) {
417
				$indexDB = new IndexSqlite($username, $session, $store);
418
			}
419
		}
420
		else {
421
			$indexDB = new IndexSqlite();
422
		}
423
424
		$search_result = $indexDB->search(hex2bin((string) $searchFolderEntryId), $search_patterns, $entryid, $recursive);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $indexDB does not seem to be defined for all execution paths leading up to this point.
Loading history...
425
		// Use the query search if search in index fails or is not available.
426
		if ($search_result == false) {
427
			// Search in the inbox instead of Top of Information Store
428
			if (isset($store_props[PR_IPM_SUBTREE_ENTRYID]) &&
429
				$GLOBALS['entryid']->compareEntryIds(bin2hex($entryid), bin2hex((string) $store_props[PR_IPM_SUBTREE_ENTRYID]))) {
430
				$inbox = mapi_msgstore_getreceivefolder($store);
431
				$inboxProps = mapi_getprops($inbox, [PR_ENTRYID]);
432
				$entryid = $inboxProps[PR_ENTRYID];
433
			}
434
435
			return parent::messageList($store, $entryid, $action, "search");
0 ignored issues
show
Bug introduced by
Are you sure the usage of parent::messageList($sto...yid, $action, 'search') targeting ListModule::messageList() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
436
		}
437
438
		unset($action["restriction"]);
439
440
		// Get the table and merge the arrays
441
		$table = $GLOBALS["operations"]->getTable($store, hex2bin((string) $searchFolderEntryId), $this->properties, $this->sort, $this->start);
442
		// Create the data array, which will be send back to the client
443
		$data = [];
444
		$data = array_merge($data, $table);
445
446
		$this->getDelegateFolderInfo($store);
0 ignored issues
show
Bug introduced by
$store of type object is incompatible with the type resource expected by parameter $store of ListModule::getDelegateFolderInfo(). ( Ignorable by Annotation )

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

446
		$this->getDelegateFolderInfo(/** @scrutinizer ignore-type */ $store);
Loading history...
447
		$data = $this->filterPrivateItems($data);
448
449
		// remember which entryid's are send to the client
450
		$searchResults = [];
451
		foreach ($table["item"] as $item) {
452
			// store entryid => last_modification_time mapping
453
			$searchResults[$item["entryid"]] = $item["props"]["last_modification_time"];
454
		}
455
456
		// store search results into session data
457
		if (!isset($this->sessionData['searchResults'])) {
458
			$this->sessionData['searchResults'] = [];
459
		}
460
		$this->sessionData['searchResults'][$searchFolderEntryId] = $searchResults;
461
462
		$result = mapi_folder_getsearchcriteria($searchFolder);
463
464
		$data["search_meta"] = [];
465
		$data["search_meta"]["searchfolder_entryid"] = $searchFolderEntryId;
466
		$data["search_meta"]["search_store_entryid"] = $action["store_entryid"];
467
		$data["search_meta"]["searchstate"] = $result["searchstate"];
468
		$data["search_meta"]["results"] = count($searchResults);
469
470
		// Reopen the search folder, because otherwise the suggestion property will
471
		// not have been updated
472
		$searchFolder = $this->createSearchFolder($store, true);
473
		$storeProps = mapi_getprops($searchFolder, [PR_EC_SUGGESTION]);
474
		if (isset($storeProps[PR_EC_SUGGESTION])) {
475
			$data["search_meta"]["suggestion"] = $storeProps[PR_EC_SUGGESTION];
476
		}
477
478
		$this->addActionData("search", $data);
479
		$GLOBALS["bus"]->addData($this->getResponseData());
480
481
		return true;
482
	}
483
}
484