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

EntryId::hasContactProviderGUID()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 5
rs 10
c 0
b 0
f 0
1
<?php
2
	class EntryId
3
	{
4
		/* Bit definitions for abFlags[3] of ENTRYID */
5
		const ZARAFA_FAVORITE = '01';
6
7
		/* GUID of root public folder */
8
		const STATIC_GUID_PUBLICFOLDER = '00000000000000000000000000000003';
9
		/* GUID of root favorite folder */
10
		const STATIC_GUID_FAVORITE = '00000000000000000000000000000002';
11
		/* GUID of ipm_subtree of public store*/
12
		const STATIC_GUID_FAVSUBTREE = '00000000000000000000000000000001';
13
		/* GUID of Global Addressbook */
14
		const MUIDECSAB = 'AC21A95040D3EE48B319FBA753304425';
15
		/* GUID of Contact Provider */
16
		const MUIDZCSAB = '727F0430E3924FDAB86AE52A7FE46571';
17
		/* GUID for OneOff entryid */
18
		const MAPI_ONE_OFF_UID = '812B1FA4BEA310199D6E00DD010F5402';
19
		/* GUID for Address book recipient */
20
		const MUIDEMSAB = 'DCA740C8C042101AB4B908002B2FE182';
21
22
		/* Hardcoded ID used for generating entryid of addressbook container */
23
		const ZARAFA_UID_ADDRESS_BOOK = '00000000';
24
		/* Hardcoded ID used for generating entryid of global addressbook container */
25
		const ZARAFA_UID_GLOBAL_ADDRESS_BOOK = '01000000';
26
		/* Hardcoded ID used for generating entryid of global addresslists container */
27
		const ZARAFA_UID_GLOBAL_ADDRESS_LISTS = '02000000';
28
29
		public function __construct()
30
		{
31
		}
32
33
		// Detect padding (max 3 bytes) from the entryId
34
		private function getPadding($entryId)
35
		{
36
			$len = strlen($entryId);
37
			$padding = '';
38
			$offset = 0;
39
40
			for ($iterations = 4; $iterations > 0; $iterations--) {
41
				if (substr($entryId, $len - ($offset + 2), $len - $offset) == '00') {
42
					$padding .= '00';
43
					$offset += 2;
44
				} else {
45
					// if non-null character found then break the loop
46
					break;
47
				}
48
			}
49
50
			return $padding;
51
		}
52
53
		// Entryid from version 6
54
		private function getEIDVersion($entryid)
55
		{
56
			// always make entryids in uppercase so comparison will be case insensitive
57
			$entryId = strtoupper($entryid);
58
59
			$res = array(
60
				'abFlags'	=> '',		// BYTE[4],   4 bytes,  8 hex characters
61
				'guid'		=> '',		// GUID,     16 bytes, 32 hex characters
62
				'version'	=> '',		// ULONG,     4 bytes,  8 hex characters
63
				'type'		=> '',		// ULONG,     4 bytes,  8 hex characters
64
				'uniqueId'	=> '',		// ULONG,    16 bytes,  32 hex characters
65
				'server'	=> '',		// CHAR,     variable length
66
				'padding'	=> '',		// TCHAR[3],  4 bytes,  8 hex characters (upto 4 bytes)
67
			);
68
69
			$res['length'] = strlen($entryId);
70
			$offset = 0;
71
72
			// First determine padding, and remove if from the entryId
73
			$res['padding'] = $this->getPadding($entryId);
74
			$entryId = substr($entryId, 0, strlen($entryId) - strlen($res['padding']));
75
76
			$res['abFlags'] = substr($entryId, $offset, 8);
77
			$offset =+ 8;
78
79
			$res['guid'] = substr($entryId, $offset, 32);
80
			$offset += 32;
81
82
			$res['version'] = substr($entryId, $offset, 8);
83
			$offset += 8;
84
85
			$res['type'] = substr($entryId, $offset, 8);
86
			$offset += 8;
87
88
			$res['uniqueId'] = substr($entryId, $offset, 32);
89
			$offset += 32;
90
91
			$res['server'] = substr($entryId, $offset);
92
93
			$res['min_length'] = 88;
94
			$res['name'] = 'EID';
95
96
			return $res;
97
		}
98
99
		// The entryid from the begin of zarafa till 5.20
100
		private function getEID_V0Version($entryid)
101
		{
102
			// always make entryids in uppercase so comparison will be case insensitive
103
			$entryId = strtoupper($entryid);
104
105
			$res = array(
106
				'abFlags'	=> '',		// BYTE[4],   4 bytes,  8 hex characters
107
				'guid'		=> '',		// GUID,     16 bytes, 32 hex characters
108
				'version'	=> '',		// ULONG,     4 bytes,  8 hex characters
109
				'type'		=> '',		// ULONG,     4 bytes,  8 hex characters
110
				'id'		=> '',		// ULONG,     4 bytes,  8 hex characters
111
				'server'	=> '',		// CHAR,     variable length
112
				'padding'	=> '',		// TCHAR[3],  4 bytes,  8 hex characters (upto 4 bytes)
113
			);
114
115
			$res['length'] = strlen($entryId);
116
			$offset = 0;
117
118
			// First determine padding, and remove if from the entryId
119
			$res['padding'] = $this->getPadding($entryId);
120
			$entryId = substr($entryId, 0, strlen($entryId) - strlen($res['padding']));
121
122
			$res['abFlags'] = substr($entryId, $offset, 8);
123
			$offset =+ 8;
124
125
			$res['guid'] = substr($entryId, $offset, 32);
126
			$offset += 32;
127
128
			$res['version'] = substr($entryId, $offset, 8);
129
			$offset += 8;
130
131
			$res['type'] = substr($entryId, $offset, 8);
132
			$offset += 8;
133
134
			$res['id'] = substr($entryId, $offset, 8);
135
			$offset += 8;
136
137
			$res['server'] = substr($entryId, $offset);
138
139
			$res['min_length'] = 64;
140
			$res['name'] = 'EID_V0';
141
142
			return $res;
143
		}
144
145
		// wrapped store entryid
146
		private function getWrappedSEID($storeEntryId)
147
		{
148
			$res = array();
149
150
			$res['name'] = 'WrappedSEID';
151
			$res['length'] = strlen($storeEntryId);
152
153
			// always make entryids in uppercase so comparison will be case insensitive
154
			$storeEntryId = strtoupper($storeEntryId);
155
156
			$offset = 0;
157
158
			$res['flags'] = substr($storeEntryId, $offset, 8);
159
			$offset += 8;
160
161
			$res['providerUID'] = substr($storeEntryId, $offset, 32);
162
			$offset += 32;
163
164
			$res['version'] = substr($storeEntryId, $offset, 2);
165
			$offset += 2;
166
167
			$res['type'] = substr($storeEntryId, $offset, 2);
168
			$offset += 2;
169
170
			// find length of dll name, find null character which indicates end of dll name after the current offset
171
			$termCharIndex = strpos(substr($storeEntryId, $offset), '00');
172
			$res['DLLFileName'] = substr($storeEntryId, $offset, $termCharIndex);
173
			$offset += $termCharIndex;
174
175
			$res['terminationChar'] = substr($storeEntryId, $offset, 2);
176
			$offset += 2;
177
178
			$res['unWrappedEntryId'] = substr($storeEntryId, $offset);
179
180
			// unwrapped entryid is actually an object entryid so decompose it
181
			$res['unWrappedEntryId'] = $this->createEntryIdObj($res['unWrappedEntryId']);
182
183
			return $res;
184
		}
185
186
		// Addressbook Entryid
187
		private function getABEIDVersion($entryId)
188
		{
189
			// always make entryids in uppercase so comparison will be case insensitive
190
			$entryId = strtoupper($entryId);
191
192
			$res = array(
193
				'abFlags'	=> '',		// BYTE[4],   4 bytes,  8 hex characters
194
				'guid'		=> '',		// GUID,     16 bytes, 32 hex characters
195
				'version'	=> '',		// ULONG,     4 bytes,  8 hex characters
196
				'type'		=> '',		// ULONG,     4 bytes,  8 hex characters
197
				'id'		=> '',		// ULONG,    16 bytes,  32 hex characters
198
				'extid'		=> '',		// CHAR,     variable length
199
				'padding'	=> '',		// TCHAR[3],  4 bytes,  8 hex characters (upto 4 bytes)
200
			);
201
202
			$res['length'] = strlen($entryId);
203
			$offset = 0;
204
205
			// First determine padding, and remove if from the entryId
206
			$res['padding'] = $this->getPadding($entryId);
207
			$entryId = substr($entryId, 0, strlen($entryId) - strlen($res['padding']));
208
209
			$res['abFlags'] = substr($entryId, $offset, 8);
210
			$offset =+ 8;
211
212
			$res['guid'] = substr($entryId, $offset, 32);
213
			$offset += 32;
214
215
			$res['version'] = substr($entryId, $offset, 8);
216
			$offset += 8;
217
218
			$res['type'] = substr($entryId, $offset, 8);
219
			$offset += 8;
220
221
			$res['id'] = substr($entryId, $offset, 8);
222
			$offset += 8;
223
224
			$res['extid'] = substr($entryId, $offset);
225
226
			$res['min_length'] = 88;
227
			$res['name'] = 'ABEID';
228
229
			return $res;
230
		}
231
232
		/**
233
		 * Creates an object that has split up all the components of an entryID.
234
		 * @param {String} entryid Entryid
235
		 * @return {Object} EntryID object
0 ignored issues
show
Documentation Bug introduced by
The doc comment {Object} at position 0 could not be parsed: Unknown type name '{' at position 0 in {Object}.
Loading history...
236
		 */
237
		private function createEntryIdObj($entryid)
238
		{
239
			// check if we are dealing with old or new object entryids
240
			$versionString = substr($entryid, 40, 8);
241
242
			if($versionString == '00000000') {
243
				// use EID_V0 struct
244
				$eidObj = $this->getEID_V0Version($entryid);
245
			} else {
246
				// use EID struct
247
				$eidObj = $this->getEIDVersion($entryid);
248
			}
249
250
			return $eidObj;
251
		}
252
253
		/**
254
		 * Compares two entryIds. It is possible to have two different entryIds that should match as they
255
		 * represent the same object (in multiserver environments).
256
		 * @param {String} entryId1 EntryID
257
		 * @param {String} entryId2 EntryID
0 ignored issues
show
Bug introduced by
The type entryId2 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...
258
		 * @return {Boolean} Result of the comparison
0 ignored issues
show
Documentation Bug introduced by
The doc comment {Boolean} at position 0 could not be parsed: Unknown type name '{' at position 0 in {Boolean}.
Loading history...
259
		 */
260
		public function compareEntryIds($entryId1, $entryId2)
261
		{
262
			if(!is_string($entryId1) || !is_string($entryId2)) {
263
				return false;
264
			}
265
266
			if($entryId1 === $entryId2) {
267
				// if normal comparison succeeds then we can directly say that entryids are same
268
				return true;
269
			}
270
			return false;
271
		}
272
273
		/**
274
		 * Creates an object that has split up all the components of a store entryid.
275
		 * @param {String} storeEntryId unwrapped store entryid.
0 ignored issues
show
Bug introduced by
The type storeEntryId 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...
276
		 * @return {Object} store entryid object.
0 ignored issues
show
Documentation Bug introduced by
The doc comment {Object} at position 0 could not be parsed: Unknown type name '{' at position 0 in {Object}.
Loading history...
277
		 */
278
		private function createStoreEntryIdObj($storeEntryId)
0 ignored issues
show
Unused Code introduced by
The method createStoreEntryIdObj() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
279
		{
280
			return $this->getWrappedSEID($storeEntryId);
281
		}
282
283
		/**
284
		 * Compares two entryIds. It is possible to have two different entryIds that should match as they
285
		 * represent the same object (in multiserver environments).
286
		 * @param {String} storeEntryId1 store entryid
287
		 * @param {String} storeEntryId2 store entryid
0 ignored issues
show
Bug introduced by
The type storeEntryId2 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...
288
		 * @return {Boolean} Result of the comparison
0 ignored issues
show
Documentation Bug introduced by
The doc comment {Boolean} at position 0 could not be parsed: Unknown type name '{' at position 0 in {Boolean}.
Loading history...
289
		 */
290
		public function compareStoreEntryIds($storeEntryId1, $storeEntryId2)
291
		{
292
			if(!is_string($storeEntryId1) || !is_string($storeEntryId2)) {
293
				return false;
294
			}
295
296
			if($storeEntryId1 === $storeEntryId2) {
297
				// if normal comparison succeeds then we can directly say that entryids are same
298
				return true;
299
			}
300
			return false;
301
		}
302
303
		/**
304
		 * Creates an object that has split up all the components of an addressbook entryid.
305
		 * @param {String} abEntryId unwrapped addressbook entryid.
0 ignored issues
show
Bug introduced by
The type abEntryId 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...
306
		 * @return {Object} addresbook entryid object.
0 ignored issues
show
Documentation Bug introduced by
The doc comment {Object} at position 0 could not be parsed: Unknown type name '{' at position 0 in {Object}.
Loading history...
307
		 */
308
		public function createABEntryIdObj($abEntryId)
309
		{
310
			return $this->getABEIDVersion($abEntryId);
311
		}
312
313
		/**
314
		 * Creates an object that has wrapped a normal entryid using the AddressBook Provider GUID
315
		 * @param {String} entryId unwrapped entryid.
316
		 * @param {Number} objType The ObjectType which represents the object
0 ignored issues
show
Bug introduced by
The type objType 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...
317
		 * @return {String} wrapped addresbook entryid object.
0 ignored issues
show
Documentation Bug introduced by
The doc comment {String} at position 0 could not be parsed: Unknown type name '{' at position 0 in {String}.
Loading history...
318
		 */
319
		public function wrapABEntryIdObj($entryId, $objType)
320
		{
321
			$objType = dechex($objType);
322
323
			// add padding for the type, which is of 4 bytes (8 characters)
324
			$objType = str_pad($objType, 2, '0', STR_PAD_LEFT);
325
			$objType = str_pad($objType, 8, '0', STR_PAD_RIGHT);
326
327
			return '00000000' . self::MUIDZCSAB . $objType . '00000000' . $entryId;
328
		}
329
330
		/**
331
		 * Unwrap a Address Book Provider Entryid to a normal entryid
332
		 * @param {String} abEntryId wrapped entryid
333
		 * @return {Object} unwrapped entryid
0 ignored issues
show
Documentation Bug introduced by
The doc comment {Object} at position 0 could not be parsed: Unknown type name '{' at position 0 in {Object}.
Loading history...
334
		 */
335
		public function unwrapABEntryIdObj($abEntryId)
336
		{
337
			// Remove ulVersion (8 char), muid (32 char), ulObjType (8 char) and ulOffset (8 char)
338
			return substr($abEntryId, 56);
339
		}
340
341
		/**
342
		 * Compares two entryIds. It is possible to have two different entryIds that should match as they
343
		 * represent the same object (in multiserver environments).
344
		 * @param {String} entryId1 EntryID
345
		 * @param {String} entryId2 EntryID
346
		 * @return {Boolean} Result of the comparison
0 ignored issues
show
Documentation Bug introduced by
The doc comment {Boolean} at position 0 could not be parsed: Unknown type name '{' at position 0 in {Boolean}.
Loading history...
347
		 */
348
		public function compareABEntryIds($entryId1, $entryId2)
349
		{
350
			if(!is_string($entryId1) || !is_string($entryId2)) {
351
				return false;
352
			}
353
354
			if($entryId1 === $entryId2) {
355
				// if normal comparison succeeds then we can directly say that entryids are same
356
				return true;
357
			}
358
			return false;
359
		}
360
361
		/**
362
		 * Checks if the passed folder entryid is a folder in the favorites folder, favorites folder
363
		 * contains 0x01 in the abFlags[3] flag.
364
		 * @param {String} entryId folder entryid
365
		 * @return {Boolean} true of folder is a favorite folder else false
0 ignored issues
show
Documentation Bug introduced by
The doc comment {Boolean} at position 0 could not be parsed: Unknown type name '{' at position 0 in {Boolean}.
Loading history...
366
		 */
367
		public function isFavoriteFolder($entryId)
368
		{
369
			$entryIdObj = $this->createEntryIdObj($entryId);
370
371
			return (substr($entryIdObj['abFlags'], 6, 8) == self::ZARAFA_FAVORITE);
372
		}
373
374
		/**
375
		 * Checks if the given entryid is a oneoff entryid.
376
		 * @param {String} entryId The entryid
377
		 * @return {Boolean} true if the entryid is a oneoff
0 ignored issues
show
Documentation Bug introduced by
The doc comment {Boolean} at position 0 could not be parsed: Unknown type name '{' at position 0 in {Boolean}.
Loading history...
378
		 */
379
		public function isOneOffEntryId($entryId)
380
		{
381
			$entryIdObj = $this->createEntryIdObj($entryId);
382
383
			return $entryIdObj['guid'] == self::MAPI_ONE_OFF_UID;
384
		}
385
386
		/**
387
		 * Checks if the passed folder entryid is root favorites folder.
388
		 * @param {String} entryId folder entryid
389
		 * @return {Boolean} true of folder is a root favorite folder else false
0 ignored issues
show
Documentation Bug introduced by
The doc comment {Boolean} at position 0 could not be parsed: Unknown type name '{' at position 0 in {Boolean}.
Loading history...
390
		 */
391
		public function isFavoriteRootFolder($entryId)
392
		{
393
			$entryIdObj = $this->createEntryIdObj($entryId);
394
395
			return $entryIdObj['uniqueId'] == self::STATIC_GUID_FAVORITE;
396
		}
397
398
		/**
399
		 * Checks if the passed folder entryid is root public folder.
400
		 * @param {String} entryId folder entryid
401
		 * @return {Boolean} true of folder is a root public folder else false
0 ignored issues
show
Documentation Bug introduced by
The doc comment {Boolean} at position 0 could not be parsed: Unknown type name '{' at position 0 in {Boolean}.
Loading history...
402
		 */
403
		public function isPublicRootFolder($entryId)
404
		{
405
			$entryIdObj = $this->createEntryIdObj($entryId);
406
407
			return $entryIdObj['uniqueId'] == self::STATIC_GUID_PUBLICFOLDER;
408
		}
409
410
		/**
411
		 * Checks if the passed folder entryid is public subtree folder.
412
		 * @param {String} entryId folder entryid
413
		 * @return {Boolean} true of folder is a root public folder else false
0 ignored issues
show
Documentation Bug introduced by
The doc comment {Boolean} at position 0 could not be parsed: Unknown type name '{' at position 0 in {Boolean}.
Loading history...
414
		 */
415
		public function isPublicSubtreeFolder($entryId)
416
		{
417
			$entryIdObj = $this->createEntryIdObj($entryId);
418
419
			return $entryIdObj['uniqueId'] == self::STATIC_GUID_FAVSUBTREE;
420
		}
421
422
		/**
423
		 * Checks if the given entryid
424
		 * @param {String} entryId Addressbook entryid
425
		 *
426
		 */
427
		public function hasContactProviderGUID($entryId)
428
		{
429
			$entryIdObj = $this->createABEntryIdObj($entryId);
430
431
			return $entryIdObj['guid'] == self::MUIDZCSAB;
432
		}
433
434
		/**
435
		 * Checks if the GUID part of the entryid is of the Global Addressbook.
436
		 * @param {String} $entryId Address Book entryid
0 ignored issues
show
Documentation Bug introduced by
The doc comment {String} at position 0 could not be parsed: Unknown type name '{' at position 0 in {String}.
Loading history...
437
		 * @return {Boolean} true if guid matches the Global Addressbook else false
0 ignored issues
show
Documentation Bug introduced by
The doc comment {Boolean} at position 0 could not be parsed: Unknown type name '{' at position 0 in {Boolean}.
Loading history...
438
		 */
439
		public function hasAddressBookGUID($entryId)
440
		{
441
			$entryIdObj = $this->createABEntryIdObj($entryId);
442
443
			return $entryIdObj['guid'] == self::MUIDECSAB;
444
		}
445
446
		/**
447
		 * Checks if the GUID part of the entryid is of the Address book recipient.
448
		 * @param {String} $entryId Address Book entryid
0 ignored issues
show
Documentation Bug introduced by
The doc comment {String} at position 0 could not be parsed: Unknown type name '{' at position 0 in {String}.
Loading history...
449
		 * @return {Boolean} true if guid matches the Ab recipient else false
0 ignored issues
show
Documentation Bug introduced by
The doc comment {Boolean} at position 0 could not be parsed: Unknown type name '{' at position 0 in {Boolean}.
Loading history...
450
		 */
451
		public function hasAddressBookRecipientGUID($entryId)
452
		{
453
			$entryIdObj = $this->createABEntryIdObj($entryId);
454
455
			return $entryIdObj['guid'] == self::MUIDEMSAB;
456
		}
457
458
		/**
459
		 * Checks if the GUID part of the entryid is of the Global Addressbook Container.
460
		 * @param {String} $entryId Address Book entryid
0 ignored issues
show
Documentation Bug introduced by
The doc comment {String} at position 0 could not be parsed: Unknown type name '{' at position 0 in {String}.
Loading history...
461
		 * @return {Boolean} true if guid matches the Global Addressbook Container else false
0 ignored issues
show
Documentation Bug introduced by
The doc comment {Boolean} at position 0 could not be parsed: Unknown type name '{' at position 0 in {Boolean}.
Loading history...
462
		 */
463
		public function isGlobalAddressbookContainer($entryId)
464
		{
465
			// check for global addressbook entryid
466
			if($this->hasAddressBookGUID($entryId) === false) {
467
				return false;
468
			}
469
470
			$entryIdObj = $this->createABEntryIdObj($entryId);
471
472
			// check for object_type == MAPI_ABCONT and id == 1
473
			return ($entryIdObj['type'] == '04000000' && $entryIdObj['id'] == self::ZARAFA_UID_GLOBAL_ADDRESS_BOOK);
474
		}
475
476
		/**
477
		 * Creates an object that has split up all the components of an message store entryid.
478
		 * @param {String} $entryId message store entryid
0 ignored issues
show
Documentation Bug introduced by
The doc comment {String} at position 0 could not be parsed: Unknown type name '{' at position 0 in {String}.
Loading history...
479
		 * @return {Object} message store entryid object
0 ignored issues
show
Documentation Bug introduced by
The doc comment {Object} at position 0 could not be parsed: Unknown type name '{' at position 0 in {Object}.
Loading history...
480
		 */
481
		public function createMsgStoreEntryIdObj($entryId) {
482
			$res = array(
483
				'Flags' => '',
484
				'ProviderUID' => '',
485
				'Version' => '',
486
				'Flag' => '',
487
				'DLLFileName' => '',
488
				'WrappedFlags' => '',
489
				'WrappedProviderUID' => '',
490
				'WrappedType' => '',
491
				'ServerShortname' => '',
492
				'MailboxDN' => '',
493
				'V2' => array(
494
					'Magic' => '',
495
					'Size' => '',
496
					'Version' => '',
497
					'OffsetDN' => '',
498
					'OffsetFQDN' => '',
499
					'ServerDN' => '',
500
					'ServerFQDN' => '',
501
					'ReservedBlock' => ''
502
				),
503
				'V3' => array(
504
					'Magic' => '',
505
					'Size' => '',
506
					'Version' => '',
507
					'OffsetSmtpAddress' => '',
508
					'SmtpAddress' => '',
509
				)
510
			);
511
512
			if (!$entryId) {
513
				return $res;
514
			}
515
516
			$offset = 0;
517
			if (!$this->getAndCheckComponents($entryId, $offset, 4, 0x0, $res, 'Flags')) {
518
				return $res;
519
			};
520
			$offset += 4;
521
522
			if (!$this->getAndCheckComponents($entryId, $offset, 16, MUID_STORE_WRAP_GUID, $res, 'ProviderUID')) {
523
				return $res;
524
			};
525
			$offset += 16;
526
527
			if (!$this->getAndCheckComponents($entryId, $offset, 1, 0x0, $res, 'Version')) {
528
				return $res;
529
			};
530
			$offset += 1;
531
532
			if (!$this->getAndCheckComponents($entryId, $offset, 1, 0x0, $res, 'Flag')) {
533
				return $res;
534
			};
535
			$offset += 1;
536
537
			if (!$this->getAndCheckComponents($entryId, $offset, 10, 'emsmdb.dll', $res, 'DLLFileName')) {
538
				return $res;
539
			};
540
			$offset += 14;
541
542
			if (!$this->getAndCheckComponents($entryId, $offset, 4, 0x0, $res, 'WrappedFlags')) {
543
				return $res;
544
			};
545
			$offset += 4;
546
547
			if (!$this->getAndCheckComponents($entryId, $offset, 16, array(MUID_STORE_PRIVATE_GUID, MUID_STORE_PUBLIC_GUID), $res, 'WrappedProviderUID')) {
548
				return $res;
549
			};
550
			$offset += 16;
551
552
			if (!$this->getAndCheckComponents($entryId, $offset, 4, array_map('hex2bin', array('0C000000', '06000000')), $res, 'WrappedType')) {
553
				return $res;
554
			};
555
			$offset += 4;
556
557
			$zeroBytePos = strpos($entryId, "\0", $offset);
558
			if ($zeroBytePos !== false) {
559
				$res['ServerShortname'] = trim(substr($entryId, $offset, $zeroBytePos - $offset));
560
				$offset = $zeroBytePos + 1;
561
			}
562
563
			$zeroBytePos = strpos($entryId, "\0", $offset);
564
			if ($zeroBytePos !== false) {
565
				$res['MailboxDN'] = trim(substr($entryId, $offset, $zeroBytePos - $offset));
566
				$offset = $zeroBytePos + 1;
0 ignored issues
show
Unused Code introduced by
The assignment to $offset is dead and can be removed.
Loading history...
567
			}
568
569
			// TODO V2 and V3 structs
570
571
			return $res;
572
		}
573
574
		/**
575
		 * Reads $len bytes beginning from $start of the $entryid,
576
		 * checks if the value of resulting string is expected and adds it
577
		 * to $res object in such case.
578
		 * @param {String} $entryId message store entryid
0 ignored issues
show
Documentation Bug introduced by
The doc comment {String} at position 0 could not be parsed: Unknown type name '{' at position 0 in {String}.
Loading history...
579
		 * @param {int} $start start position of the value to get
580
		 * @param {int} $len length in bytes of the value to get
581
		 * @param {Object} $checkValue value to check against
582
		 * @param {Object} $res message store entryid object
583
		 * @param {String} $key component name
584
		 * @return {Boolean} true if the component has the expected value, false otherwise.
0 ignored issues
show
Documentation Bug introduced by
The doc comment {Boolean} at position 0 could not be parsed: Unknown type name '{' at position 0 in {Boolean}.
Loading history...
585
		 */
586
		private function getAndCheckComponents($entryId, $start, $len, $checkValue, &$res, $key) {
587
			$val = substr($entryId, $start, $len);
588
			if (is_array($checkValue)) {
589
				 if (!in_array($val, $checkValue)) {
590
					error_log(sprintf("Unexpected value in store entryid for user %s. Entryid: %s key: '%s' value: '%s' expected: %s",
591
						$GLOBALS["mapisession"]->getUserName(), bin2hex($entryId), $key, $val, print_r(array_map('bin2hex', $checkValue), 1)));
0 ignored issues
show
Bug introduced by
It seems like print_r(array_map('bin2hex', $checkValue), 1) can also be of type true; however, parameter $values of sprintf() does only seem to accept double|integer|string, 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

591
						$GLOBALS["mapisession"]->getUserName(), bin2hex($entryId), $key, $val, /** @scrutinizer ignore-type */ print_r(array_map('bin2hex', $checkValue), 1)));
Loading history...
592
					return false;
593
				 }
594
			}
