Passed
Push — master ( 8dcc68...34e8da )
by
unknown
23:44 queued 20:40
created

MAPIUtils::IsInCalendarSyncInterval()   C

Complexity

Conditions 14
Paths 2

Size

Total Lines 39
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 14
eloc 18
nc 2
nop 3
dl 0
loc 39
rs 6.2666
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
/*
3
 * SPDX-License-Identifier: AGPL-3.0-only
4
 * SPDX-FileCopyrightText: Copyright 2007-2013,2016 Zarafa Deutschland GmbH
5
 * SPDX-FileCopyrightText: Copyright 2020-2022 grommunio GmbH
6
 */
7
8
/**
9
 *
10
 * MAPI to AS mapping class
11
 *
12
 *
13
 */
14
class MAPIUtils {
15
16
    /**
17
     * Create a MAPI restriction to use within an email folder which will
18
     * return all messages since since $timestamp
19
     *
20
     * @param long       $timestamp     Timestamp since when to include messages
0 ignored issues
show
Bug introduced by
The type long 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...
21
     *
22
     * @access public
23
     * @return array
24
     */
25
    public static function GetEmailRestriction($timestamp) {
26
        // ATTENTION: ON CHANGING THIS RESTRICTION, MAPIUtils::IsInEmailSyncInterval() also needs to be changed
27
        $restriction = array ( RES_PROPERTY,
28
                          array (   RELOP => RELOP_GE,
29
                                    ULPROPTAG => PR_MESSAGE_DELIVERY_TIME,
30
                                    VALUE => $timestamp
31
                          )
32
                      );
33
34
        return $restriction;
35
    }
36
37
38
    /**
39
     * Create a MAPI restriction to use in the calendar which will
40
     * return all future calendar items, plus those since $timestamp
41
     *
42
     * @param MAPIStore  $store         the MAPI store
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...
43
     * @param long       $timestamp     Timestamp since when to include messages
44
     *
45
     * @access public
46
     * @return array
47
     */
48
    //TODO getting named properties
49
    public static function GetCalendarRestriction($store, $timestamp) {
50
        // This is our viewing window
51
        $start = $timestamp;
52
        $end = 0x7fffffff; // infinite end
53
54
        $props = MAPIMapping::GetAppointmentProperties();
55
        $props = getPropIdsFromStrings($store, $props);
56
57
        // ATTENTION: ON CHANGING THIS RESTRICTION, MAPIUtils::IsInCalendarSyncInterval() also needs to be changed
58
        $restriction = Array(RES_OR,
59
             Array(
60
                   // OR
61
                   // item.end > window.start && item.start < window.end
62
                   Array(RES_AND,
63
                         Array(
64
                               Array(RES_PROPERTY,
65
                                     Array(RELOP => RELOP_LE,
66
                                           ULPROPTAG => $props["starttime"],
67
                                           VALUE => $end
68
                                           )
69
                                     ),
70
                               Array(RES_PROPERTY,
71
                                     Array(RELOP => RELOP_GE,
72
                                           ULPROPTAG => $props["endtime"],
73
                                           VALUE => $start
74
                                           )
75
                                     )
76
                               )
77
                         ),
78
                   // OR
79
                   Array(RES_OR,
80
                         Array(
81
                               // OR
82
                               // (EXIST(recurrence_enddate_property) && item[isRecurring] == true && recurrence_enddate_property >= start)
83
                               Array(RES_AND,
84
                                     Array(
85
                                           Array(RES_EXIST,
86
                                                 Array(ULPROPTAG => $props["recurrenceend"],
87
                                                       )
88
                                                 ),
89
                                           Array(RES_PROPERTY,
90
                                                 Array(RELOP => RELOP_EQ,
91
                                                       ULPROPTAG => $props["isrecurring"],
92
                                                       VALUE => true
93
                                                       )
94
                                                 ),
95
                                           Array(RES_PROPERTY,
96
                                                 Array(RELOP => RELOP_GE,
97
                                                       ULPROPTAG => $props["recurrenceend"],
98
                                                       VALUE => $start
99
                                                       )
100
                                                 )
101
                                           )
102
                                     ),
103
                               // OR
104
                               // (!EXIST(recurrence_enddate_property) && item[isRecurring] == true && item[start] <= end)
105
                               Array(RES_AND,
106
                                     Array(
107
                                           Array(RES_NOT,
108
                                                 Array(
109
                                                       Array(RES_EXIST,
110
                                                             Array(ULPROPTAG => $props["recurrenceend"]
111
                                                                   )
112
                                                             )
113
                                                       )
114
                                                 ),
115
                                           Array(RES_PROPERTY,
116
                                                 Array(RELOP => RELOP_LE,
117
                                                       ULPROPTAG => $props["starttime"],
118
                                                       VALUE => $end
119
                                                       )
120
                                                 ),
121
                                           Array(RES_PROPERTY,
122
                                                 Array(RELOP => RELOP_EQ,
123
                                                       ULPROPTAG => $props["isrecurring"],
124
                                                       VALUE => true
125
                                                       )
126
                                                 )
127
                                           )
128
                                     )
129
                               )
130
                         ) // EXISTS OR
131
                   )
132
             );        // global OR
133
134
        return $restriction;
135
    }
136
137
138
    /**
139
     * Create a MAPI restriction in order to check if a contact has a picture
140
     *
141
     * @access public
142
     * @return array
143
     */
144
    public static function GetContactPicRestriction() {
145
        return array ( RES_PROPERTY,
146
                        array (
147
                            RELOP => RELOP_EQ,
148
                            ULPROPTAG => mapi_prop_tag(PT_BOOLEAN, 0x7FFF),
1 ignored issue
show
Bug introduced by
The function mapi_prop_tag was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

148
                            ULPROPTAG => /** @scrutinizer ignore-call */ mapi_prop_tag(PT_BOOLEAN, 0x7FFF),
Loading history...
149
                            VALUE => true
150
                        )
151
        );
152
    }
153
154
155
    /**
156
     * Create a MAPI restriction for search
157
     *
158
     * @access public
159
     *
160
     * @param string $query
161
     * @return array
162
     */
163
    public static function GetSearchRestriction($query) {
164
        return array(RES_AND,
165
                    array(
166
                        array(RES_OR,
167
                            array(
168
                                array(RES_CONTENT, array(FUZZYLEVEL => FL_SUBSTRING | FL_IGNORECASE, ULPROPTAG => PR_DISPLAY_NAME, VALUE => $query)),
169
                                array(RES_CONTENT, array(FUZZYLEVEL => FL_SUBSTRING | FL_IGNORECASE, ULPROPTAG => PR_ACCOUNT, VALUE => $query)),
170
                                array(RES_CONTENT, array(FUZZYLEVEL => FL_SUBSTRING | FL_IGNORECASE, ULPROPTAG => PR_SMTP_ADDRESS, VALUE => $query)),
171
                            ), // RES_OR
172
                        ),
173
                        array(RES_OR,
174
                            array (
175
                                array(
176
                                        RES_PROPERTY,
177
                                        array(RELOP => RELOP_EQ, ULPROPTAG => PR_OBJECT_TYPE, VALUE => MAPI_MAILUSER)
178
                                ),
179
                                array(
180
                                        RES_PROPERTY,
181
                                        array(RELOP => RELOP_EQ, ULPROPTAG => PR_OBJECT_TYPE, VALUE => MAPI_DISTLIST)
182
                                )
183
                            )
184
                        ) // RES_OR
185
                    ) // RES_AND
186
        );
187
    }
188
189
    /**
190
     * Create a MAPI restriction for a certain email address
191
     *
192
     * @access public
193
     *
194
     * @param MAPIStore  $store         the MAPI store
195
     * @param string     $query         email address
196
     *
197
     * @return array
198
     */
199
    public static function GetEmailAddressRestriction($store, $email) {
200
        $props = MAPIMapping::GetContactProperties();
201
        $props = getPropIdsFromStrings($store, $props);
202
203
        return array(RES_OR,
204
                    array(
205
                        array(  RES_PROPERTY,
206
                                array(  RELOP => RELOP_EQ,
207
                                        ULPROPTAG => $props['emailaddress1'],
208
                                        VALUE => array($props['emailaddress1'] => $email),
209
                                ),
210
                        ),
211
                        array(  RES_PROPERTY,
212
                                array(  RELOP => RELOP_EQ,
213
                                        ULPROPTAG => $props['emailaddress2'],
214
                                        VALUE => array($props['emailaddress2'] => $email),
215
                                ),
216
                        ),
217
                        array(  RES_PROPERTY,
218
                                array(  RELOP => RELOP_EQ,
219
                                        ULPROPTAG => $props['emailaddress3'],
220
                                        VALUE => array($props['emailaddress3'] => $email),
221
                                ),
222
                        ),
223
                ),
224
        );
225
    }
226
227
    /**
228
     * Create a MAPI restriction for a certain folder type
229
     *
230
     * @access public
231
     *
232
     * @param string     $foldertype    folder type for restriction
233
     * @return array
234
     */
235
    public static function GetFolderTypeRestriction($foldertype) {
236
        return array(   RES_PROPERTY,
237
                        array(  RELOP => RELOP_EQ,
238
                                ULPROPTAG => PR_CONTAINER_CLASS,
239
                                VALUE => array(PR_CONTAINER_CLASS => $foldertype)
240
                        ),
241
                );
242
    }
243
244
    /**
245
     * Returns subfolders of given type for a folder or false if there are none.
246
     *
247
     * @access public
248
     *
249
     * @param MAPIFolder $folder
0 ignored issues
show
Bug introduced by
The type MAPIFolder 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...
250
     * @param string $type
251
     *
252
     * @return MAPITable|boolean
0 ignored issues
show
Bug introduced by
The type MAPITable 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...
253
     */
254
    public static function GetSubfoldersForType($folder, $type) {
255
        $subfolders = mapi_folder_gethierarchytable($folder, CONVENIENT_DEPTH);
1 ignored issue
show
Bug introduced by
The function mapi_folder_gethierarchytable was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

255
        $subfolders = /** @scrutinizer ignore-call */ mapi_folder_gethierarchytable($folder, CONVENIENT_DEPTH);
Loading history...
256
        mapi_table_restrict($subfolders, MAPIUtils::GetFolderTypeRestriction($type));
1 ignored issue
show
Bug introduced by
The function mapi_table_restrict was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

256
        /** @scrutinizer ignore-call */ 
257
        mapi_table_restrict($subfolders, MAPIUtils::GetFolderTypeRestriction($type));
Loading history...
257
        if (mapi_table_getrowcount($subfolders) > 0) {
1 ignored issue
show
Bug introduced by
The function mapi_table_getrowcount was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

257
        if (/** @scrutinizer ignore-call */ mapi_table_getrowcount($subfolders) > 0) {
Loading history...
258
            return mapi_table_queryallrows($subfolders, array(PR_ENTRYID));
1 ignored issue
show
Bug introduced by
The function mapi_table_queryallrows was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

258
            return /** @scrutinizer ignore-call */ mapi_table_queryallrows($subfolders, array(PR_ENTRYID));
Loading history...
259
        }
260
        return false;
261
    }
262
263
    /**
264
     * Checks if mapimessage is inside the synchronization interval
265
     * also defined by MAPIUtils::GetEmailRestriction()
266
     *
267
     * @param MAPIStore       $store           mapi store
268
     * @param MAPIMessage     $mapimessage     the mapi message to be checked
0 ignored issues
show
Bug introduced by
The type MAPIMessage 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...
269
     * @param long            $timestamp       the lower time limit
270
     *
271
     * @access public
272
     * @return boolean
273
     */
274
    public static function IsInEmailSyncInterval($store, $mapimessage, $timestamp) {
275
        $p = mapi_getprops($mapimessage, array(PR_MESSAGE_DELIVERY_TIME));
1 ignored issue
show
Bug introduced by
The function mapi_getprops was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

275
        $p = /** @scrutinizer ignore-call */ mapi_getprops($mapimessage, array(PR_MESSAGE_DELIVERY_TIME));
Loading history...
276
277
        if (isset($p[PR_MESSAGE_DELIVERY_TIME]) && $p[PR_MESSAGE_DELIVERY_TIME] >= $timestamp) {
278
            ZLog::Write(LOGLEVEL_DEBUG, "MAPIUtils->IsInEmailSyncInterval: Message is in the synchronization interval");
279
            return true;
280
        }
281
282
        ZLog::Write(LOGLEVEL_WARN, "MAPIUtils->IsInEmailSyncInterval: Message is OUTSIDE the synchronization interval");
283
        return false;
284
    }
285
286
    /**
287
     * Checks if mapimessage is inside the synchronization interval
288
     * also defined by MAPIUtils::GetCalendarRestriction()
289
     *
290
     * @param MAPIStore       $store           mapi store
291
     * @param MAPIMessage     $mapimessage     the mapi message to be checked
292
     * @param long            $timestamp       the lower time limit
293
     *
294
     * @access public
295
     * @return boolean
296
     */
297
    public static function IsInCalendarSyncInterval($store, $mapimessage, $timestamp) {
298
        // This is our viewing window
299
        $start = $timestamp;
300
        $end = 0x7fffffff; // infinite end
301
302
        $props = MAPIMapping::GetAppointmentProperties();
303
        $props = getPropIdsFromStrings($store, $props);
304
305
        $p = mapi_getprops($mapimessage, array($props["starttime"], $props["endtime"], $props["recurrenceend"], $props["isrecurring"], $props["recurrenceend"]));
1 ignored issue
show
Bug introduced by
The function mapi_getprops was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

305
        $p = /** @scrutinizer ignore-call */ mapi_getprops($mapimessage, array($props["starttime"], $props["endtime"], $props["recurrenceend"], $props["isrecurring"], $props["recurrenceend"]));
Loading history...
306
307
        if (
308
                (
309
                    isset($p[$props["endtime"]]) && isset($p[$props["starttime"]]) &&
310
311
                    //item.end > window.start && item.start < window.end
312
                    $p[$props["endtime"]] > $start && $p[$props["starttime"]] < $end
313
                )
314
            ||
315
                (
316
                    isset($p[$props["isrecurring"]]) &&
317
318
                    //(EXIST(recurrence_enddate_property) && item[isRecurring] == true && recurrence_enddate_property >= start)
319
                    isset($p[$props["recurrenceend"]]) && $p[$props["isrecurring"]] == true && $p[$props["recurrenceend"]] >= $start
320
                )
321
            ||
322
                (
323
                    isset($p[$props["isrecurring"]]) && isset($p[$props["starttime"]]) &&
324
325
                    //(!EXIST(recurrence_enddate_property) && item[isRecurring] == true && item[start] <= end)
326
                    !isset($p[$props["recurrenceend"]]) && $p[$props["isrecurring"]] == true && $p[$props["starttime"]] <= $end
327
                )
328
           ) {
329
            ZLog::Write(LOGLEVEL_DEBUG, "MAPIUtils->IsInCalendarSyncInterval: Message is in the synchronization interval");
330
            return true;
331
        }
332
333
334
        ZLog::Write(LOGLEVEL_WARN, "MAPIUtils->IsInCalendarSyncInterval: Message is OUTSIDE the synchronization interval");
335
        return false;
336
    }
337
338
    /**
339
     * Checks if mapimessage is in a shared folder and private.
340
     *
341
     * @param string          $folderid        binary folderid of the message
342
     * @param MAPIMessage     $mapimessage     the mapi message to be checked
343
     *
344
     * @access public
345
     * @return boolean
346
     */
347
    public static function IsMessageSharedAndPrivate($folderid, $mapimessage) {
348
        $sensitivity = mapi_getprops($mapimessage, array(PR_SENSITIVITY));
1 ignored issue
show
Bug introduced by
The function mapi_getprops was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

348
        $sensitivity = /** @scrutinizer ignore-call */ mapi_getprops($mapimessage, array(PR_SENSITIVITY));
Loading history...
349
        if (isset($sensitivity[PR_SENSITIVITY]) && $sensitivity[PR_SENSITIVITY] >= SENSITIVITY_PRIVATE) {
350
            $hexFolderid = bin2hex($folderid);
351
            $shortId = ZPush::GetDeviceManager()->GetFolderIdForBackendId($hexFolderid);
352
            if (Utils::GetFolderOriginFromId($shortId) == DeviceManager::FLD_ORIGIN_IMPERSONATED) {
353
                ZLog::Write(LOGLEVEL_DEBUG, sprintf("MAPIUtils->IsMessageSharedAndPrivate(): Message is in impersonated store '%s' and marked as private", ZPush::GetBackend()->GetImpersonatedUser()));
354
                return true;
355
            }
356
            $sharedUser = ZPush::GetAdditionalSyncFolderStore($hexFolderid);
357
            if (Utils::GetFolderOriginFromId($shortId) != DeviceManager::FLD_ORIGIN_USER && $sharedUser != false && $sharedUser != 'SYSTEM') {
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing $sharedUser of type string to the boolean false. If you are specifically checking for a non-empty string, consider using the more explicit !== '' instead.
Loading history...
358
                ZLog::Write(LOGLEVEL_DEBUG, sprintf("MAPIUtils->IsMessageSharedAndPrivate(): Message is in shared store '%s' and marked as private", $sharedUser));
359
                return true;
360
            }
361
        }
362
        return false;
363
    }
364
365
    /**
366
     * Reads data of large properties from a stream
367
     *
368
     * @param MAPIMessage $message
369
     * @param long $prop
370
     *
371
     * @access public
372
     * @return string
373
     */
374
    public static function readPropStream($message, $prop) {
375
        $stream = mapi_openproperty($message, $prop, IID_IStream, 0, 0);
1 ignored issue
show
Bug introduced by
The function mapi_openproperty was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

375
        $stream = /** @scrutinizer ignore-call */ mapi_openproperty($message, $prop, IID_IStream, 0, 0);
Loading history...
376
        $ret = mapi_last_hresult();
1 ignored issue
show
Bug introduced by
The function mapi_last_hresult was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

376
        $ret = /** @scrutinizer ignore-call */ mapi_last_hresult();
Loading history...
377
        if ($ret == MAPI_E_NOT_FOUND) {
378
            ZLog::Write(LOGLEVEL_DEBUG, sprintf("MAPIUtils->readPropStream: property 0x%08X not found. It is either empty or not set. It will be ignored.", $prop));
379
            return "";
380
        }
381
        elseif ($ret) {
382
            ZLog::Write(LOGLEVEL_ERROR, "MAPIUtils->readPropStream error opening stream: 0x%08X", $ret);
383
            return "";
384
        }
385
        $data = "";
0 ignored issues
show
Unused Code introduced by
The assignment to $data is dead and can be removed.
Loading history...
386
        $string = "";
387
        while(1) {
388
            $data = mapi_stream_read($stream, 1024);
1 ignored issue
show
Bug introduced by
The function mapi_stream_read was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

388
            $data = /** @scrutinizer ignore-call */ mapi_stream_read($stream, 1024);
Loading history...
389
            if(strlen($data) == 0)
390
                break;
391
            $string .= $data;
392
        }
393
394
        return $string;
395
    }
396
397
398
    /**
399
     * Checks if a store supports properties containing unicode characters
400
     *
401
     * @param MAPIStore $store
402
     *
403
     * @access public
404
     * @return
405
     */
406
    public static function IsUnicodeStore($store) {
407
        $supportmask = mapi_getprops($store, array(PR_STORE_SUPPORT_MASK));
1 ignored issue
show
Bug introduced by
The function mapi_getprops was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

407
        $supportmask = /** @scrutinizer ignore-call */ mapi_getprops($store, array(PR_STORE_SUPPORT_MASK));
Loading history...
408
        if (isset($supportmask[PR_STORE_SUPPORT_MASK]) && ($supportmask[PR_STORE_SUPPORT_MASK] & STORE_UNICODE_OK)) {
409
            ZLog::Write(LOGLEVEL_DEBUG, "Store supports properties containing Unicode characters.");
410
            define('STORE_SUPPORTS_UNICODE', true);
411
            define('STORE_INTERNET_CPID', INTERNET_CPID_UTF8);
412
        }
413
    }
414
415
    /**
416
     * Returns the MAPI PR_CONTAINER_CLASS string for an ActiveSync Foldertype
417
     *
418
     * @param int       $foldertype
419
     *
420
     * @access public
421
     * @return string
422
     */
423
    public static function GetContainerClassFromFolderType($foldertype) {
424
        switch ($foldertype) {
425
            case SYNC_FOLDER_TYPE_TASK:
426
            case SYNC_FOLDER_TYPE_USER_TASK:
427
                return "IPF.Task";
428
                break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
429
430
            case SYNC_FOLDER_TYPE_APPOINTMENT:
431
            case SYNC_FOLDER_TYPE_USER_APPOINTMENT:
432
                return "IPF.Appointment";
433
                break;
434
435
            case SYNC_FOLDER_TYPE_CONTACT:
436
            case SYNC_FOLDER_TYPE_USER_CONTACT:
437
                return "IPF.Contact";
438
                break;
439
440
            case SYNC_FOLDER_TYPE_NOTE:
441
            case SYNC_FOLDER_TYPE_USER_NOTE:
442
                return "IPF.StickyNote";
443
                break;
444
445
            case SYNC_FOLDER_TYPE_JOURNAL:
446
            case SYNC_FOLDER_TYPE_USER_JOURNAL:
447
                return "IPF.Journal";
448
                break;
449
450
            case SYNC_FOLDER_TYPE_INBOX:
451
            case SYNC_FOLDER_TYPE_DRAFTS:
452
            case SYNC_FOLDER_TYPE_WASTEBASKET:
453
            case SYNC_FOLDER_TYPE_SENTMAIL:
454
            case SYNC_FOLDER_TYPE_OUTBOX:
455
            case SYNC_FOLDER_TYPE_USER_MAIL:
456
            case SYNC_FOLDER_TYPE_OTHER:
457
            case SYNC_FOLDER_TYPE_UNKNOWN:
458
            default:
459
                return "IPF.Note";
460
                break;
461
        }
462
    }
463
464
    public static function GetSignedAttachmentRestriction() {
465
        return array(  RES_PROPERTY,
466
            array(  RELOP => RELOP_EQ,
467
                ULPROPTAG => PR_ATTACH_MIME_TAG,
468
                VALUE => array(PR_ATTACH_MIME_TAG => 'multipart/signed')
469
            ),
470
        );
471
    }
472
473
    /**
474
     * Calculates the native body type of a message using available properties. Refer to oxbbody.
475
     *
476
     * @param array             $messageprops
477
     *
478
     * @access public
479
     * @return int
480
     */
481
    public static function GetNativeBodyType($messageprops) {
482
        //check if the properties are set and get the error code if needed
483
        if (!isset($messageprops[PR_BODY]))             $messageprops[PR_BODY]              = self::GetError(PR_BODY, $messageprops);
484
        if (!isset($messageprops[PR_RTF_COMPRESSED]))   $messageprops[PR_RTF_COMPRESSED]    = self::GetError(PR_RTF_COMPRESSED, $messageprops);
485
        if (!isset($messageprops[PR_HTML]))             $messageprops[PR_HTML]              = self::GetError(PR_HTML, $messageprops);
486
        if (!isset($messageprops[PR_RTF_IN_SYNC]))      $messageprops[PR_RTF_IN_SYNC]       = self::GetError(PR_RTF_IN_SYNC, $messageprops);
487
488
        if ( // 1
489
                ($messageprops[PR_BODY]             == MAPI_E_NOT_FOUND) &&
490
                ($messageprops[PR_RTF_COMPRESSED]   == MAPI_E_NOT_FOUND) &&
491
                ($messageprops[PR_HTML]             == MAPI_E_NOT_FOUND))
492
                    return SYNC_BODYPREFERENCE_PLAIN;
493
                elseif ( // 2
494
                        ($messageprops[PR_BODY]             == MAPI_E_NOT_ENOUGH_MEMORY) &&
495
                        ($messageprops[PR_RTF_COMPRESSED]   == MAPI_E_NOT_FOUND) &&
496
                        ($messageprops[PR_HTML]             == MAPI_E_NOT_FOUND))
497
                        return SYNC_BODYPREFERENCE_PLAIN;
498
                elseif ( // 3
499
                        ($messageprops[PR_BODY]             == MAPI_E_NOT_ENOUGH_MEMORY) &&
500
                        ($messageprops[PR_RTF_COMPRESSED]   == MAPI_E_NOT_ENOUGH_MEMORY) &&
501
                        ($messageprops[PR_HTML]             == MAPI_E_NOT_FOUND))
502
                        return SYNC_BODYPREFERENCE_RTF;
503
                elseif ( // 4
504
                        ($messageprops[PR_BODY]             == MAPI_E_NOT_ENOUGH_MEMORY) &&
505
                        ($messageprops[PR_RTF_COMPRESSED]   == MAPI_E_NOT_ENOUGH_MEMORY) &&
506
                        ($messageprops[PR_HTML]             == MAPI_E_NOT_ENOUGH_MEMORY) &&
507
                        ($messageprops[PR_RTF_IN_SYNC]))
508
                        return SYNC_BODYPREFERENCE_RTF;
509
                elseif ( // 5
510
                        ($messageprops[PR_BODY]             == MAPI_E_NOT_ENOUGH_MEMORY) &&
511
                        ($messageprops[PR_RTF_COMPRESSED]   == MAPI_E_NOT_ENOUGH_MEMORY) &&
512
                        ($messageprops[PR_HTML]             == MAPI_E_NOT_ENOUGH_MEMORY) &&
513
                        (!$messageprops[PR_RTF_IN_SYNC]))
514
                        return SYNC_BODYPREFERENCE_HTML;
515
                elseif ( // 6
516
                        ($messageprops[PR_RTF_COMPRESSED]   != MAPI_E_NOT_FOUND   || $messageprops[PR_RTF_COMPRESSED]  == MAPI_E_NOT_ENOUGH_MEMORY) &&
517
                        ($messageprops[PR_HTML]             != MAPI_E_NOT_FOUND   || $messageprops[PR_HTML]            == MAPI_E_NOT_ENOUGH_MEMORY) &&
518
                        ($messageprops[PR_RTF_IN_SYNC]))
519
                        return SYNC_BODYPREFERENCE_RTF;
520
                elseif ( // 7
521
                        ($messageprops[PR_RTF_COMPRESSED]   != MAPI_E_NOT_FOUND   || $messageprops[PR_RTF_COMPRESSED]  == MAPI_E_NOT_ENOUGH_MEMORY) &&
522
                        ($messageprops[PR_HTML]             != MAPI_E_NOT_FOUND   || $messageprops[PR_HTML]            == MAPI_E_NOT_ENOUGH_MEMORY) &&
523
                        (!$messageprops[PR_RTF_IN_SYNC]))
524
                        return SYNC_BODYPREFERENCE_HTML;
525
                elseif ( // 8
526
                        ($messageprops[PR_BODY]             != MAPI_E_NOT_FOUND   || $messageprops[PR_BODY]            == MAPI_E_NOT_ENOUGH_MEMORY) &&
527
                        ($messageprops[PR_RTF_COMPRESSED]   != MAPI_E_NOT_FOUND   || $messageprops[PR_RTF_COMPRESSED]  == MAPI_E_NOT_ENOUGH_MEMORY) &&
528
                        ($messageprops[PR_RTF_IN_SYNC]))
529
                        return SYNC_BODYPREFERENCE_RTF;
530
                elseif ( // 9.1
531
                        ($messageprops[PR_BODY]             != MAPI_E_NOT_FOUND   || $messageprops[PR_BODY]            == MAPI_E_NOT_ENOUGH_MEMORY) &&
532
                        ($messageprops[PR_RTF_COMPRESSED]   != MAPI_E_NOT_FOUND   || $messageprops[PR_RTF_COMPRESSED]  == MAPI_E_NOT_ENOUGH_MEMORY) &&
533
                        (!$messageprops[PR_RTF_IN_SYNC]))
534
                        return SYNC_BODYPREFERENCE_PLAIN;
535
                elseif ( // 9.2
536
                        ($messageprops[PR_RTF_COMPRESSED]   != MAPI_E_NOT_FOUND   || $messageprops[PR_RTF_COMPRESSED]  == MAPI_E_NOT_ENOUGH_MEMORY) &&
537
                        ($messageprops[PR_BODY]             == MAPI_E_NOT_FOUND) &&
538
                        ($messageprops[PR_HTML]             == MAPI_E_NOT_FOUND))
539
                        return SYNC_BODYPREFERENCE_RTF;
540
                elseif ( // 9.3
541
                        ($messageprops[PR_BODY]             != MAPI_E_NOT_FOUND   || $messageprops[PR_BODY]            == MAPI_E_NOT_ENOUGH_MEMORY) &&
542
                        ($messageprops[PR_RTF_COMPRESSED]   == MAPI_E_NOT_FOUND) &&
543
                        ($messageprops[PR_HTML]             == MAPI_E_NOT_FOUND))
544
                        return SYNC_BODYPREFERENCE_PLAIN;
545
                elseif ( // 9.4
546
                        ($messageprops[PR_HTML]             != MAPI_E_NOT_FOUND   || $messageprops[PR_HTML]            == MAPI_E_NOT_ENOUGH_MEMORY) &&
547
                        ($messageprops[PR_BODY]             == MAPI_E_NOT_FOUND) &&
548
                        ($messageprops[PR_RTF_COMPRESSED]   == MAPI_E_NOT_FOUND))
549
                        return SYNC_BODYPREFERENCE_HTML;
550
                else // 10
551
                    return SYNC_BODYPREFERENCE_PLAIN;
552
    }
553
554
    /**
555
     * Returns the error code for a given property.
556
     * Helper for MAPIUtils::GetNativeBodyType() function but also used in other places.
557
     *
558
     * @param int               $tag
559
     * @param array             $messageprops
560
     *
561
     * @access public
562
     * @return int (MAPI_ERROR_CODE)
563
     */
564
    public static function GetError($tag, $messageprops) {
565
        $prBodyError = mapi_prop_tag(PT_ERROR, mapi_prop_id($tag));
2 ignored issues
show
Bug introduced by
The function mapi_prop_id was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

565
        $prBodyError = mapi_prop_tag(PT_ERROR, /** @scrutinizer ignore-call */ mapi_prop_id($tag));
Loading history...
Bug introduced by
The function mapi_prop_tag was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

565
        $prBodyError = /** @scrutinizer ignore-call */ mapi_prop_tag(PT_ERROR, mapi_prop_id($tag));
Loading history...
566
        if(isset($messageprops[$prBodyError]) && mapi_is_error($messageprops[$prBodyError])) {
1 ignored issue
show
Bug introduced by
The function mapi_is_error was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

566
        if(isset($messageprops[$prBodyError]) && /** @scrutinizer ignore-call */ mapi_is_error($messageprops[$prBodyError])) {
Loading history...
567
            if($messageprops[$prBodyError] == MAPI_E_NOT_ENOUGH_MEMORY_32BIT ||
568
                    $messageprops[$prBodyError] == MAPI_E_NOT_ENOUGH_MEMORY_64BIT) {
569
                        return MAPI_E_NOT_ENOUGH_MEMORY;
570
                    }
571
        }
572
        return MAPI_E_NOT_FOUND;
573
    }
574
575
576
    /**
577
     * Function will be used to decode smime messages and convert it to normal messages.
578
     *
579
     * @param MAPISession       $session
0 ignored issues
show
Bug introduced by
The type MAPISession 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...
580
     * @param MAPIStore         $store
581
     * @param MAPIAdressBook    $addressBook
0 ignored issues
show
Bug introduced by
The type MAPIAdressBook 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...
582
     * @param MAPIMessage       $message smime message
583
     *
584
     * @access public
585
     * @return void
586
     */
587
    public static function ParseSmime($session, $store, $addressBook, &$mapimessage) {
588
        $props = mapi_getprops($mapimessage, array(PR_MESSAGE_CLASS, PR_SUBJECT, PR_MESSAGE_DELIVERY_TIME, PR_SENT_REPRESENTING_NAME, PR_SENT_REPRESENTING_ENTRYID, PR_SENT_REPRESENTING_SEARCH_KEY, PR_MESSAGE_FLAGS));
1 ignored issue
show
Bug introduced by
The function mapi_getprops was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

588
        $props = /** @scrutinizer ignore-call */ mapi_getprops($mapimessage, array(PR_MESSAGE_CLASS, PR_SUBJECT, PR_MESSAGE_DELIVERY_TIME, PR_SENT_REPRESENTING_NAME, PR_SENT_REPRESENTING_ENTRYID, PR_SENT_REPRESENTING_SEARCH_KEY, PR_MESSAGE_FLAGS));
Loading history...
589
        $read = $props[PR_MESSAGE_FLAGS] & MSGFLAG_READ;
590
591
        if (isset($props[PR_MESSAGE_CLASS]) && stripos($props[PR_MESSAGE_CLASS], 'IPM.Note.SMIME.MultipartSigned') !== false) {
592
            // this is a signed message. decode it.
593
            $attachTable = mapi_message_getattachmenttable($mapimessage);
1 ignored issue
show
Bug introduced by
The function mapi_message_getattachmenttable was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

593
            $attachTable = /** @scrutinizer ignore-call */ mapi_message_getattachmenttable($mapimessage);
Loading history...
594
            $rows = mapi_table_queryallrows($attachTable, array(PR_ATTACH_MIME_TAG, PR_ATTACH_NUM));
1 ignored issue
show
Bug introduced by
The function mapi_table_queryallrows was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

594
            $rows = /** @scrutinizer ignore-call */ mapi_table_queryallrows($attachTable, array(PR_ATTACH_MIME_TAG, PR_ATTACH_NUM));
Loading history...
595
            $attnum = false;
596
597
            foreach($rows as $row) {
598
                if (isset($row[PR_ATTACH_MIME_TAG]) && $row[PR_ATTACH_MIME_TAG] == 'multipart/signed') {
599
                    $attnum = $row[PR_ATTACH_NUM];
600
                }
601
            }
602
603
            if ($attnum !== false) {
604
                $att = mapi_message_openattach($mapimessage, $attnum);
1 ignored issue
show
Bug introduced by
The function mapi_message_openattach was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

604
                $att = /** @scrutinizer ignore-call */ mapi_message_openattach($mapimessage, $attnum);
Loading history...
605
                $data = mapi_openproperty($att, PR_ATTACH_DATA_BIN);
1 ignored issue
show
Bug introduced by
The function mapi_openproperty was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

605
                $data = /** @scrutinizer ignore-call */ mapi_openproperty($att, PR_ATTACH_DATA_BIN);
Loading history...
606
                mapi_message_deleteattach($mapimessage, $attnum);
1 ignored issue
show
Bug introduced by
The function mapi_message_deleteattach was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

606
                /** @scrutinizer ignore-call */ 
607
                mapi_message_deleteattach($mapimessage, $attnum);
Loading history...
607
                mapi_inetmapi_imtomapi($session, $store, $addressBook, $mapimessage, $data, array("parse_smime_signed" => 1));
1 ignored issue
show
Bug introduced by
The function mapi_inetmapi_imtomapi was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

607
                /** @scrutinizer ignore-call */ 
608
                mapi_inetmapi_imtomapi($session, $store, $addressBook, $mapimessage, $data, array("parse_smime_signed" => 1));
Loading history...
608
                ZLog::Write(LOGLEVEL_DEBUG, "Convert a smime signed message to a normal message.");
609
            }
610
            $mprops = mapi_getprops($mapimessage, array(PR_MESSAGE_FLAGS));
611
            // Workaround for issue 13
612
            mapi_setprops($mapimessage, array(
1 ignored issue
show
Bug introduced by
The function mapi_setprops was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

612
            /** @scrutinizer ignore-call */ 
613
            mapi_setprops($mapimessage, array(
Loading history...
613
                PR_MESSAGE_CLASS => 'IPM.Note.SMIME.MultipartSigned',
614
                PR_SUBJECT => $props[PR_SUBJECT],
615
                PR_MESSAGE_DELIVERY_TIME => $props[PR_MESSAGE_DELIVERY_TIME],
616
                PR_SENT_REPRESENTING_NAME => $props[PR_SENT_REPRESENTING_NAME],
617
                PR_SENT_REPRESENTING_ENTRYID => $props[PR_SENT_REPRESENTING_ENTRYID],
618
                PR_SENT_REPRESENTING_SEARCH_KEY => $props[PR_SENT_REPRESENTING_SEARCH_KEY],
619
                // mark the message as read if the main message has read flag
620
                PR_MESSAGE_FLAGS => $read ? $mprops[PR_MESSAGE_FLAGS] | MSGFLAG_READ : $mprops[PR_MESSAGE_FLAGS],
621
            ));
622
        }
623
        // TODO check if we need to do this for encrypted (and signed?) message as well
624
    }
625
626
    /**
627
     * Compares two entryIds. It is possible to have two different entryIds that should match as they
628
     * represent the same object (in multiserver environments).
629
     * @param string $entryId1
630
     * @param string $entryId2
631
     *
632
     * @access public
633
     * @return boolean
634
     */
635
    public static function CompareEntryIds($entryId1, $entryId2) {
636
        if (!is_string($entryId1) || !is_string($entryId2)) {
0 ignored issues
show
introduced by
The condition is_string($entryId2) is always true.
Loading history...
introduced by
The condition is_string($entryId1) is always true.
Loading history...
637
            return false;
638
        }
639
640
        if ($entryId1 === $entryId2) {
641
            // if normal comparison succeeds then we can directly say that entryids are same
642
            return true;
643
        }
644
645
        $eid1 = self::createEntryIdObj($entryId1);
646
        $eid2 = self::createEntryIdObj($entryId2);
647
648
        if ($eid1['length'] != $eid2['length'] ||
649
            $eid1['abFlags'] != $eid2['abFlags'] ||
650
            $eid1['version'] != $eid2['version'] ||
651
            $eid1['type'] != $eid2['type']) {
652
            return false;
653
        }
654
655
        if ($eid1['name'] == 'EID_V0') {
656
            if ($eid1['length'] < $eid1['min_length'] || $eid1['id'] != $eid2['id']) {
657
                return false;
658
            }
659
        }
660
        elseif ($eid1['length'] < $eid1['min_length'] || $eid1['uniqueId'] != $eid2['uniqueId']) {
661
            return false;
662
        }
663
664
        return true;
665
    }
666
667
    /**
668
     * Creates an object that has split up all the components of an entryID.
669
     * @param string $entryid Entryid
670
     *
671
     * @access private
672
     * @return Object EntryID object
673
     */
674
    private static function createEntryIdObj($entryid) {
675
        // check if we are dealing with old or new object entryids
676
        return (substr($entryid, 40, 8) == '00000000') ? self::getEID_V0Version($entryid) : self::getEIDVersion($entryid);
0 ignored issues
show
Bug Best Practice introduced by
The expression return substr($entryid, ...getEIDVersion($entryid) also could return the type array<string,string> which is incompatible with the documented return type object.
Loading history...
677
    }
678
679
    /**
680
     * The entryid from the begin of zarafa till 5.20.
681
     * @param string $entryid
682
     *
683
     * @access private
684
     * @return Object EntryID object
685
     *
686
     */
687
    private static function getEID_V0Version($entryid) {
688
        // always make entryids in uppercase so comparison will be case insensitive
689
        $entryId = strtoupper($entryid);
690
691
        $res = array(
692
            'abFlags'   => '',  // BYTE[4],  4 bytes,  8 hex characters
693
            'guid'      => '',  // GUID,    16 bytes, 32 hex characters
694
            'version'   => '',  // ULONG,    4 bytes,  8 hex characters
695
            'type'      => '',  // ULONG,    4 bytes,  8 hex characters
696
            'id'        => '',  // ULONG,    4 bytes,  8 hex characters
697
            'server'    => '',  // CHAR,    variable length
698
            'padding'   => '',  // TCHAR[3], 4 bytes,  8 hex characters (upto 4 bytes)
699
        );
700
701
        $res['length'] = strlen($entryId);
702
        $offset = 0;
703
704
        // First determine padding, and remove if from the entryId
705
        $res['padding'] = self::getPadding($entryId);
706
        $entryId = substr($entryId, 0, strlen($entryId) - strlen($res['padding']));
707
708
        $res['abFlags'] = substr($entryId, $offset, 8);
709
        $offset =+ 8;
710
711
        $res['guid'] = substr($entryId, $offset, 32);
712
        $offset += 32;
713
714
        $res['version'] = substr($entryId, $offset, 8);
715
        $offset += 8;
716
717
        $res['type'] = substr($entryId, $offset, 8);
718
        $offset += 8;
719
720
        $res['id'] = substr($entryId, $offset, 8);
721
        $offset += 8;
722
723
        $res['server'] = substr($entryId, $offset);
724
725
        $res['min_length'] = 64;
726
        $res['name'] = 'EID_V0';
727
728
        return $res;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $res returns the type array<string,string> which is incompatible with the documented return type object.
Loading history...
729
    }
730
731
    /**
732
     * Entryid from version 6.
733
     * @param string $entryid
734
     *
735
     * @access private
736
     * @return string[]|number[]|NULL[]
737
     */
738
    private static function getEIDVersion($entryid) {
739
        // always make entryids in uppercase so comparison will be case insensitive
740
        $entryId = strtoupper($entryid);
741
742
        $res = array(
743
            'abFlags'   => '',  // BYTE[4],  4 bytes,  8 hex characters
744
            'guid'      => '',  // GUID,    16 bytes, 32 hex characters
745
            'version'   => '',  // ULONG,    4 bytes,  8 hex characters
746
            'type'      => '',  // ULONG,    4 bytes,  8 hex characters
747
            'uniqueId'  => '',  // ULONG,   16 bytes,  32 hex characters
748
            'server'    => '',  // CHAR,    variable length
749
            'padding'   => '',  // TCHAR[3], 4 bytes,  8 hex characters (upto 4 bytes)
750
        );
751
752
        $res['length'] = strlen($entryId);
753
        $offset = 0;
754
755
        // First determine padding, and remove if from the entryId
756
        $res['padding'] = self::getPadding($entryId);
757
        $entryId = substr($entryId, 0, strlen($entryId) - strlen($res['padding']));
758
759
        $res['abFlags'] = substr($entryId, $offset, 8);
760
        $offset =+ 8;
761
762
        $res['guid'] = substr($entryId, $offset, 32);
763
        $offset += 32;
764
765
        $res['version'] = substr($entryId, $offset, 8);
766
        $offset += 8;
767
768
        $res['type'] = substr($entryId, $offset, 8);
769
        $offset += 8;
770
771
        $res['uniqueId'] = substr($entryId, $offset, 32);
772
        $offset += 32;
773
774
        $res['server'] = substr($entryId, $offset);
775
776
        $res['min_length'] = 88;
777
        $res['name'] = 'EID';
778
779
        return $res;
780
    }
781
782
    /**
783
     * Detect padding (max 3 bytes) from the entryId.
784
     * @param string $entryId
785
     *
786
     * @access private
787
     * @return string
788
     */
789
    private static function getPadding($entryId) {
790
        $len = strlen($entryId);
791
        $padding = '';
792
        $offset = 0;
793
794
        for ($iterations = 4; $iterations > 0; $iterations--) {
795
            if (substr($entryId, $len - ($offset + 2), $len - $offset) == '00') {
796
                $padding .= '00';
797
                $offset += 2;
798
            }
799
            else {
800
                // if non-null character found then break the loop
801
                break;
802
            }
803
        }
804
805
        return $padding;
806
    }
807
}
808