Completed
Push — master ( ea24b8...e11a9c )
by Gareth
04:07
created

CalendarAPI::declineMeeting()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 16
Code Lines 10

Duplication

Lines 16
Ratio 100 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 10
nc 1
nop 4
dl 16
loc 16
ccs 0
cts 10
cp 0
crap 2
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
        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
        if (!($start instanceof DateTime)) {
101 6
            $start = new DateTime($start);
102 6
        }
103
104 6
        if (!($end instanceof DateTime)) {
105 6
            $end = new DateTime($end);
106 6
        }
107
108
        $request = [
109 6
            'Traversal' => 'Shallow',
110
            'ItemShape' => [
111
                'BaseShape' => 'AllProperties'
112 6
            ],
113
            'CalendarView' => [
114 6
                'MaxEntriesReturned' => 100,
115 6
                'StartDate' => $start->format('c'),
116 6
                'EndDate' => $end->format('c')
117 6
            ],
118
            'ParentFolderIds' => [
119 6
                'FolderId' => $this->getFolderId()->toXmlObject()
120 6
            ]
121 6
        ];
122
123 6
        $request = array_replace_recursive($request, $options);
124
125 6
        $request = Type::buildFromArray($request);
126 6
        $response = $this->getClient()->FindItem($request);
127 6
        $items = $response;
128
129 6
        return $items;
130
    }
131
132
    /**
133
     * @param $id
134
     * @param $changeKey
135
     * @return Type\CalendarItemType
136
     */
137 1
    public function getCalendarItem($id, $changeKey)
138
    {
139 1
        return $this->getItem(['Id' => $id, 'ChangeKey' => $changeKey]);
140
    }
141
142
    /**
143
     * Updates a calendar item with changes
144
     *
145
     * @param $itemId Type\ItemIdType
146
     * @param array $changes
147
     * @return Type\CalendarItemType[]
148
     */
149 1
    public function updateCalendarItem(Type\ItemIdType $itemId, $changes)
150
    {
151
        //Create the request
152
        $request = [
153
            'ItemChange' => [
154 1
                'ItemId' => $itemId->toArray(),
155 1
                'Updates' => API\ItemUpdateBuilder::buildUpdateItemChanges('CalendarItem', 'calendar', $changes)
156 1
            ]
157 1
        ];
158
159
        $options = [
160
            'SendMeetingInvitationsOrCancellations' => 'SendToNone'
161 1
        ];
162
163 1
        $items = $this->updateItems($request, $options)->getCalendarItem();
164 1
        return Utilities\ensureIsArray($items);
165
    }
166
167
    /**
168
     * @param Type\ItemIdType $itemId
169
     * @param array $options
170
     * @return bool
171
     */
172 3
    public function deleteCalendarItem(Type\ItemIdType $itemId, $options = array())
173
    {
174
        $defaultOptions = array(
175
            'SendMeetingCancellations' => 'SendToNone'
176 3
        );
177
178 3
        $options = array_replace_recursive($defaultOptions, $options);
179 3
        return $this->deleteItems($itemId, $options);
180
    }
181
182
    /**
183
     * @param string $start
184
     * @param string $end
185
     * @param array $options
186
     */
187 6
    public function deleteAllCalendarItems($start = '12:00 AM', $end = '11:59 PM', $options = array())
188
    {
189 6
        $items = $this->getCalendarItems($start, $end, $options);
190 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...
191 2
            $this->deleteCalendarItem($item->getItemId());
192 6
        }
193 6
    }
194
195
    /**
196
     * Get a list of changes on the calendar items
197
     *
198
     * @param null $syncState
199
     * @param array $options
200
     * @return API\Message\SyncFolderItemsResponseMessageType
201
     */
202 1
    public function listChanges($syncState = null, $options = array())
203
    {
204 1
        return parent::listItemChanges($this->getFolderId(), $syncState, $options);
205
    }
206
207
    /**
208
     * @param Type\ItemIdType $itemId
209
     * @param string $message
210
     * @param string $sensitivity
211
     * @param array $options
212
     *
213
     * @return Type\ItemIdType[]
214
     */
215 View Code Duplication
    public function acceptMeeting($itemId, $message, $sensitivity = 'Private', $options = array())