595
			elseif ($checkValue !== null && $val != $checkValue) {
596
				$user = $GLOBALS["mapisession"] !== null ? $GLOBALS["mapisession"]->getUserName() :
597
				        "<mapisession not yet initialized>";
598
				error_log(sprintf("Unexpected value in store entryid for user %s. Entryid: %s key: '%s' value: '%s' expected: %s",
599
				          $user, bin2hex($entryId), $key, $val, $checkValue));
600
				return false;
601
			}
602
603
			$res[$key] = $val;
604
			return true;
605
		}
606
607
		/**
608
		 * Creates an object that has split up all the components of a message entryid.
609
		 * @param {String} $entryId message entryid
0 ignored issues
show
Documentation Bug introduced by
The doc comment {String} at position 0 could not be parsed: Unknown type name '{' at position 0 in {String}.
Loading history...
610
		 * @return {Object} message entryid object
0 ignored issues
show
Documentation Bug introduced by
The doc comment {Object} at position 0 could not be parsed: Unknown type name '{' at position 0 in {Object}.
Loading history...
611
		 */
612
		public function createMessageEntryIdObj($entryId)
613
		{
614
			// always make entryids in uppercase so comparison will be case insensitive
615
			$entryId = strtoupper($entryId);
616
617
			$res = array(
618
				'providerguid' => '',			// GUID,     16 bytes, 32 hex characters
619
				'messagetype' => '',			// UINT,      2 bytes,  4 hex characters
620
				'folderdbguid' => '',			// GUID,     16 bytes, 32 hex characters
621
				'foldercounter'	=> '',		// ULONG,     6 bytes, 12 hex characters
622
				'padding'	=> '',					// TCHAR[3],  2 bytes,  4 hex characters
623
				'messagedbguid' => '',		// GUID,     16 bytes, 32 hex characters
624
				'messagecounter'	=> '',	// ULONG,     6 bytes, 12 hex characters
625
			);
626
627
			if (!$entryId) {
628
				return $res;
629
			}
630
631
			$res['length'] = strlen($entryId);
632
			$offset = 0;
633
634
			$res['providerguid'] = substr($entryId, $offset, 32);
635
			$offset += 32;
636
637
			$res['messagetype'] = substr($entryId, $offset, 4);
638
			$offset += 4;
639
640
			$res['folderdbguid'] = substr($entryId, $offset, 32);
641
			$offset += 32;
642
643
			$res['foldercounter'] = substr($entryId, $offset, 12);
644
			$offset += 12;
645
646
			$res['padding'] = substr($entryId, $offset, 4);
647
			$offset += 4;
648
649
			$res['messagedbguid'] = substr($entryId, $offset, 32);
650
			$offset += 32;
651
652
			$res['messagecounter'] = substr($entryId, $offset, 12);
653
			$offset += 12;
654
655
			return $res;
656
		}
