Completed
Push — master ( 960198...1c7e94 )
by Gareth
04:35 queued 01:36
created

API::getFolder()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 1
Metric Value
dl 0
loc 13
ccs 6
cts 6
cp 1
rs 9.4285
cc 1
eloc 8
nc 1
nop 1
crap 1
1
<?php
2
3
namespace garethp\ews;
4
5
use garethp\ews\API\Enumeration\DictionaryURIType;
6
use garethp\ews\API\Enumeration\UnindexedFieldURIType;
7
use garethp\ews\API\Exception\ExchangeException;
8
use garethp\ews\API\ExchangeWebServices;
9
use garethp\ews\API\Message\GetServerTimeZonesType;
10
use garethp\ews\API\Message\SyncFolderItemsResponseMessageType;
11
use garethp\ews\API\Type;
12
use garethp\ews\Calendar\CalendarAPI;
13
use garethp\ews\Mail\MailAPI;
14
15
/**
16
 * A base class for APIs
17
 *
18
 * Class BaseAPI
19
 * @package garethp\ews
20
 */
21
class API
22
{
23
    protected static $defaultClientOptions = array(
24
        'version' => ExchangeWebServices::VERSION_2010
25
    );
26
27 17
    public function __construct(ExchangeWebServices $client = null)
28
    {
29 17
        if ($client) {
30 5
            $this->setClient($client);
31
        }
32
    }
33
34
    /**
35
     * @return Type\EmailAddressType
36
     */
37 16
    public function getPrimarySmtpMailbox()
38
    {
39 16
        return $this->getClient()->getPrimarySmtpMailbox();
40
    }
41
42
    private $unIndexedFieldUris = array();
43
    private $dictionaryFieldUris = array();
44
45
    /**
46
     * Storing the API client
47
     * @var ExchangeWebServices
48
     */
49
    private $client;
50
51
    /**
52
     * @param $className
53
     * @return array
54
     */
55 3
    public function getFieldUrisFromClass($className)
56
    {
57
        //So, since we have to pass in URI's of everything we update, we need to fetch them
58 3
        $reflection = new \ReflectionClass($className);
59 3
        $constants = $reflection->getConstants();
60 3
        $constantsFound = array();
61
62
        //Loop through all URI's to list them in an array
63 3
        foreach ($constants as $constant) {
64 3
            $exploded = explode(":", $constant);
65 3
            if (count($exploded) == 1) {
66 3
                $exploded = ['item', $exploded[0]];
67
            }
68
69 3
            $name = strtolower($exploded[1]);
70 3
            $category = strtolower($exploded[0]);
71
72 3
            if (!isset($constantsFound[$name])) {
73 3
                $constantsFound[$name] = array();
74
            }
75 3
            $constantsFound[$name][$category] = $constant;
76
        }
77
78 3
        return $constantsFound;
79
    }
80
81 3
    public function setupFieldUris()
82
    {
83 3
        $this->unIndexedFieldUris = $this
84 3
            ->getFieldUrisFromClass(UnindexedFieldURIType::class);
85
86 3
        $this->dictionaryFieldUris = $this
87 3
            ->getFieldUrisFromClass(DictionaryURIType::class);
88
    }
89
90 3 View Code Duplication
    public function getFieldUriByName($fieldName, $preference = 'item')
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...
91
    {
92 3
        $fieldName = strtolower($fieldName);
93 3
        $preference = strtolower($preference);
94
95 3
        if (empty($this->unIndexedFieldUris)) {
96 3
            $this->setupFieldUris();
97
        }
98
99 3
        if (!isset($this->unIndexedFieldUris[$fieldName])) {
100
            return false;
101
        }
102
103 3
        if (!isset($this->unIndexedFieldUris[$fieldName][$preference])) {
104 1
            $preference = 'item';
105
        }
106
107 3
        if (!isset($this->unIndexedFieldUris[$fieldName][$preference])) {
108
            throw new ExchangeException("Could not find uri $preference:$fieldName");
109
        }
110
111 3
        return $this->unIndexedFieldUris[$fieldName][$preference];
112
    }
113
114 View Code Duplication
    public function getIndexedFieldUriByName($fieldName, $preference = 'item')
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...
115
    {
116
        $fieldName = strtolower($fieldName);
117
        $preference = strtolower($preference);
118
119
        if (empty($this->dictionaryFieldUris)) {
120
            $this->setupFieldUris();
121
        }
122
123
        if (!isset($this->dictionaryFieldUris[$fieldName])) {
124
            return false;
125
        }
126
127
        if (!isset($this->dictionaryFieldUris[$fieldName][$preference])) {
128
            $preference = 'item';
129
        }
130
131
        if (!isset($this->dictionaryFieldUris[$fieldName][$preference])) {
132
            throw new ExchangeException("Could not find uri $preference:$fieldName");
133
        }
134
135
        return $this->dictionaryFieldUris[$fieldName][$preference];
136
    }
137
138
    /**
139
     * Get a calendar item
140
     *
141
     * @param string $name
142
     * @return CalendarAPI
143
     */
144 6
    public function getCalendar($name = null)
145
    {
146 6
        $calendar = new CalendarAPI();
147 6
        $calendar->setClient($this->getClient());
148 6
        $calendar->pickCalendar($name);
149
150 6
        return $calendar;
151
    }
152
153
    /**
154
     * @param string $folderName
155
     * @return MailAPI
156
     */
157 6
    public function getMailbox($folderName = null)
158
    {
159 6
        $mailApi = new MailAPI();
160 6
        $mailApi->setClient($this->getClient());
161 6
        $mailApi->pickMailFolder($folderName);
162
163 6
        return $mailApi;
164
    }
165
166
    /**
167
     * Set the API client
168
     *
169
     * @param ExchangeWebServices $client
170
     * @return $this
171
     */
172 17
    public function setClient($client)
173
    {
174 17
        $this->client = $client;
175 17
        return $this;
176
    }
177
178
    /**
179
     * Get the API client
180
     *
181
     * @return ExchangeWebServices
182
     */
183 17
    public function getClient()
184
    {
185 17
        return $this->client;
186
    }
187
188
    /**
189
     * Instantiate and set a client (ExchangeWebServices) based on the parameters given
190
     *
191
     * @deprecated Since 0.6.3
192
     * @param $server
193
     * @param $username
194
     * @param $password
195
     * @param array $options
196
     * @return $this
197
     */
198 12
    public function buildClient(
199
        $server,
200
        $username,
201
        $password,
202
        $options = [ ]
203
    ) {
204 12
        $this->setClient(ExchangeWebServices::fromUsernameAndPassword(
205
            $server,
206
            $username,
207
            $password,
208 12
            array_replace_recursive(self::$defaultClientOptions, $options)
209
        ));
210
    }
211
212 5
    public static function withUsernameAndPassword($server, $username, $password, $options = [ ])
213
    {
214 5
        return new static(ExchangeWebServices::fromUsernameAndPassword(
215
            $server,
216
            $username,
217
            $password,
218 5
            array_replace_recursive(self::$defaultClientOptions, $options)
219
        ));
220
    }
221
222
    public static function withCallbackToken($server, $token, $options = [ ])
223
    {
224
        return new static(ExchangeWebServices::fromCallbackToken(
225
            $server,
226
            $token,
227
            array_replace_recursive(self::$defaultClientOptions, $options)
228
        ));
229
    }
230
231 1
    public function getPrimarySmptEmailAddress()
232
    {
233 1
        if ($this->getPrimarySmtpMailbox() == null) {
234 1
            return null;
235
        }
236
237 1
        return $this->getPrimarySmtpMailbox()->getEmailAddress();
238
    }
239
240 1
    public function setPrimarySmtpEmailAddress($emailAddress)
241
    {
242 1
        $this->getClient()->setPrimarySmtpEmailAddress($emailAddress);
243
244 1
        return $this;
245
    }
246
247
    /**
248
     * Create items through the API client
249
     *
250
     * @param $items
251
     * @param array $options
252
     * @return API\CreateItemResponseType
253
     */
254 8 View Code Duplication
    public function createItems($items, $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...
255
    {
256 8
        if (!is_array($items)) {
257
            $items = array($items);
258
        }
259
260
        $request = array(
261 8
            'Items' => $items
262
        );
263
264 8
        $request = array_replace_recursive($request, $options);
265 8
        $request = Type::buildFromArray($request);
266
267 8
        $response = $this->getClient()->CreateItem($request);
268
269 8
        return $response;
270
    }
271
272 2
    public function updateItems($items, $options = array())
273
    {
274
        $request = array(
275 2
            'ItemChanges' => $items,
276 2
            'MessageDisposition' => 'SaveOnly',
277 2
            'ConflictResolution' => 'AlwaysOverwrite'
278
        );
279
280 2
        $request = array_replace_recursive($request, $options);
281
282 2
        $request = Type::buildFromArray($request);
283
284 2
        return $this->getClient()->UpdateItem($request)->getItems();
0 ignored issues
show
Documentation Bug introduced by
The method getItems 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...
285
    }
286
287 2
    protected function buildUpdateItemChanges($itemType, $uriType, $changes)
288
    {
289 2
        $setItemFields = array();
290
291
        //Add each property to a setItemField
292 2
        foreach ($changes as $key => $value) {
293 2
            if (strpos($key, ':') !== false) {
294
                try {
295
                    $fieldUri = $this->getIndexedFieldUriByName(substr($key, 0, strpos($key, ':')), $uriType);
296
297
                    list ($key, $index) = explode(':', $key);
298
                    $fieldKey = key($value);
299
                    $value = $value[$fieldKey];
300
301
                    $setItemFields[] = array(
302
                        'IndexedFieldURI' => array('FieldURI' => $fieldUri, 'FieldIndex' => $index),
303
                        $itemType => array($fieldKey => $value)
304
                    );
305
                    continue;
306
                } catch (\Exception $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
307
                }
308
            }
309
310 2
            $fullName = $this->getFieldUriByName($key, $uriType);
311
312 2
            $setItemFields[] = array(
313 2
                'FieldURI' => array('FieldURI' => $fullName),
314 2
                $itemType => array($key => $value)
315
            );
316
        }
317
318 2
        return $setItemFields;
319
    }
320
321
    public function createFolders($names, Type\FolderIdType $parentFolder, $options = array())
322
    {
323
        $request = array('Folders' => array('Folder' => array()));
324
        if (!empty($parentFolder)) {
325
            $request['ParentFolderId'] = array('FolderId' => $parentFolder->toArray());
326
        }
327
328
        if (!is_array($names)) {
329
            $names = array($names);
330
        }
331
332
        foreach ($names as $name) {
333
            $request['Folders']['Folder'][] = array(
334
                'DisplayName' => $name
335
            );
336
        }
337
338
        $request = array_merge_recursive($request, $options);
339
340
        $this->client->CreateFolder($request);
0 ignored issues
show
Documentation Bug introduced by
The method CreateFolder does not exist on object<garethp\ews\API\ExchangeWebServices>? 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...
341
342
        return true;
343
    }
344
345 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...
346
    {
347
        $request = array(
348
            'DeleteType' => 'HardDelete',
349
            'FolderIds' => array(
350
                'FolderId' => $folderId->toArray()
351
            )
352
        );
353
354
        $request = array_merge_recursive($request, $options);
355
        return $this->client->DeleteFolder($request);
0 ignored issues
show
Documentation Bug introduced by
The method DeleteFolder does not exist on object<garethp\ews\API\ExchangeWebServices>? 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...
356
    }
357
358 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...
359
    {
360
        $request = array(
361
            'ToFolderId' => array('FolderId' => $folderId->toArray()),
362
            'ItemIds' => array('ItemId' => $itemId->toArray())
363
        );
364
365
        $request = array_merge_recursive($request, $options);
366
367
        return $this->client->MoveItem($request);
0 ignored issues
show
Documentation Bug introduced by
The method MoveItem does not exist on object<garethp\ews\API\ExchangeWebServices>? 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...
368
    }
369
370
    /**
371
     * @param $items Type\ItemIdType|Type\ItemIdType[]
372
     * @param array $options
373
     * @return bool
374
     */
375 8
    public function deleteItems($items, $options = array())
376
    {
377 8
        if (!is_array($items) || Type::arrayIsAssoc($items)) {
378 8
            $items = array($items);
379
        }
380
381 8
        $itemIds = array();
382 8
        foreach ($items as $item) {
383 8
            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...
384 7
                $item = $item->toArray();
385
            }
386 8
            $item = (array) $item;
387 8
            $itemIds[] = array(
388 8
                'Id' => $item['Id'],
389 8
                'ChangeKey' => $item['ChangeKey']
390
            );
391
        }
392
393
        $request = array(
394 8
            'ItemIds' => array('ItemId' => $itemIds),
395 8
            'DeleteType' => 'MoveToDeletedItems'
396
        );
397
398 8
        $request = array_replace_recursive($request, $options);
399 8
        $request = Type::buildFromArray($request);
400 8
        $this->getClient()->DeleteItem($request);
401
402
        //If the delete fails, an Exception will be thrown in processResponse before it gets here
403 8
        return true;
404
    }
405
406
    /**
407
     * @param $identifier
408
     * @return Type\BaseFolderType
409
     */
410 15
    public function getFolder($identifier)
411
    {
412
        $request = array(
413
            'FolderShape' => array(
414
                'BaseShape' => array('_' => 'Default')
415 15
            ),
416 15
            'FolderIds' => $identifier
417
        );
418 15
        $request = Type::buildFromArray($request);
419
420 15
        $response = $this->getClient()->GetFolder($request);
421 15
        return $response;
422
    }
423
424
    /**
425
     * Get a folder by it's distinguishedId
426
     *
427
     * @param string $distinguishedId
428
     * @return Type\BaseFolderType
429
     */
430 15
    public function getFolderByDistinguishedId($distinguishedId)
431
    {
432 15
        return $this->getFolder(array(
433
            'DistinguishedFolderId' => array(
434 15
                'Id' => $distinguishedId,
435 15
                'Mailbox' => $this->getPrimarySmtpMailbox()
436
            )
437
        ));
438
    }
439
440
    /**
441
     * @param $folderId
442
     * @return Type\BaseFolderType
443
     */
444 4
    public function getFolderByFolderId($folderId)
445
    {
446 4
        return $this->getFolder(array(
447 4
            'FolderId' => array('Id'=>$folderId, 'Mailbox' => $this->getPrimarySmtpMailbox())
448
        ));
449
    }
450
451
    /**
452
     * @param string|Type\FolderIdType $parentFolderId
453
     * @param array $options
454
     * @return bool|Type\BaseFolderType
455
     */
456 15
    public function getChildrenFolders($parentFolderId = 'root', $options = array())
457
    {
458 15
        if (is_string($parentFolderId)) {
459 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...
460
        }
461
462
        $request = array(
463 15
            'Traversal' => 'Shallow',
464
            'FolderShape' => array(
465
                'BaseShape' => 'AllProperties'
466
            ),
467
            'ParentFolderIds' => array(
468 15
                'FolderId' => $parentFolderId->toArray()
469
            )
470
        );
471
472 15
        $request = array_replace_recursive($request, $options);
473
474 15
        $request = Type::buildFromArray($request);
475
476
        /** @var \garethp\ews\API\Message\FindFolderResponseMessageType $folders */
477 15
        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...
478
        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...
479
    }
480
481
    /**
482
     * @param $folderName
483
     * @param string|Type\FolderIdType $parentFolderId
484
     * @param array $options
485
     * @return bool|Type\BaseFolderType
486
     */
487 15
    public function getFolderByDisplayName($folderName, $parentFolderId = 'root', $options = array())
488
    {
489 15
        $folders = $this->getChildrenFolders($parentFolderId, $options);
490
491 15
        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...
492 15
            if ($folder->getDisplayName() == $folderName) {
493 15
                return $folder;
494
            }
495
        }
496
497 1
        return false;
498
    }
