Completed
Push — master ( c7e42b...9e6269 )
by Gareth
03:51
created

API::getChildrenFolders()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 25
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 2.0054

Importance

Changes 2
Bugs 1 Features 1
Metric Value
c 2
b 1
f 1
dl 0
loc 25
ccs 8
cts 9
cp 0.8889
rs 8.8571
cc 2
eloc 13
nc 2
nop 2
crap 2.0054
1
<?php
2
3
namespace garethp\ews;
4
5
use garethp\ews\API\Exception\ExchangeException;
6
use garethp\ews\API\ExchangeWebServices;
7
use garethp\ews\API\ItemUpdateBuilder;
8
use garethp\ews\API\Message\GetServerTimeZonesType;
9
use garethp\ews\API\Message\SyncFolderItemsResponseMessageType;
10
use garethp\ews\API\Message\UpdateItemResponseMessageType;
11
use garethp\ews\API\Type;
12
use garethp\ews\Calendar\CalendarAPI;
13
use garethp\ews\Mail\MailAPI;
14
use garethp\ews\API\FieldURIManager;
15
16
/**
17
 * A base class for APIs
18
 *
19
 * Class BaseAPI
20
 * @package garethp\ews
21
 */
22
class API
23
{
24
    protected static $defaultClientOptions = array(
25
        'version' => ExchangeWebServices::VERSION_2010
26
    );
27
28 32
    public function __construct(ExchangeWebServices $client = null)
29
    {
30 32
        if ($client) {
31 20
            $this->setClient($client);
32
        }
33
    }
34
35
    /**
36
     * @return Type\EmailAddressType
37
     */
38 23
    public function getPrimarySmtpMailbox()
39
    {
40 23
        return $this->getClient()->getPrimarySmtpMailbox();
41
    }
42
43
    /**
44
     * Storing the API client
45
     * @var ExchangeWebServices
46
     */
47
    private $client;
48
49
    /**
50
     * @deprecated This will be removed in 0.9
51
     *
52
     * @param $className
53
     * @return array
54
     */
55
    public function getFieldUrisFromClass($className)
56
    {
57
        return FieldURIManager::getFieldUrisFromClass($className);
0 ignored issues
show
Deprecated Code introduced by
The method garethp\ews\API\FieldURI...getFieldUrisFromClass() has been deprecated with message: This will be made protected in 0.9

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
58
    }
59
60
    public function setupFieldUris()
61
    {
62
        FieldURIManager::setupFieldUris();
0 ignored issues
show
Deprecated Code introduced by
The method garethp\ews\API\FieldURIManager::setupFieldUris() has been deprecated with message: This will be made protected in 0.9

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
63
    }
64
65
    /**
66
     * @deprecated This will be removed in 0.9. See FieldURIManager
67
     *
68
     * @param $fieldName
69
     * @param string $preference
70
     * @throws ExchangeException
71
     * @return string
72
     */
73 2
    public function getFieldUriByName($fieldName, $preference = 'item')
74
    {
75 2
        return FieldURIManager::getFieldUriByName($fieldName, $preference);
76
    }
77
78
    /**
79
     * @deprecated This will be removed in 0.9. See FieldURIManager
80
     *
81
     * @param $fieldName
82
     * @param string $preference
83
     * @param bool $entryKey
84
     * @throws ExchangeException
85
     * @return string
86
     */
87
    public function getIndexedFieldUriByName($fieldName, $preference = 'item', $entryKey = false)
88
    {
89
        return FieldURIManager::getIndexedFieldUriByName($fieldName, $preference, $entryKey);
90
    }
91
92
    /**
93
     * Get a calendar item
94
     *
95
     * @param string $name
96
     * @return CalendarAPI
97
     */
98 6
    public function getCalendar($name = null)
99
    {
100 6
        $calendar = new CalendarAPI();
101 6
        $calendar->setClient($this->getClient());
102 6
        $calendar->pickCalendar($name);
103
104 6
        return $calendar;
105
    }
106
107
    /**
108
     * @param string $folderName
109
     * @return MailAPI
110
     */
111 6
    public function getMailbox($folderName = null)
112
    {
113 6
        $mailApi = new MailAPI();
114 6
        $mailApi->setClient($this->getClient());
115 6
        $mailApi->pickMailFolder($folderName);
116
117 6
        return $mailApi;
118
    }
119
120
    /**
121
     * Set the API client
122
     *
123
     * @param ExchangeWebServices $client
124
     * @return $this
125
     */
126 32
    public function setClient($client)
127
    {
128 32
        $this->client = $client;
129
130 32
        return $this;
131
    }
132
133
    /**
134
     * Get the API client
135
     *
136
     * @return ExchangeWebServices
137
     */
138 30
    public function getClient()
139
    {
140 30
        return $this->client;
141
    }
142
143
    /**
144
     * Instantiate and set a client (ExchangeWebServices) based on the parameters given
145
     *
146
     * @deprecated Since 0.6.3
147
     * @param $server
148
     * @param $username
149
     * @param $password
150
     * @param array $options
151
     * @return $this
152
     */
153 12
    public function buildClient(
154
        $server,
155
        $username,
156
        $password,
157
        $options = []
158
    ) {
159 12
        $this->setClient(ExchangeWebServices::fromUsernameAndPassword(
160
            $server,
161
            $username,
162
            $password,
163 12
            array_replace_recursive(self::$defaultClientOptions, $options)
164
        ));
165
    }
166
167 19
    public static function withUsernameAndPassword($server, $username, $password, $options = [])
168
    {
169 19
        return new static(ExchangeWebServices::fromUsernameAndPassword(
170
            $server,
171
            $username,
172
            $password,
173 19
            array_replace_recursive(self::$defaultClientOptions, $options)
174
        ));
175
    }
176
177 1
    public static function withCallbackToken($server, $token, $options = [])
178
    {
179 1
        return new static(ExchangeWebServices::fromCallbackToken(
180
            $server,
181
            $token,
182 1
            array_replace_recursive(self::$defaultClientOptions, $options)
183
        ));
184
    }
185
186 1
    public function getPrimarySmptEmailAddress()
187
    {
188 1
        if ($this->getPrimarySmtpMailbox() == null) {
189 1
            return null;
190
        }
191
192 1
        return $this->getPrimarySmtpMailbox()->getEmailAddress();
193
    }
194
195 1
    public function setPrimarySmtpEmailAddress($emailAddress)
196
    {
197 1
        $this->getClient()->setPrimarySmtpEmailAddress($emailAddress);
198
199 1
        return $this;
200
    }
201
202
    /**
203
     * Create items through the API client
204
     *
205
     * @param $items
206
     * @param array $options
207
     * @return Type
208
     */
209 15
    public function createItems($items, $options = array())
210
    {
211 15
        if (!is_array($items)) {
212
            $items = array($items);
213
        }
214
215
        $request = array(
216 15
            'Items' => $items
217
        );
218
219 15
        $request = array_replace_recursive($request, $options);
220 15
        $request = Type::buildFromArray($request);
221
222 15
        $response = $this->getClient()->CreateItem($request);
223
224 15
        return $response;
225
    }
226
227 4
    public function updateItems($items, $options = array())
228
    {
229
        $request = array(
230 4
            'ItemChanges' => $items,
231 4
            'MessageDisposition' => 'SaveOnly',
232 4
            'ConflictResolution' => 'AlwaysOverwrite'
233
        );
234
235 4
        $request = array_replace_recursive($request, $options);
236
237 4
        $request = Type::buildFromArray($request);
238
239 4
        $response = $this->getClient()->UpdateItem($request);
240 4
        if ($response instanceof UpdateItemResponseMessageType) {
0 ignored issues
show
Bug introduced by
The class garethp\ews\API\Message\...ItemResponseMessageType does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
241 4
            return $response->getItems();
242
        }
243
244
        if (!is_array($response)) {
245
            $response = array($response);
246
        }
247
248
        return $response;
249
    }
250
251
    /**
252
     * @param string $itemType
253
     * @param string $uriType
254
     * @param array $changes
255
     * @return array
256
     */
257 4
    protected function buildUpdateItemChanges($itemType, $uriType, $changes)
258
    {
259 4
        return ItemUpdateBuilder::buildUpdateItemChanges($itemType, $uriType, $changes);
260
    }
261
262 2
    public function createFolders($names, Type\FolderIdType $parentFolder, $options = array())
263
    {
264 2
        $request = array('Folders' => array('Folder' => array()));
265 2
        if (!empty($parentFolder)) {
266 2
            $request['ParentFolderId'] = array('FolderId' => $parentFolder->toArray());
267
        }
268
269 2
        if (!is_array($names)) {
270 2
            $names = array($names);
271
        }
272
273 2
        foreach ($names as $name) {
274 2
            $request['Folders']['Folder'][] = array(
275 2
                'DisplayName' => $name
276
            );
277
        }
278
279 2
        $request = array_merge_recursive($request, $options);
280
281 2
        $this->client->CreateFolder($request);
282
283 2
        return true;
284
    }
285
286 2 View Code Duplication
    public function deleteFolder(Type\FolderIdType $folderId, $options = array())
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
287
    {
288
        $request = array(
289 2
            'DeleteType' => 'HardDelete',
290
            'FolderIds' => array(
291 2
                'FolderId' => $folderId->toArray()
292
            )
293
        );
294
295 2
        $request = array_merge_recursive($request, $options);
296
297 2
        return $this->client->DeleteFolder($request);
298
    }
299
300 View Code Duplication
    public function moveItem(Type\ItemIdType $itemId, Type\FolderIdType $folderId, $options = array())
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
301
    {
302
        $request = array(
303
            'ToFolderId' => array('FolderId' => $folderId->toArray()),
304
            'ItemIds' => array('ItemId' => $itemId->toArray())
305
        );
306
307
        $request = array_merge_recursive($request, $options);
308
309
        return $this->client->MoveItem($request);
310
    }
311
312
    /**
313
     * @param $items Type\ItemIdType|Type\ItemIdType[]
314
     * @param array $options
315
     * @return bool
316
     */
317 15
    public function deleteItems($items, $options = array())
318
    {
319 15
        if (!is_array($items) || Type::arrayIsAssoc($items)) {
320 15
            $items = array($items);
321
        }
322
323 15
        $itemIds = array();
324 15
        foreach ($items as $item) {
325 15
            if ($item instanceof Type\ItemIdType) {
0 ignored issues
show
Bug introduced by
The class garethp\ews\API\Type\ItemIdType does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
326 14
                $item = $item->toArray();
327
            }
328 15
            $item = (array)$item;
329 15
            $itemIds[] = array(
330 15
                'Id' => $item['Id'],
331 15
                'ChangeKey' => $item['ChangeKey']
332
            );
333
        }
334
335
        $request = array(
336 15
            'ItemIds' => array('ItemId' => $itemIds),
337 15
            'DeleteType' => 'MoveToDeletedItems'
338
        );
339
340 15
        $request = array_replace_recursive($request, $options);
341 15
        $request = Type::buildFromArray($request);
342 15
        $this->getClient()->DeleteItem($request);
343
344
        //If the delete fails, an Exception will be thrown in processResponse before it gets here
345 15
        return true;
346
    }
347
348
    /**
349
     * @param $identifier
350
     * @return Type\BaseFolderType
351
     */
352 22
    public function getFolder($identifier)
353
    {
354
        $request = array(
355
            'FolderShape' => array(
356
                'BaseShape' => array('_' => 'Default')
357 22
            ),
358 22
            'FolderIds' => $identifier
359
        );
360 22
        $request = Type::buildFromArray($request);
361
362 22
        $response = $this->getClient()->GetFolder($request);
363
364 22
        return $response;
365
    }
366
367
    /**
368
     * Get a folder by it's distinguishedId
369
     *
370
     * @param string $distinguishedId
371
     * @return Type\BaseFolderType
372
     */
373 22
    public function getFolderByDistinguishedId($distinguishedId)
374
    {
375 22
        return $this->getFolder(array(
376
            'DistinguishedFolderId' => array(
377 22
                'Id' => $distinguishedId,
378 22
                'Mailbox' => $this->getPrimarySmtpMailbox()
379
            )
380
        ));
381
    }
382
383
    /**
384
     * @param $folderId
385
     * @return Type\BaseFolderType
386
     */
387 4
    public function getFolderByFolderId($folderId)
388
    {
389 4
        return $this->getFolder(array(
390 4
            'FolderId' => array('Id' => $folderId, 'Mailbox' => $this->getPrimarySmtpMailbox())
391
        ));
392
    }
393
394
    /**
395
     * @param string|Type\FolderIdType $parentFolderId
396
     * @param array $options
397
     * @return bool|Type\BaseFolderType
398
     */
399 21
    public function getChildrenFolders($parentFolderId = 'root', $options = array())
400
    {
401 21
        if (is_string($parentFolderId)) {
402 15
            $parentFolderId = $this->getFolderByDistinguishedId($parentFolderId)->getFolderId();
0 ignored issues
show
Documentation Bug introduced by
The method getFolderId does not exist on object<garethp\ews\API\Type>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
403
        }
404
405
        $request = array(
406 21
            'Traversal' => 'Shallow',
407
            'FolderShape' => array(
408
                'BaseShape' => 'AllProperties'
409
            ),
410
            'ParentFolderIds' => array(
411 21
                'FolderId' => $parentFolderId->toArray()
412
            )
413
        );
414
415 21
        $request = array_replace_recursive($request, $options);
416
417 21
        $request = Type::buildFromArray($request);
418
419
        /** @var \garethp\ews\API\Message\FindFolderResponseMessageType $folders */
420 21
        return $this->getClient()->FindFolder($request);
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->getClient()->FindFolder($request); (garethp\ews\API\Type) is incompatible with the return type documented by garethp\ews\API::getChildrenFolders of type boolean|garethp\ews\API\Type\BaseFolderType.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
421
422
        return $folders->getFolders();
0 ignored issues
show
Unused Code introduced by
return $folders->getFolders(); does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
423
    }
424
425
    /**
426
     * @param string $folderName
427
     * @param string|Type\FolderIdType $parentFolderId
428
     * @param array $options
429
     * @return bool|Type\BaseFolderType
430
     */
431 21
    public function getFolderByDisplayName($folderName, $parentFolderId = 'root', $options = array())
432
    {
433 21
        $folders = $this->getChildrenFolders($parentFolderId, $options);
434
435 21
        foreach ($folders as $folder) {
0 ignored issues
show
Bug introduced by
The expression $folders of type boolean|object<garethp\e...PI\Type\BaseFolderType> is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
436 21
            if ($folder->getDisplayName() == $folderName) {
437 21
                return $folder;
438
            }
439
        }
440
441 3
        return false;
442
    }
443
444
    /**
445
     * @param $itemId array|Type\ItemIdType
446
     * @param array $options
447
     * @return Type
448
     */
449 5 View Code Duplication
    public function getItem($itemId, $options = array())
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
450
    {
451 5
        if ($itemId instanceof Type\ItemIdType) {
0 ignored issues
show
Bug introduced by
The class garethp\ews\API\Type\ItemIdType does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
452 4
            $itemId = $itemId->toArray();
453
        }
454
455
        $request = array(
456 5
            'ItemShape' => array('BaseShape' => 'AllProperties'),
457 5
            'ItemIds' => array('ItemId' => $itemId)
458
        );
459
460 5
        $request = array_replace_recursive($request, $options);
461
462 5
        return $this->getClient()->GetItem($request);
463
    }
464
465
    /**
466
     * Get a list of sync changes on a folder
467
     *
468
     * @param Type\FolderIdType $folderId
469
     * @param null $syncState
470
     * @param array $options
471
     * @return SyncFolderItemsResponseMessageType
472
     */
473 2
    public function listItemChanges($folderId, $syncState = null, $options = array())
474
    {
475
        $request = array(
476 2
            'ItemShape' => array('BaseShape' => 'IdOnly'),
477 2
            'SyncFolderId' => array('FolderId' => $folderId->toXmlObject()),
478 2
            'SyncScope' => 'NormalItems',
479 2
            'MaxChangesReturned' => '10'
480
        );
481
482 2
        if ($syncState != null) {
483 1
            $request['SyncState'] = $syncState;
484 1
            $request['ItemShape']['BaseShape'] = 'AllProperties';
485
        }
486
487 2
        $request = array_replace_recursive($request, $options);
488
489 2
        switch ($this->getClient()->getVersion()) {
490 2
            case ExchangeWebServices::VERSION_2007:
491 2
            case ExchangeWebServices::VERSION_2007_SP1:
492 2
            case ExchangeWebServices::VERSION_2007_SP2:
493 2
            case ExchangeWebServices::VERSION_2007_SP3:
494 2
                unset($request['SyncScope']);
495
        }
496
497 2
        $request = Type::buildFromArray($request);
498 2
        $response = $this->getClient()->SyncFolderItems($request);
499
500 2
        return $response;
501
    }
502
503
    public function getServerTimezones($timezoneIDs = array(), $fullTimezoneData = false)
504
    {
505
        $request = GetServerTimeZonesType::buildFromArray(array(
506
            'returnFullTimeZoneData' => $fullTimezoneData
507
        ));
508
509
        if (!empty($timezoneIDs)) {
510
            $request->setIds($timezoneIDs);
511
        }
512
513
        $timezones = $this->getClient()->GetServerTimeZones($request);
514
        $timezones = $timezones->TimeZoneDefinition;
0 ignored issues
show
Documentation introduced by
The property TimeZoneDefinition does not exist on object<garethp\ews\API\Type>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
515
516
        if (!is_array($timezones)) {
517
            $timezones = array($timezones);
518
        }
519
520
        return $timezones;
521
    }
522
523
    /**
524
     * @param Type\ItemIdType $itemId
525
     * @param $fromType
526
     * @param $destinationType
527
     * @param $mailbox
528
     *
529
     * @return Type\ItemIdType
530
     */
531
    public function convertIdFormat(Type\ItemIdType $itemId, $fromType, $destinationType, $mailbox)
532
    {
533
        $result = $this->getClient()->ConvertId(array(
534
            'DestinationFormat' => $destinationType,
535
            'SourceIds' => array(
536
                'AlternateId' => array(
537
                    'Format' => $fromType,
538
                    'Id' => $itemId->getId(),
539
                    'Mailbox' => $mailbox
540
                )
541
            )
542
        ));
543
544
        $itemId->setId($result->getId());
0 ignored issues
show
Documentation Bug introduced by
The method getId does not exist on object<garethp\ews\API\Type>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
545
546
        return $itemId;
547
    }
548
}
549