657
658
		/**
659
		 * Creates a folder entryid with provided parameters.
660
		 * @param $providerguid {String} provider guid
0 ignored issues
show
Documentation Bug introduced by
The doc comment {String} at position 0 could not be parsed: Unknown type name '{' at position 0 in {String}.
Loading history...
661
		 * @param $foldertype {int} folder type flag
662
		 * @param $folderdbguid {String} folder db guid
663
		 * @param $foldercounter {String} folder counter
664
		 * @return {String} folder entryid
0 ignored issues
show
Documentation Bug introduced by
The doc comment {String} at position 0 could not be parsed: Unknown type name '{' at position 0 in {String}.
Loading history...
665
		 */
666
		public function createFolderEntryId($providerguid, $foldertype, $folderdbguid, $foldercounter)
667
		{
668
			return strtoupper('00000000' . $providerguid . $foldertype . $folderdbguid . $foldercounter . '0000');
669
		}
670
671
		/**
672
		 * Creates an object that has split up all the components of a folder entryid.
673
		 * @param {String} $entryId folder entryid
0 ignored issues
show
Documentation Bug introduced by
The doc comment {String} at position 0 could not be parsed: Unknown type name '{' at position 0 in {String}.
Loading history...
674
		 * @return {Object} folder entryid object
0 ignored issues
show
Documentation Bug introduced by
The doc comment {Object} at position 0 could not be parsed: Unknown type name '{' at position 0 in {Object}.
Loading history...
675
		 */