216
    {
217
        $request = [
218
            'AcceptItem' => [
219
                'Sensitivity' => $sensitivity,
220
                'Body' => ['BodyType' => 'HTML', '_value' => $message],
221
                'ReferenceItemId' => $itemId->toArray()
222
            ]
223
        ];
224
225
        $defaultOptions = ['MessageDisposition' => 'SendOnly'];
226
        $options = array_replace_recursive($defaultOptions, $options);
227
228
        $return = $this->createItems($request, $options)->getCalendarItem();
229
        return Utilities\ensureIsArray($return);
230
    }
231
232
    /**
233
     * @param $itemId
234
     * @param $message
235
     * @param string $sensitivity
236
     * @param array $options
237
     * @return Type\ItemIdType[]
238
     */
239 View Code Duplication
    public function declineMeeting($itemId, $message, $sensitivity = 'Private', $options = array())
240
    {
241
        $request = [
242
            'DeclineItem' => [
243
                'Sensitivity' => $sensitivity,
244
                'Body' => ['BodyType' => 'HTML', '_value' => $message],
245
                'ReferenceItemId' => $itemId->toArray()
246
            ]
247
        ];
248
249
        $defaultOptions = array('MessageDisposition' => 'SendOnly');
250
        $options = array_replace_recursive($defaultOptions, $options);
251
252
        $return = $this->createItems($request, $options)->getCalendarItem();
253
        return Utilities\ensureIsArray($return);
254
    }
255
256
    /**
257
     * @param $startTime
258
     * @param $endTime
259
     * @param array $users
260
     * @param array $options
261
     *
262
     * @return API\Message\GetUserAvailabilityResponseType
263
     */
264
    public function getAvailabilityFor($startTime, $endTime, array $users, array $options = array())
265
    {
266
        if (!$startTime instanceof DateTime) {
267
            $startTime = new DateTime($startTime);
268
        }
269
270
        if (!$endTime instanceof DateTime) {
271
            $endTime = new DateTime($endTime);
272
        }
273
274
        $request = [
275
            'MailboxDataArray' => ['MailboxData' => []],
276
            'FreeBusyViewOptions' => [
277
                'TimeWindow' => [
278
                    'StartTime' => $startTime->format('c'),
279
                    'EndTime' => $endTime->format('c'),
280
                ],
281
                'RequestedView' => 'FreeBusyMerged',
282
                'MergedFreeBusyIntervalInMinutes' => 30
283
            ],
284
        ];
285
286
        $users = array_map(function ($user) {
287
            return [
288
                'Email' => ['Address' => $user],
289
                'AttendeeType' => 'Required',
290
                'ExcludeConflicts' => false
291
            ];
292
        }, $users);
293
294
        $request['MailboxDataArray']['MailboxData'] = $users;
295
296
        $request = array_replace_recursive($request, $options);
297
        $response = $this->getClient()->GetUserAvailability($request);
298
        return $response;
299
    }
300
301
    /**
302
     * @param $startTime
303
     * @param $endTime
304
     * @param int $period The period of time to see if users of free for (in minutes)
305
     * @param array $users
306
     * @param array $options
307
     *
308
     * @return boolean
309
     */
310
    public function areAvailable($startTime, $endTime, $period, array $users, array $options = [])
311
    {
312
        $options = array_replace_recursive($options, [
313
            'FreeBusyViewOptions' => [
314
                'MergedFreeBusyIntervalInMinutes' => $period, 'RequestedView' => 'MergedOnly'
315
            ]]);
316
        $availability = $this->getAvailabilityFor($startTime, $endTime, $users, $options);
317
318
        $availabilities = array_map(function (FreeBusyResponseType $freeBusyResponseType) {
319
            return str_split($freeBusyResponseType->getFreeBusyView()->getMergedFreeBusy());
320
        }, $availability->getFreeBusyResponseArray()->FreeBusyResponse);
321
322
        foreach ($availabilities[0] as $periodIndex => $availability) {
323
            if ($availability != 0) {
324
                continue;
325
            }
326
327
            $free = true;
328
            foreach ($availabilities as $userAvailability) {
329
                if ($userAvailability[$periodIndex] != 0) {
330
                    $free = false;
331
                    break;
332
                }
333
            }
334
335
            if ($free === false) {
336
                continue;
337
            }
338
339
            return true;
340
        }
341
342
        return false;
343
    }
344
}
345