Completed
Push — master ( 9a3ace...8909a0 )
by Gareth
06:20
created

API::setClient()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 5
ccs 3
cts 3
cp 1
rs 9.4286
cc 1
eloc 3
nc 1
nop 1
crap 1
1
<?php
2
3
namespace jamesiarmes\PEWS;
4
5
use jamesiarmes\PEWS\API\ExchangeWebServices;
6
use jamesiarmes\PEWS\API\ExchangeWebServicesAuth;
7
use jamesiarmes\PEWS\API\Type;
8
use jamesiarmes\PEWS\Calendar\CalendarAPI;
9
use jamesiarmes\PEWS\Mail\MailAPI;
10
11
/**
12
 * A base class for APIs
13
 *
14
 * Class BaseAPI
15
 * @package jamesiarmes\PEWS
16
 */
17
class API
18
{
19
    protected static $defaultClientOptions = array(
20
        'version' => ExchangeWebServices::VERSION_2010
21
    );
22
23 23
    public function __construct(ExchangeWebServices $client = null)
24
    {
25 23
        if ($client) {
26 10
            $this->setClient($client);
27 10
        }
28 23
    }
29
30
    /**
31
     * @return Type\EmailAddressType
32
     */
33 15
    public function getPrimarySmtpMailbox()
34
    {
35 15
        return $this->getClient()->getPrimarySmtpMailbox();
36
    }
37
38
    private $fieldUris = array();
39
40
    /**
41
     * Storing the API client
42
     * @var ExchangeWebServices
43
     */
44
    private $client;
45
46 4
    public function setupFieldUris()
47
    {
48
        //So, since we have to pass in URI's of everything we update, we need to fetch them
49 4
        $reflection = new \ReflectionClass('jamesiarmes\PEWS\API\Enumeration\UnindexedFieldURIType');
50 4
        $constants = $reflection->getConstants();
51 4
        $constantsFound = array();
52
53
        //Loop through all URI's to list them in an array
54 4
        foreach ($constants as $constant) {
55 4
            $exploded = explode(":", $constant);
56 4
            if (count($exploded) == 1) {
57 4
                $exploded = ['item', $exploded[0]];
58 4
            }
59
60 4
            $name = strtolower($exploded[1]);
61 4
            $category = strtolower($exploded[0]);
62
63 4
            if (!isset($constantsFound[$name])) {
64 4
                $constantsFound[$name] = array();
65 4
            }
66 4
            $constantsFound[$name][$category] = $constant;
67 4
        }
68
69 4
        $this->fieldUris = $constantsFound;
70 4
    }
71
72 4
    public function getFieldUriByName($fieldName, $preference = 'item')
73
    {
74 4
        $fieldName = strtolower($fieldName);
75 4
        $preference = strtolower($preference);
76
77 4
        if (empty($this->fieldUris)) {
78 4
            $this->setupFieldUris();
79 4
        }
80
81 4
        if (!isset($this->fieldUris[$fieldName])) {
82 1
            return false;
83
        }
84
85 4
        if (!isset($this->fieldUris[$fieldName][$preference])) {
86 1
            $preference = 'item';
87 1
        }
88
89 4
        if (!isset($this->fieldUris[$fieldName][$preference])) {
90
            throw new \Exception("Could not find uri $preference:$fieldName");
91
        }
92
93 4
        return $this->fieldUris[$fieldName][$preference];
94
    }
95
96
    /**
97
     * Get a calendar item
98
     *
99
     * @param string $name
100
     * @return CalendarAPI
101
     */
102 6
    public function getCalendar($name = null)
103
    {
104 6
        $calendar = new CalendarAPI();
105 6
        $calendar->setClient($this->getClient());
106 6
        $calendar->pickCalendar($name);
107
108 6
        return $calendar;
109
    }
110
111
    /**
112
     * @param string $folderName
113
     * @return MailAPI
114
     */
115 8
    public function getMailbox($folderName = null)
116
    {
117 8
        $mailApi = new MailAPI();
118 6
        $mailApi->setClient($this->getClient());
119 6
        $mailApi->pickMailFolder($folderName);
120
121 6
        return $mailApi;
122
    }
123
124
    /**
125
     * Set the API client
126
     *
127
     * @param ExchangeWebServices $client
128
     * @return $this
129
     */
130 23
    public function setClient($client)
131
    {
132 23
        $this->client = $client;
133 23
        return $this;
134
    }
135
136
    /**
137
     * Get the API client
138
     *
139
     * @return ExchangeWebServices
140
     */
141 22
    public function getClient()
142
    {
143 22
        return $this->client;
144
    }
145
146
    /**
147
     * Instantiate and set a client (ExchangeWebServices) based on the parameters given
148
     *
149
     * @deprecated Since 0.6.3
150
     * @param $server
151
     * @param $username
152
     * @param $password
153
     * @param array $options
154
     * @return $this
155
     */
156
    public function buildClient(
157
        $server,
158
        $username,
159
        $password,
160
        $options = [ ]
161
    ) {
162
        $this->setClient(ExchangeWebServices::fromUsernameAndPassword(
163
            $server,
164
            $username,
165
            $password,
166
            array_replace_recursive(self::$defaultClientOptions, $options)
167
        ));
168
    }
169
170 9
    public static function withUsernameAndPassword($server, $username, $password, $options = [ ])
171
    {
172 9
        return new static(ExchangeWebServices::fromUsernameAndPassword(
173 9
            $server,
174 9
            $username,
175 9
            $password,
176 9
            array_replace_recursive(self::$defaultClientOptions, $options)
177 9
        ));
178
    }
179
180 1
    public static function withCallbackToken($server, $token, $options = [ ])
181
    {
182 1
        return new static(ExchangeWebServices::fromCallbackToken(
183 1
            $server,
184 1
            $token,
185 1
            array_replace_recursive(self::$defaultClientOptions, $options)
186 1
        ));
187
    }
188
189
    public function getPrimarySmptEmailAddress()
190
    {
191
        if ($this->getPrimarySmtpMailbox() == null) {
192
            return null;
193
        }
194
195
        return $this->getPrimarySmtpMailbox()->getEmailAddress();
196
    }
197
198
    public function setPrimarySmtpEmailAddress($emailAddress)
199
    {
200
        $this->getClient()->setPrimarySmtpEmailAddress($emailAddress);
201
202
        return $this;
203
    }
204
205
    /**
206
     * Create items through the API client
207
     *
208
     * @param $items
209
     * @param array $options
210
     * @return API\CreateItemResponseType
211
     */
212 9
    public function createItems($items, $options = array())
213
    {
214 9
        if (!is_array($items)) {
215
            $items = array($items);
216
        }
217
218
        $request = array(
219
            'Items' => $items
220 9
        );
221
222 9
        $request = array_replace_recursive($request, $options);
223 9
        $request = Type::buildFromArray($request);
224
225 9
        $response = $this->getClient()->CreateItem($request);
226
227 9
        return $response;
228
    }
229
230 2
    public function updateItems($items, $options = array())
231
    {
232
        $request = array(
233 2
            'ItemChanges' => $items,
234 2
            'MessageDisposition' => 'SaveOnly',
235
            'ConflictResolution' => 'AlwaysOverwrite'
236 2
        );
237
238 2
        $request = array_replace_recursive($request, $options);
239
240 2
        $request = Type::buildFromArray($request);
241
242 2
        return $this->getClient()->UpdateItem($request)->getItems();
0 ignored issues
show
Documentation Bug introduced by
The method getItems does not exist on object<jamesiarmes\PEWS\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...
243
    }
244
245 2
    protected function buildUpdateItemChanges($itemType, $uriType, $changes)
246
    {
247 2
        $setItemFields = array();
248
249
        //Add each property to a setItemField
250 2
        foreach ($changes as $key => $value) {
251 2
            $fullName = $this->getFieldUriByName($key, $uriType);
252
253 2
            $setItemFields[] = array(
254 2
                'FieldURI' => array('FieldURI' => $fullName),
255 2
                $itemType => array($key => $value)
256 2
            );
257 2
        }
258
259 2
        return $setItemFields;
260
    }
261
262
    public function createFolders($names, Type\FolderIdType $parentFolder, $options = array())
263
    {
264
        $request = array('Folders' => array('Folder' => array()));
265
        if (!empty($parentFolder)) {
266
            $request['ParentFolderId'] = array('FolderId' => $parentFolder->toArray());
267
        }
268
269
        if (!is_array($names)) {
270
            $names = array($names);
271
        }
272
273
        foreach ($names as $name) {
274
            $request['Folders']['Folder'][] = array(
275
                'DisplayName' => $name
276
            );
277
        }
278
279
        $request = array_merge_recursive($request, $options);
280
281
        $this->client->CreateFolder($request);
0 ignored issues
show
Documentation Bug introduced by
The method CreateFolder does not exist on object<jamesiarmes\PEWS\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...
282
283
        return true;
284
    }
285
286
    public function moveItem(Type\ItemIdType $itemId, Type\FolderIdType $folderId, $options = array())
287
    {
288
        $request = array(
289
            'ToFolderId' => array('FolderId' => $folderId->toArray()),
290
            'ItemIds' => array('ItemId' => $itemId->toArray())
291
        );
292
293
        $request = array_merge_recursive($request, $options);
294
295
        return $this->client->MoveItem($request);
0 ignored issues
show
Documentation Bug introduced by
The method MoveItem does not exist on object<jamesiarmes\PEWS\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...
296
    }
297
298
    /**
299
     * @param $items Type\ItemIdType|Type\ItemIdType[]
300
     * @param array $options
301
     * @return bool
302
     */
303 8
    public function deleteItems($items, $options = array())
304
    {
305 8
        if (!is_array($items) || Type::arrayIsAssoc($items)) {
306 8
            $items = array($items);
307 8
        }
308
309 8
        $itemIds = array();
310 8
        foreach ($items as $item) {
311 8
            if ($item instanceof Type\ItemIdType) {
0 ignored issues
show
Bug introduced by
The class jamesiarmes\PEWS\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...
312 7
                $item = $item->toArray();
313 7
            }
314 8
            $item = (array) $item;
315 8
            $itemIds[] = array(
316 8
                'Id' => $item['Id'],
317 8
                'ChangeKey' => $item['ChangeKey']
318 8
            );
319 8
        }
320
321
        $request = array(
322 8
            'ItemIds' => array('ItemId' => $itemIds),
323
            'DeleteType' => 'MoveToDeletedItems'
324 8
        );
325
326 8
        $request = array_replace_recursive($request, $options);
327 8
        $request = Type::buildFromArray($request);
328 8
        $this->getClient()->DeleteItem($request);
329
330
        //If the delete fails, an Exception will be thrown in processResponse before it gets here
331 8
        return true;
332
    }
333
334
    /**
335
     * @param $identifier
336
     * @return Type\BaseFolderType
337
     */
338 15
    public function getFolder($identifier)
339
    {
340
        $request = array(
341
            'FolderShape' => array(
342 15
                'BaseShape' => array('_' => 'Default')
343 15
            ),
344
            'FolderIds' => $identifier
345 15
        );
346 15
        $request = Type::buildFromArray($request);
347
348 15
        $response = $this->getClient()->GetFolder($request);
349 15
        return $response;
350
    }
351
352
    /**
353
     * Get a folder by it's distinguishedId
354
     *
355
     * @param string $distinguishedId
356
     * @return Type\BaseFolderType
357
     */
358 15
    public function getFolderByDistinguishedId($distinguishedId)
359
    {
360 15
        return $this->getFolder(array(
361
            'DistinguishedFolderId' => array(
362 15
                'Id' => $distinguishedId,
363 15
                'Mailbox' => $this->getPrimarySmtpMailbox()
364 15
            )
365 15
        ));
366
    }
367
368
    /**
369
     * @param $folderId
370
     * @return Type\BaseFolderType
371
     */
372 4
    public function getFolderByFolderId($folderId)
373
    {
374 4
        return $this->getFolder(array(
375 4
            'FolderId' => array('Id'=>$folderId, 'Mailbox' => $this->getPrimarySmtpMailbox())
376 4
        ));
377
    }
378
379
    /**
380
     * @param $folderName
381
     * @param string|Type\FolderIdType $parentFolderId
382
     * @param array $options
383
     * @return bool|Type\BaseFolderType
384
     */
385 14
    public function getFolderByDisplayName($folderName, $parentFolderId = 'root', $options = array())
386
    {
387 14
        if (is_string($parentFolderId)) {
388 14
            $parentFolderId = $this->getFolderByDistinguishedId($parentFolderId)->getFolderId();
0 ignored issues
show
Documentation Bug introduced by
The method getFolderId does not exist on object<jamesiarmes\PEWS\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...
389 14
        }
390
391
        $request = array(
392 14
            'Traversal' => 'Shallow',
393
            'FolderShape' => array(
394
                'BaseShape' => 'AllProperties'
395 14
            ),
396
            'ParentFolderIds' => array(
397 14
                'FolderId' => $parentFolderId->toArray()
398 14
            )
399 14
        );
400
401 14
        $request = array_replace_recursive($request, $options);
402
403 14
        $request = Type::buildFromArray($request);
404
405
        /** @var \jamesiarmes\PEWS\API\Message\FindFolderResponseMessageType $folders */
406 14
        $folders = $this->getClient()->FindFolder($request);
407 14
        $folders = $folders->getFolders();
408
409 14
        foreach ($folders->getAllFolders() as $folder) {
410 14
            if ($folder->getDisplayName() == $folderName) {
411 14
                return $folder;
412
            }
413 13
        }
414
415
        return false;
416
    }
417
418
    /**
419
     * @param $itemId array|Type\ItemIdType
420
     * @param array $options
421
     * @return Type
422
     */
423 1
    public function getItem($itemId, $options = array())
424
    {
425 1
        if ($itemId instanceof Type\ItemIdType) {
0 ignored issues
show
Bug introduced by
The class jamesiarmes\PEWS\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...
426
            $itemId = $itemId->toArray();
427
        }
428
429
        $request = array(
430 1
            'ItemShape' => array('BaseShape' => 'AllProperties'),
431 1
            'ItemIds' => array('ItemId' => $itemId)
432 1
        );
433
434 1
        $request = array_replace_recursive($request, $options);
435
436 1
        return $this->getClient()->GetItem($request);
437
    }
438
439
    /**
440
     * Get a list of sync changes on a folder
441
     *
442
     * @param Type\FolderIdType $folderId
443
     * @param null $syncState
444
     * @param array $options
445
     * @return mixed
446
     */
447 2
    public function listItemChanges($folderId, $syncState = null, $options = array())
448
    {
449
        $request = array(
450 2
            'ItemShape' => array('BaseShape' => 'IdOnly'),
451 2
            'SyncFolderId' => array('FolderId' => $folderId->toXmlObject()),
452 2
            'SyncScope' => 'NormalItems',
453
            'MaxChangesReturned' => '10'
454 2
        );
455
456 2
        if ($syncState != null) {
457
            $request['SyncState'] = $syncState;
458
            $request['ItemShape']['BaseShape'] = 'AllProperties';
459
        }
460
461 2
        $request = array_replace_recursive($request, $options);
462
463 2
        $request = Type::buildFromArray($request);
464 2
        $response = $this->getClient()->SyncFolderItems($request);
465 2
        return $response;
466
    }
467
}
468