676
		public function createFolderEntryIdObj($entryId)
677
		{
678
			// always make entryids in uppercase so comparison will be case insensitive
679
			$entryId = strtoupper($entryId);
680
681
			$res = array(
682
				'abflags'	=> '',					// BYTE[4],   4 bytes,  8 hex characters
683
				'providerguid' => '',			// GUID,     16 bytes, 32 hex characters
684
				'foldertype' => '',				// UINT,      2 bytes,  4 hex characters
685
				'folderdbguid' => '',			// GUID,     16 bytes, 32 hex characters
686
				'foldercounter'	=> '',		// ULONG,     6 bytes, 12 hex characters
687
				'padding'	=> '',					// TCHAR[3],  2 bytes,  4 hex characters
688
			);
689
690
			if (!$entryId) {
691
				return $res;
692
			}
693
694
			$res['length'] = strlen($entryId);
695
			$offset = 0;
696
697
			$res['abflags'] = substr($entryId, $offset, 8);
698
			$offset += 8;
699
700
			$res['providerguid'] = substr($entryId, $offset, 32);
701
			$offset += 32;
702
703
			$res['foldertype'] = substr($entryId, $offset, 4);
704
			$offset += 4;
705
706
			$res['folderdbguid'] = substr($entryId, $offset, 32);
707
			$offset += 32;
708
709
			$res['foldercounter'] = substr($entryId, $offset, 12);
710
			$offset += 12;
711
712
			$res['padding'] = substr($entryId, $offset, 4);
713
			$offset += 4;
714
715
			return $res;
716
		}
717
	}
718
719
	// Create global entryId object
720
	$GLOBALS["entryid"] = new EntryId();
721
?>
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...
722