Completed
Push — master ( 35728e...5c8980 )
by Gareth
03:35
created

API::moveItem()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 6

Duplication

Lines 11
Ratio 100 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 2
Bugs 0 Features 2
Metric Value
c 2
b 0
f 2
dl 11
loc 11
ccs 0
cts 6
cp 0
rs 9.4285
cc 1
eloc 6
nc 1
nop 3
crap 2
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 30
    public function __construct(ExchangeWebServices $client = null)
29
    {
30 30
        if ($client) {
31 18
            $this->setClient($client);
32 18
        }
33 30
    }
34
35
    /**
36
     * @return Type\EmailAddressType
37
     */
38 21
    public function getPrimarySmtpMailbox()
39
    {
40 21
        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
    public function getFieldUriByName($fieldName, $preference = 'item')
74
    {
75
        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 7
    public function getCalendar($name = null)
99
    {
100 6
        $calendar = new CalendarAPI();
101 6
        $calendar->setClient($this->getClient());
102 7
        $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 30
    public function setClient($client)
127
    {
128 30
        $this->client = $client;
129
130 30
        return $this;
131
    }
132
133
    /**
134
     * Get the API client
135
     *
136
     * @return ExchangeWebServices
137
     */
138 28
    public function getClient()
139
    {
140 28
        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
    public function buildClient(
154
        $server,
155
        $username,
156
        $password,
157
        $options = []
158
    ) {
159
        $this->setClient(ExchangeWebServices::fromUsernameAndPassword(
160
            $server,
161
            $username,
162
            $password,
163
            array_replace_recursive(self::$defaultClientOptions, $options)
164
        ));
165
    }
166
167 17
    public static function withUsernameAndPassword($server, $username, $password, $options = [])
168
    {
169 17
        return new static(ExchangeWebServices::fromUsernameAndPassword(
170 17
            $server,
171 17
            $username,
172 17
            $password,
173 17
            array_replace_recursive(self::$defaultClientOptions, $options)
174 17
        ));
175
    }
176
177 1
    public static function withCallbackToken($server, $token, $options = [])
178
    {
179 1
        return new static(ExchangeWebServices::fromCallbackToken(
180 1
            $server,
181 1
            $token,
182 1
            array_replace_recursive(self::$defaultClientOptions, $options)
183 1
        ));
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 13
    public function createItems($items, $options = array())
210
    {
211 13
        if (!is_array($items)) {
212
            $items = array($items);
213
        }
214
215
        $request = array(
216
            'Items' => $items
217 13
        );
218
219 13
        $request = array_replace_recursive($request, $options);
220 13
        $request = Type::buildFromArray($request);
221
222 13
        $response = $this->getClient()->CreateItem($request);
223
224 13
        return $response;
225
    }
226
227 3
    public function updateItems($items, $options = array())
228
    {
229
        $request = array(
230 3
            'ItemChanges' => $items,
231 3
            'MessageDisposition' => 'SaveOnly',
232
            'ConflictResolution' => 'AlwaysOverwrite'
233 3
        );
234
235 3
        $request = array_replace_recursive($request, $options);
236
237 3
        $request = Type::buildFromArray($request);
238
239 3
        $response = $this->getClient()->UpdateItem($request);
240 3
        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 3
            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 3
    protected function buildUpdateItemChanges($itemType, $uriType, $changes)
258
    {
259 3
        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 2
        }
268
269 2
        if (!is_array($names)) {
270 2
            $names = array($names);
271 2
        }
272
273 2
        foreach ($names as $name) {
274 2
            $request['Folders']['Folder'][] = array(
275
                'DisplayName' => $name
276 2
            );
277 2
        }
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 2
            )
293 2
        );
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 13
    public function deleteItems($items, $options = array())
318
    {
319 13
        if (!is_array($items) || Type::arrayIsAssoc($items)) {
320 13
            $items = array($items);
321 13
        }
322
323 13
        $itemIds = array();
324 13
        foreach ($items as $item) {
325 13
            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 12
                $item = $item->toArray();
327 12
            }
328 13
            $item = (array)$item;
329 13
            $itemIds[] = array(
330 13
                'Id' => $item['Id'],
331 13
                'ChangeKey' => $item['ChangeKey']
332 13
            );
333 13
        }
334
335
        $request = array(
336 13
            'ItemIds' => array('ItemId' => $itemIds),
337
            'DeleteType' => 'MoveToDeletedItems'
338 13
        );
339
340 13
        $request = array_replace_recursive($request, $options);
341 13
        $request = Type::buildFromArray($request);
342 13
        $this->getClient()->DeleteItem($request);
343
344
        //If the delete fails, an Exception will be thrown in processResponse before it gets here
345 13
        return true;
346
    }
347
348
    /**
349
     * @param $identifier
350
     * @return Type\BaseFolderType
351
     */
352 20
    public function getFolder($identifier)
353
    {
354
        $request = array(
355
            'FolderShape' => array(
356 20
                'BaseShape' => array('_' => 'Default')
357 20
            ),
358
            'FolderIds' => $identifier
359 20
        );
360 20
        $request = Type::buildFromArray($request);
361
362 20
        $response = $this->getClient()->GetFolder($request);
363
364 20
        return $response;
365
    }
366
367
    /**
368
     * Get a folder by it's distinguishedId
369
     *
370
     * @param string $distinguishedId
371
     * @return Type\BaseFolderType
372
     */
373 20
    public function getFolderByDistinguishedId($distinguishedId)
374
    {
375 20
        return $this->getFolder(array(
376
            'DistinguishedFolderId' => array(
377 20
                'Id' => $distinguishedId,
378 20
                'Mailbox' => $this->getPrimarySmtpMailbox()
379 20
            )
380 20
        ));
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 4
        ));
392
    }
393
394
    /**
395
     * @param string|Type\FolderIdType $parentFolderId
396
     * @param array $options
397
     * @return bool|Type\BaseFolderType
398
     */
399 19
    public function getChildrenFolders($parentFolderId = 'root', $options = array())
400
    {
401 19
        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 15
        }
404
405
        $request = array(
406 19
            'Traversal' => 'Shallow',
407
            'FolderShape' => array(
408
                'BaseShape' => 'AllProperties'
409 19
            ),
410
            'ParentFolderIds' => array(
411 19
                'FolderId' => $parentFolderId->toArray()
412 19
            )
413 19
        );
414
415 19
        $request = array_replace_recursive($request, $options);
416
417 19
        $request = Type::buildFromArray($request);
418
419
        /** @var \garethp\ews\API\Message\FindFolderResponseMessageType $folders */
420 19
        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 19
    public function getFolderByDisplayName($folderName, $parentFolderId = 'root', $options = array())
432
    {
433 19
        $folders = $this->getChildrenFolders($parentFolderId, $options);
434
435 19
        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 19
            if ($folder->getDisplayName() == $folderName) {
437 18
                return $folder;
438
            }
439 13
        }
440
441 3
        return false;
442
    }
