CalendarAPI::listChanges()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
nc 1
nop 2
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 1
b 0
f 0
1
<?php
2
3
namespace garethp\ews;
4
5
use DateTime;
6
use garethp\ews\API\Enumeration;
7
use garethp\ews\API\Exception\ExchangeException;
8
use garethp\ews\API\Message\FreeBusyResponseType;
9
use garethp\ews\API\Type;
10
use garethp\ews\API\Type\CalendarItemType;
11
12
/**
13
 * An API end point for Calendar items
14
 *
15
 * Class API
16
 * @package garethp\ews\Calendar
17
 */
18
class CalendarAPI extends API
19
{
20
    /**
21
     * @var Type\BaseFolderIdType
22
     */
23
    protected $folderId;
24
25
    /**
26
     * Pick a Calendar based on it's name
27
     *
28
     * @param string|null $displayName
29
     * @return $this
30
     */
31 6
    public function pickCalendar($displayName = null)
32
    {
33 6
        if ($displayName == 'default.calendar' || $displayName == null) {
0 ignored issues
show
Bug introduced by
It seems like you are loosely comparing $displayName of type null|string against null; this is ambiguous if the string can be empty. Consider using a strict comparison === instead.
Loading history...
34 1
            $this->folderId = $this->getDistinguishedFolderId('calendar');
35
        } else {
36 6
            $this->folderId = $this->getFolderByDisplayName($displayName, 'calendar')->getFolderId();
37
        }
38
39 6
        return $this;
40
    }
41
42
    /**
43
     * @return Type\BaseFolderIdType
44
     */
45 6
    public function getFolderId()
46
    {
47 6
        if ($this->folderId === null) {
48
            $this->pickCalendar();
49
        }
50
51 6
        return $this->folderId;
52
    }
53
54
    /**
55
     * @param Type\BaseFolderIdType $folderId
56
     * @return $this
57
     */
58
    public function setFolderId($folderId)
59
    {
60
        $this->folderId = $folderId;
61
62
        return $this;
63
    }
64
65
    /**
66
     * Create one or more calendar items
67
     *
68
     * @param $items CalendarItemType[]|CalendarItemType|array or more calendar items to create
69
     * @param $options array Options to merge in to the request
70
     * @return Type\ItemIdType[]
71
     */
72 3
    public function createCalendarItems($items, $options = array())
73
    {
74 3
        $items = Utilities\ensureIsArray($items, true);
75 3
        $item = array('CalendarItem' => $items);
76 3
        $defaultOptions = array(
77 3
            'SendMeetingInvitations' => Enumeration\CalendarItemCreateOrDeleteOperationType::SEND_TO_NONE,
78 3
            'SavedItemFolderId' => $this->getFolderId()->toArray(true)
79 3
        );
80
81 3
        $options = array_replace_recursive($defaultOptions, $options);
82
83 3
        $items = $this->createItems($item, $options);
84 3
        return Utilities\ensureIsArray($items);
85
    }
86
87
    /**
88
     * Get a list of calendar items between two dates/times
89
     *
90
     * @param string|DateTime $start
91
     * @param string|DateTime $end
92
     * @param array $options
93
     * @return CalendarItemType[]|Type\FindItemParentType
94
     */
95 6
    public function getCalendarItems($start = '12:00 AM', $end = '11:59 PM', $options = array())
96
    {
97 6
        $start = Utilities\ensureIsDateTime($start);
98 6
        $end = Utilities\ensureIsDateTime($end);
99
100 6
        $request = [
101 6
            'Traversal' => 'Shallow',
102 6
            'ItemShape' => [
103 6
                'BaseShape' => 'AllProperties'
104 6
            ],
105 6
            'CalendarView' => [
106 6
                'MaxEntriesReturned' => 100,
107 6
                'StartDate' => $start->format('c'),
108 6
                'EndDate' => $end->format('c')
109 6
            ],
110 6
            'ParentFolderIds' => $this->getFolderId()->toArray(true)
111 6
        ];
112
113 6
        $request = array_replace_recursive($request, $options);
114
115 6
        $request = Type::buildFromArray($request);
116 6
        $response = $this->getClient()->FindItem($request);
117 6
        $items = $response;
118
119 6
        return $items;
120
    }
121
122
    /**
123
     * @param $id
124
     * @param $changeKey
125
     * @param array $options
126
     * @return Type\CalendarItemType
127
     */
128 1
    public function getCalendarItem($id, $changeKey, $options = [])
129
    {
130 1
        return $this->getItem(['Id' => $id, 'ChangeKey' => $changeKey], $options);
131
    }
132
133
    /**
134
     * Updates a calendar item with changes
135
     *
136
     * @param $itemId Type\ItemIdType
137
     * @param array $changes
138
     * @param array $options
139
     * @return Type\CalendarItemType[]
140
     */
141 1
    public function updateCalendarItem(Type\ItemIdType $itemId, $changes, $options = array())
142
    {
143
        //Create the request
144 1
        $request = [
145 1
            'ItemChange' => [
146 1
                'ItemId' => $itemId->toArray(),
147 1
                'Updates' => API\ItemUpdateBuilder::buildUpdateItemChanges('CalendarItem', 'calendar', $changes)
148 1
            ]
149 1
        ];
150
151 1
        $defaultOptions = [
152 1
            'SendMeetingInvitationsOrCancellations' => 'SendToNone'
153 1
        ];
154
155 1
        $options = array_replace_recursive($defaultOptions, $options);
156 1
        $items = $this->updateItems($request, $options)->getCalendarItem();
157 1
        return Utilities\ensureIsArray($items);
158
    }
159
160
    /**
161
     * @param Type\ItemIdType $itemId
162
     * @param array $options
163
     * @return bool
164
     */
165 3
    public function deleteCalendarItem(Type\ItemIdType $itemId, $options = array())
166
    {
167 3
        $defaultOptions = array(
168 3
            'SendMeetingCancellations' => 'SendToNone'
169 3
        );
170
171 3
        $options = array_replace_recursive($defaultOptions, $options);
172 3
        return $this->deleteItems($itemId, $options);
173
    }
174
175
    /**
176
     * @param string $start
177
     * @param string $end
178
     * @param array $options
179
     */
180 6
    public function deleteAllCalendarItems($start = '12:00 AM', $end = '11:59 PM', $options = array())
181
    {
182 6
        $items = $this->getCalendarItems($start, $end, $options);
183 6
        foreach ($items as $item) {
184 2
            $this->deleteCalendarItem($item->getItemId());
185
        }
186
    }
187
188
    /**
189
     * Get a list of changes on the calendar items
190
     *
191
     * @param null $syncState
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $syncState is correct as it would always require null to be passed?
Loading history...
192
     * @param array $options
193
     * @return API\Message\SyncFolderItemsResponseMessageType
194
     */
195 1
    public function listChanges($syncState = null, $options = array())
196
    {
197 1
        return parent::listItemChanges($this->getFolderId(), $syncState, $options);
198
    }
199
200
    /**
201
     * @param Type\ItemIdType $itemId
202
     * @param string $message
203
     * @param string $sensitivity
204
     * @param array $options
205
     *
206
     * @return Type\ItemIdType[]
207
     */
208
    public function acceptMeeting($itemId, $message, $sensitivity = 'Private', $options = array())
209
    {
210
        $request = [
211
            'AcceptItem' => [
212
                'Sensitivity' => $sensitivity,
213
                'Body' => ['BodyType' => 'HTML', '_value' => $message],
214
                'ReferenceItemId' => $itemId->toArray()
215
            ]
216
        ];
217
218
        $defaultOptions = ['MessageDisposition' => 'SendOnly'];
219
        $options = array_replace_recursive($defaultOptions, $options);
220
221
        $return = $this->createItems($request, $options)->getCalendarItem();
0 ignored issues
show
Bug introduced by
The method getCalendarItem() does not exist on garethp\ews\API\Type. It seems like you code against a sub-type of garethp\ews\API\Type such as garethp\ews\API\Type\ArrayOfRealItemsType or garethp\ews\API\Type\NonEmptyArrayOfAllItemsType or garethp\ews\API\Type\Syn...ItemsCreateOrUpdateType or garethp\ews\API\Type\ItemAttachmentType or garethp\ews\API\Type\SetItemFieldType or garethp\ews\API\Type\AppendToItemFieldType. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

221
        $return = $this->createItems($request, $options)->/** @scrutinizer ignore-call */ getCalendarItem();
Loading history...
222
        return Utilities\ensureIsArray($return);
223
    }
224
225
    /**
226
     * @param $itemId
227
     * @param $message
228
     * @param string $sensitivity
229
     * @param array $options
230
     * @return Type\ItemIdType[]
231
     */
232
    public function declineMeeting($itemId, $message, $sensitivity = 'Private', $options = array())
233
    {
234
        $request = [
235
            'DeclineItem' => [
236
                'Sensitivity' => $sensitivity,
237
                'Body' => ['BodyType' => 'HTML', '_value' => $message],
238
                'ReferenceItemId' => $itemId->toArray()
239
            ]
240
        ];
241
242
        $defaultOptions = array('MessageDisposition' => 'SendOnly');
243
        $options = array_replace_recursive($defaultOptions, $options);
244
245
        $return = $this->createItems($request, $options)->getCalendarItem();
246
        return Utilities\ensureIsArray($return);
247
    }
248
249
    /**
250
     * @param $startTime
251
     * @param $endTime
252
     * @param array $users
253
     * @param array $options
254
     *
255
     * @return API\Message\GetUserAvailabilityResponseType
256
     */
257
    public function getAvailabilityFor($startTime, $endTime, array $users, array $options = array())
258
    {
259
        $startTime = Utilities\ensureIsDateTime($startTime);
260
        $endTime = Utilities\ensureIsDateTime($endTime);
261
262
        $request = [
263
            'MailboxDataArray' => ['MailboxData' => []],
264
            'FreeBusyViewOptions' => [
265
                'TimeWindow' => [
266
                    'StartTime' => $startTime->format('c'),
267
                    'EndTime' => $endTime->format('c'),
268
                ],
269
                'RequestedView' => 'FreeBusyMerged',
270
                'MergedFreeBusyIntervalInMinutes' => 30
271
            ],
272
        ];
273
274
        $users = array_map(function ($user) {
275
            return [
276
                'Email' => ['Address' => $user],
277
                'AttendeeType' => 'Required',
278
                'ExcludeConflicts' => false
279
            ];
280
        }, $users);
281
282
        $request['MailboxDataArray']['MailboxData'] = $users;
283
284
        $request = array_replace_recursive($request, $options);
285
        $response = $this->getClient()->GetUserAvailability($request);
286
        return $response;
287
    }
288
289
    /**
290
     * @param $startTime
291
     * @param $endTime
292
     * @param int $period The period of time to see if users of free for (in minutes)
293
     * @param array $users
294
     * @param array $options
295
     *
296
     * @return boolean
297
     * @throws ExchangeException
298
     */
299
    public function areAvailable($startTime, $endTime, $period, array $users, array $options = [])
300
    {
301
        $options = array_replace_recursive($options, [
302
            'FreeBusyViewOptions' => [
303
                'MergedFreeBusyIntervalInMinutes' => $period, 'RequestedView' => 'MergedOnly'
304
            ]]);
305
        $availability = $this->getAvailabilityFor($startTime, $endTime, $users, $options);
306
307
        $responseMessage = $availability->getFreeBusyResponseArray()->FreeBusyResponse->getResponseMessage();
308
        if ($responseMessage->getResponseClass() === 'Error') {
309
            throw new ExchangeException($responseMessage);
310
        }
311
312
        $availabilities = array_map(function (FreeBusyResponseType $freeBusyResponseType) {
313
            return str_split($freeBusyResponseType->getFreeBusyView()->getMergedFreeBusy());
314
        }, $availability->getFreeBusyResponseArray()->FreeBusyResponse);
315
316
        foreach ($availabilities[0] as $periodIndex => $availability) {
317
            if ($availability != 0) {
318
                continue;
319
            }
320
321
            $free = true;
322
            foreach ($availabilities as $userAvailability) {
323
                if ($userAvailability[$periodIndex] != 0) {
324
                    $free = false;
325
                    break;
326
                }
327
            }
328
329
            if ($free === false) {
330
                continue;
331
            }
332
333
            return true;
334
        }
335
336
        return false;
337
    }
338
}
339