Completed
Push — master ( 9a8ecb...d328d0 )
by Gareth
02:37
created

CalendarAPI::listChanges()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 2
crap 1
1
<?php
2
3
namespace garethp\ews;
4
5
use DateTime;
6
use garethp\ews\API\Enumeration;
7
use garethp\ews\API\Message\FreeBusyResponseType;
8
use garethp\ews\API\Type;
9
use garethp\ews\API\Type\CalendarItemType;
10
11
/**
12
 * An API end point for Calendar items
13
 *
14
 * Class API
15
 * @package garethp\ews\Calendar
16
 */
17
class CalendarAPI extends API
18
{
19
    /**
20
     * @var Type\BaseFolderIdType
21
     */
22
    protected $folderId;
23
24
    /**
25
     * Pick a Calendar based on it's name
26
     *
27
     * @param string|null $displayName
28
     * @return $this
29
     */
30 6
    public function pickCalendar($displayName = null)
31
    {
32 6 View Code Duplication
        if ($displayName == 'default.calendar' || $displayName == null) {
33 1
            $this->folderId = $this->getDistinguishedFolderId('calendar');
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->getDistinguishedFolderId('calendar') of type object<garethp\ews\API\T...tinguishedFolderIdType> is incompatible with the declared type object<garethp\ews\API\Type\BaseFolderIdType> of property $folderId.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
34 1
        } else {
35 6
            $this->folderId = $this->getFolderByDisplayName($displayName, 'calendar')->getFolderId();
36
        }
37
38 6
        return $this;
39
    }
40
41
    /**
42
     * @return Type\BaseFolderIdType
43
     */
44 6
    public function getFolderId()
45
    {
46 6
        if ($this->folderId === null) {
47
            $this->pickCalendar();
48
        }
49
50 6
        return $this->folderId;
51
    }
52
53
    /**
54
     * @param Type\BaseFolderIdType $folderId
55
     * @return $this
56
     */
57
    public function setFolderId($folderId)
58
    {
59
        $this->folderId = $folderId;
60
61
        return $this;
62
    }
63
64
    /**
65
     * Create one or more calendar items
66
     *
67
     * @param $items CalendarItemType[]|CalendarItemType|array or more calendar items to create
68
     * @param $options array Options to merge in to the request
69
     * @return Type\ItemIdType[]
70
     */
71 3
    public function createCalendarItems($items, $options = array())
72
    {
73 3
        $items = Utilities\ensureIsArray($items, true);
74 3
        $item = array('CalendarItem' => $items);
75
        $defaultOptions = array(
76 3
            'SendMeetingInvitations' => Enumeration\CalendarItemCreateOrDeleteOperationType::SEND_TO_NONE,
77 3
            'SavedItemFolderId' => $this->getFolderId()->toArray(true)
78 3
        );
79
80 3
        $options = array_replace_recursive($defaultOptions, $options);
81
82 3
        $items = $this->createItems($item, $options);
83 3
        return Utilities\ensureIsArray($items);
84
    }
85
86
    /**
87
     * Get a list of calendar items between two dates/times
88
     *
89
     * @param string|DateTime $start
90
     * @param string|DateTime $end
91
     * @param array $options
92
     * @return CalendarItemType[]|Type\FindItemParentType
93
     */
94 6
    public function getCalendarItems($start = '12:00 AM', $end = '11:59 PM', $options = array())
95
    {
96 6
        $start = Utilities\ensureIsDateTime($start);
97 6
        $end = Utilities\ensureIsDateTime($end);
98
99
        $request = [
100 6
            'Traversal' => 'Shallow',
101
            'ItemShape' => [
102
                'BaseShape' => 'AllProperties'
103 6
            ],
104
            'CalendarView' => [
105 6
                'MaxEntriesReturned' => 100,
106 6
                'StartDate' => $start->format('c'),
107 6
                'EndDate' => $end->format('c')
108 6
            ],
109 6
            'ParentFolderIds' => $this->getFolderId()->toArray(true)
110 6
        ];
111
112 6
        $request = array_replace_recursive($request, $options);
113
114 6
        $request = Type::buildFromArray($request);
115 6
        $response = $this->getClient()->FindItem($request);
116 6
        $items = $response;
117
118 6
        return $items;
119
    }
120
121
    /**
122
     * @param $id
123
     * @param $changeKey
124
     * @return Type\CalendarItemType
125
     */
126 1
    public function getCalendarItem($id, $changeKey)
127
    {
128 1
        return $this->getItem(['Id' => $id, 'ChangeKey' => $changeKey]);
129
    }
130
131
    /**
132
     * Updates a calendar item with changes
133
     *
134
     * @param $itemId Type\ItemIdType
135
     * @param array $changes
136
     * @param array $options
137
     * @return Type\CalendarItemType[]
138
     */
139 1
    public function updateCalendarItem(Type\ItemIdType $itemId, $changes, $options = array())
140
    {
141
        //Create the request
142
        $request = [
143
            'ItemChange' => [
144 1
                'ItemId' => $itemId->toArray(),
145 1
                'Updates' => API\ItemUpdateBuilder::buildUpdateItemChanges('CalendarItem', 'calendar', $changes)
146 1
            ]
147 1
        ];
148
149
        $defaultOptions = [
150
            'SendMeetingInvitationsOrCancellations' => 'SendToNone'
151 1
        ];
152
153 1
        $options = array_replace_recursive($defaultOptions, $options);
154 1
        $items = $this->updateItems($request, $options)->getCalendarItem();
155 1
        return Utilities\ensureIsArray($items);
156
    }
157
158
    /**
159
     * @param Type\ItemIdType $itemId
160
     * @param array $options
161
     * @return bool
162
     */
163 3
    public function deleteCalendarItem(Type\ItemIdType $itemId, $options = array())
164
    {
165
        $defaultOptions = array(
166
            'SendMeetingCancellations' => 'SendToNone'
167 3
        );
168
169 3
        $options = array_replace_recursive($defaultOptions, $options);
170 3
        return $this->deleteItems($itemId, $options);
171
    }
172
173
    /**
174
     * @param string $start
175
     * @param string $end
176
     * @param array $options
177
     */
178 6
    public function deleteAllCalendarItems($start = '12:00 AM', $end = '11:59 PM', $options = array())
179
    {
180 6
        $items = $this->getCalendarItems($start, $end, $options);
181 6
        foreach ($items as $item) {
0 ignored issues
show
Bug introduced by
The expression $items of type object<garethp\ews\API\Type> is not traversable.
Loading history...
182 2
            $this->deleteCalendarItem($item->getItemId());
183 6
        }
184 6
    }
185
186
    /**
187
     * Get a list of changes on the calendar items
188
     *
189
     * @param null $syncState
190
     * @param array $options
191
     * @return API\Message\SyncFolderItemsResponseMessageType
192
     */
193 1
    public function listChanges($syncState = null, $options = array())
194
    {
195 1
        return parent::listItemChanges($this->getFolderId(), $syncState, $options);
196
    }
197
198
    /**
199
     * @param Type\ItemIdType $itemId
200
     * @param string $message
201
     * @param string $sensitivity
202
     * @param array $options
203
     *
204
     * @return Type\ItemIdType[]
205
     */
206 View Code Duplication
    public function acceptMeeting($itemId, $message, $sensitivity = 'Private', $options = array())
207
    {
208
        $request = [
209
            'AcceptItem' => [
210
                'Sensitivity' => $sensitivity,
211
                'Body' => ['BodyType' => 'HTML', '_value' => $message],
212
                'ReferenceItemId' => $itemId->toArray()
213
            ]
214
        ];
215
216
        $defaultOptions = ['MessageDisposition' => 'SendOnly'];
217
        $options = array_replace_recursive($defaultOptions, $options);
218
219
        $return = $this->createItems($request, $options)->getCalendarItem();
220
        return Utilities\ensureIsArray($return);
221
    }
222
223
    /**
224
     * @param $itemId
225
     * @param $message
226
     * @param string $sensitivity
227
     * @param array $options
228
     * @return Type\ItemIdType[]
229
     */
230 View Code Duplication
    public function declineMeeting($itemId, $message, $sensitivity = 'Private', $options = array())
231
    {
232
        $request = [
233
            'DeclineItem' => [
234
                'Sensitivity' => $sensitivity,
235
                'Body' => ['BodyType' => 'HTML', '_value' => $message],
236
                'ReferenceItemId' => $itemId->toArray()
237
            ]
238
        ];
239
240
        $defaultOptions = array('MessageDisposition' => 'SendOnly');
241
        $options = array_replace_recursive($defaultOptions, $options);
242
243
        $return = $this->createItems($request, $options)->getCalendarItem();
244
        return Utilities\ensureIsArray($return);
245
    }
246
247
    /**
248
     * @param $startTime
249
     * @param $endTime
250
     * @param array $users
251
     * @param array $options
252
     *
253
     * @return API\Message\GetUserAvailabilityResponseType
254
     */
255
    public function getAvailabilityFor($startTime, $endTime, array $users, array $options = array())
256
    {
257
        $startTime = Utilities\ensureIsDateTime($startTime);
258
        $endTime = Utilities\ensureIsDateTime($endTime);
259
260
        $request = [
261
            'MailboxDataArray' => ['MailboxData' => []],
262
            'FreeBusyViewOptions' => [
263
                'TimeWindow' => [
264
                    'StartTime' => $startTime->format('c'),
265
                    'EndTime' => $endTime->format('c'),
266
                ],
267
                'RequestedView' => 'FreeBusyMerged',
268
                'MergedFreeBusyIntervalInMinutes' => 30
269
            ],
270
        ];
271
272
        $users = array_map(function ($user) {
273
            return [
274
                'Email' => ['Address' => $user],
275
                'AttendeeType' => 'Required',
276
                'ExcludeConflicts' => false
277
            ];
278
        }, $users);
279
280
        $request['MailboxDataArray']['MailboxData'] = $users;
281
282
        $request = array_replace_recursive($request, $options);
283
        $response = $this->getClient()->GetUserAvailability($request);
284
        return $response;
285
    }
286
287
    /**
288
     * @param $startTime
289
     * @param $endTime
290
     * @param int $period The period of time to see if users of free for (in minutes)
291
     * @param array $users
292
     * @param array $options
293
     *
294
     * @return boolean
295
     */
296
    public function areAvailable($startTime, $endTime, $period, array $users, array $options = [])
297
    {
298
        $options = array_replace_recursive($options, [
299
            'FreeBusyViewOptions' => [
300
                'MergedFreeBusyIntervalInMinutes' => $period, 'RequestedView' => 'MergedOnly'
301
            ]]);
302
        $availability = $this->getAvailabilityFor($startTime, $endTime, $users, $options);
303
304
        $availabilities = array_map(function (FreeBusyResponseType $freeBusyResponseType) {
305
            return str_split($freeBusyResponseType->getFreeBusyView()->getMergedFreeBusy());
306
        }, $availability->getFreeBusyResponseArray()->FreeBusyResponse);
307
308
        foreach ($availabilities[0] as $periodIndex => $availability) {
309
            if ($availability != 0) {
310
                continue;
311
            }
312
313
            $free = true;
314
            foreach ($availabilities as $userAvailability) {
315
                if ($userAvailability[$periodIndex] != 0) {
316
                    $free = false;
317
                    break;
318
                }
319
            }
320
321
            if ($free === false) {
322
                continue;
323
            }
324
325
            return true;
326
        }
327
328
        return false;
329
    }
330
}
331