499
500
    /**
501
     * @param $itemId array|Type\ItemIdType
502
     * @param array $options
503
     * @return Type
504
     */
505 1
    public function getItem($itemId, $options = array())
506
    {
507 1
        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...
508
            $itemId = $itemId->toArray();
509
        }
510
511
        $request = array(
512 1
            'ItemShape' => array('BaseShape' => 'AllProperties'),
513 1
            'ItemIds' => array('ItemId' => $itemId)
514
        );
515
516 1
        $request = array_replace_recursive($request, $options);
517
518 1
        return $this->getClient()->GetItem($request);
519
    }
520
521
    /**
522
     * Get a list of sync changes on a folder
523
     *
524
     * @param Type\FolderIdType $folderId
525
     * @param null $syncState
526
     * @param array $options
527
     * @return SyncFolderItemsResponseMessageType
528
     */
529 2
    public function listItemChanges($folderId, $syncState = null, $options = array())
530
    {
531
        $request = array(
532 2
            'ItemShape' => array('BaseShape' => 'IdOnly'),
533 2
            'SyncFolderId' => array('FolderId' => $folderId->toXmlObject()),
534 2
            'SyncScope' => 'NormalItems',
535 2
            'MaxChangesReturned' => '10'
536
        );
537
538 2
        if ($syncState != null) {
539 1
            $request['SyncState'] = $syncState;
540 1
            $request['ItemShape']['BaseShape'] = 'AllProperties';
541
        }
542
543 2
        $request = array_replace_recursive($request, $options);
544
545 2
        $request = Type::buildFromArray($request);
546 2
        $response = $this->getClient()->SyncFolderItems($request);
547 2
        return $response;
548
    }
