Completed
Push — master ( 1447a4...7d0c17 )
by Gareth
11:28 queued 08:32
created

API::listItemChanges()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 21
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 2

Importance

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