Completed
Push — master ( c41b0b...defe05 )
by Gareth
03:56
created

CalendarAPI::updateCalendarItem()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 17
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 1

Importance

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