Completed
Push — master ( 66896f...2af8a7 )
by Gareth
04:56
created

CalendarAPI::getFolderId()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2.2559

Importance

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