549
550 View Code Duplication
    public function getServerTimezones($timezoneIDs = array(), $fullTimezoneData = false)
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...
551
    {
552
        $request = GetServerTimeZonesType::buildFromArray(array(
553
            'returnFullTimeZoneData' => $fullTimezoneData
554
        ));
555
556
        if (!empty($timezoneIDs)) {
557
            $request->setIds($timezoneIDs);
558
        }
559
560
        $timezones = $this->getClient()->GetServerTimeZones($request);
0 ignored issues
show
Documentation Bug introduced by
The method GetServerTimeZones does not exist on object<garethp\ews\API\ExchangeWebServices>? 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...
561
        $timezones = $timezones->TimeZoneDefinition;
562
563
        if (!is_array($timezones)) {
564
            $timezones = array($timezones);
565
        }
566
567
        return $timezones;
568
    }
569
570
    /**
571
     * @param Type\ItemIdType $itemId
572
     * @param $fromType
573
     * @param $destinationType
574
     * @param $mailbox
575
     *
576
     * @return Type\ItemIdType
577
     */
578
    public function convertIdFormat(Type\ItemIdType $itemId, $fromType, $destinationType, $mailbox)
579
    {
580
        $result = $this->getClient()->ConvertId(array(
0 ignored issues
show
Documentation Bug introduced by
The method ConvertId does not exist on object<garethp\ews\API\ExchangeWebServices>? 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...
581
            'DestinationFormat' => $destinationType,
582
            'SourceIds' => array (
583
                'AlternateId' => array(
584
                    'Format' => $fromType,
585
                    'Id' => $itemId->getId(),
586
                    'Mailbox' => $mailbox
587
                )
588
            )
589
        ));
590
591
        $itemId->setId($result->getId());
592
593
        return $itemId;
594
    }
595
}
596