443
444
    /**
445
     * @param $itemId array|Type\ItemIdType
446
     * @param array $options
447
     * @return Type
448
     */
449 4 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 4
        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 3
            $itemId = $itemId->toArray();
453 3
        }
454
455
        $request = array(
456 4
            'ItemShape' => array('BaseShape' => 'AllProperties'),
457 4
            'ItemIds' => array('ItemId' => $itemId)
458 4
        );
459
460 4
        $request = array_replace_recursive($request, $options);
461
462 4
        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
            'MaxChangesReturned' => '10'
480 2
        );
481
482 2
        if ($syncState != null) {
483 1
            $request['SyncState'] = $syncState;
484 1
            $request['ItemShape']['BaseShape'] = 'AllProperties';
485 1
        }
486
487 2
        $request = array_replace_recursive($request, $options);
488
489 2
        $request = Type::buildFromArray($request);
490 2
        $response = $this->getClient()->SyncFolderItems($request);
491
492 2
        return $response;
493
    }
494
495
    public function getServerTimezones($timezoneIDs = array(), $fullTimezoneData = false)
496
    {
497
        $request = GetServerTimeZonesType::buildFromArray(array(
498
            'returnFullTimeZoneData' => $fullTimezoneData
499
        ));
500
501
        if (!empty($timezoneIDs)) {
502
            $request->setIds($timezoneIDs);
503
        }
504
505
        $timezones = $this->getClient()->GetServerTimeZones($request);
506
        $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...
507
508
        if (!is_array($timezones)) {
509
            $timezones = array($timezones);
510
        }
511
512
        return $timezones;
513
    }
514
515
    /**
516
     * @param Type\ItemIdType $itemId
517
     * @param $fromType
518
     * @param $destinationType
519
     * @param $mailbox
520
     *
521
     * @return Type\ItemIdType
522
     */
523
    public function convertIdFormat(Type\ItemIdType $itemId, $fromType, $destinationType, $mailbox)
524
    {
525
        $result = $this->getClient()->ConvertId(array(
526
            'DestinationFormat' => $destinationType,
527
            'SourceIds' => array(
528
                'AlternateId' => array(
529
                    'Format' => $fromType,
530
                    'Id' => $itemId->getId(),
531
                    'Mailbox' => $mailbox
532
                )
533
            )
534
        ));
535
536
        $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...
537
538
        return $itemId;
539
    }
540
}
541