├── .env.example
├── .github
└── workflows
│ └── ci.yml
├── .gitignore
├── .smoke-test-env.example
├── .tool-versions
├── CHANGELOG.md
├── LICENSE.txt
├── Makefile
├── README.md
├── composer.json
├── composer.lock
├── dev-smoke-test.php
├── init
├── phpunit.xml
├── ruleset.xml
├── src
├── Batch
│ ├── Batch.php
│ ├── BatchRequest.php
│ ├── BatchResponse.php
│ └── BatchResult.php
├── Cronofy.php
├── Exception
│ ├── CronofyException.php
│ └── PartialBatchFailureException.php
├── Http
│ ├── CurlRequest.php
│ └── HttpRequest.php
└── PagedResultIterator.php
└── tests
├── AccessibleCalendarsTest.php
├── ApplicationCalendarTest.php
├── BatchTest.php
├── CronofyTest.php
├── DelegatedAuthorizationsTest.php
├── ReadEventsTest.php
├── RulesTest.php
├── SchedulingTest.php
├── UpsertEventTest.php
└── bootstrap.php
/.env.example:
--------------------------------------------------------------------------------
1 | export CLIENT_ID=
2 | export CLIENT_SECRET=
3 | export REFRESH_TOKEN=
4 | export ACCESS_TOKEN=
5 | export DATACENTER=local
6 | export SUB=
7 | export CALENDAR_ID=
8 |
--------------------------------------------------------------------------------
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: php CI
2 |
3 | on: [push]
4 |
5 | jobs:
6 | build:
7 | runs-on: ubuntu-latest
8 | strategy:
9 | matrix:
10 | php_version: ['8.2', '8.1', '8.0','7.4','7.3']
11 |
12 | steps:
13 | - uses: actions/checkout@v2
14 |
15 | - name: Setup PHP Action
16 | uses: shivammathur/setup-php@2.11.0
17 | with:
18 | php-version: ${{ matrix.php_version }}
19 |
20 | - name: Install composer
21 | run: make install_composer
22 |
23 | - name: Run tests
24 | run: make ci
25 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /vendor
2 | composer.phar
3 | .idea
4 | .env
5 | .phpunit.result.cache
6 | .vscode
--------------------------------------------------------------------------------
/.smoke-test-env.example:
--------------------------------------------------------------------------------
1 | export CLIENT_ID=
2 | export CLIENT_SECRET=
3 | export CALENDAR_ID=
4 | export REFRESH_TOKEN=
5 | export ACCESS_TOKEN=
6 | export DATACENTER=
7 |
--------------------------------------------------------------------------------
/.tool-versions:
--------------------------------------------------------------------------------
1 | php 7.4.33
2 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## [1.7.3]
2 | * Improved PHPDoc code documentation
3 |
4 | ## [1.7.2]
5 | * Adds support for bulk event deletion with bulkDeleteEvents method
6 |
7 | ## [1.7.1]
8 | * Fixes hmacValid function not outputting raw binary data
9 |
10 | ## [1.7.0]
11 | * Adds support for event_classes on UpsertEvent
12 | * Updates PHP dev env to 8.1
13 |
14 | ## [1.6.0]
15 | * add support for disabling Real-Time Scheduling links
16 |
17 | ## [1.5.3]
18 | * accept locale on upsertEvent
19 |
20 | ## [1.5.2]
21 | * update package description
22 |
23 | ## [1.5.1]
24 | * add support for additional Real-Time Scheduling params
25 |
26 | ## [1.5.0]
27 | * add support for PHP 8
28 | * add `hmacValid` to verify a webhook call genuinely originated from Cronofy [#111]
29 |
30 | ## [1.4.0]
31 | * add support for `recurrence` key on upsertEvent (this is currently pre-release and not generally available yet)
32 |
33 | ## [1.3.0]
34 | * add AvailablePeriod create, read, delete and bulkDelete [#105] [#106]
35 | * add support for empty descriptions [#103]
36 | * add support for subscriptions on baseUpsertEvent [#104]
37 |
38 | ## [1.2.0]
39 |
40 | * add support for the Batch endpoint [#97]
41 | * add description for HTTP 429 (Too many requests) responses
42 | * add an SDK-dev script for manually testing the SDK against the API
43 |
44 | ## [1.1.10]
45 |
46 | * add missing exception `use` [#86]
47 |
48 | ## [1.1.9]
49 |
50 | * add support for `provider_name` to `conferencingServiceAuthorization()` [#94]
51 |
52 | ## [1.1.8]
53 |
54 | * add `conferencingServiceAuthorization()`
55 |
56 | ## [1.1.7]
57 |
58 | * support revoking subs
59 |
60 | ## [1.1.6]
61 |
62 | * less restrictive options for `conferencing`
63 |
64 | ## [1.1.5]
65 |
66 | * add `requestElementToken()`
67 |
68 | ## [1.1.4]
69 |
70 | * add `color` support to `upsertEvent`
71 |
72 | ## [1.1.3]
73 |
74 | * allow serialization of booleans in params
75 |
76 | ## [1.1.2]
77 |
78 | * disable libcurl verbose output
79 |
80 | ## [1.1.1]
81 |
82 | * add support for `provider_name` on `getAuthorizationURL()`
83 |
84 | ## [1.1.0]
85 |
86 | * add support for Conferencing Services
87 |
88 | ## [1.0.1]
89 |
90 | * documentation updates for v1 release
91 |
92 | ## [1.0.0]
93 |
94 | * namespacing and updated naming [#33]
95 |
96 | ## [0.29.0]
97 |
98 | * cancel_smart_invite recipients [#32]
99 |
100 | [0.29.0]: https://github.com/cronofy/cronofy-php/releases/tag/v0.29.0
101 | [1.0.0]: https://github.com/cronofy/cronofy-php/releases/tag/v1.0.0
102 | [1.0.1]: https://github.com/cronofy/cronofy-php/releases/tag/v1.0.1
103 | [1.1.0]: https://github.com/cronofy/cronofy-php/releases/tag/v1.1.0
104 | [1.1.1]: https://github.com/cronofy/cronofy-php/releases/tag/v1.1.1
105 | [1.1.2]: https://github.com/cronofy/cronofy-php/releases/tag/v1.1.2
106 | [1.1.3]: https://github.com/cronofy/cronofy-php/releases/tag/v1.1.3
107 | [1.1.4]: https://github.com/cronofy/cronofy-php/releases/tag/v1.1.4
108 | [1.1.5]: https://github.com/cronofy/cronofy-php/releases/tag/v1.1.5
109 | [1.1.6]: https://github.com/cronofy/cronofy-php/releases/tag/v1.1.6
110 | [1.1.7]: https://github.com/cronofy/cronofy-php/releases/tag/v1.1.7
111 | [1.1.8]: https://github.com/cronofy/cronofy-php/releases/tag/v1.1.8
112 | [1.1.9]: https://github.com/cronofy/cronofy-php/releases/tag/v1.1.9
113 | [1.1.10]: https://github.com/cronofy/cronofy-php/releases/tag/v1.1.10
114 | [1.2.0]: https://github.com/cronofy/cronofy-php/releases/tag/v1.2.0
115 | [1.3.0]: https://github.com/cronofy/cronofy-php/releases/tag/v1.3.0
116 | [1.4.0]: https://github.com/cronofy/cronofy-php/releases/tag/v1.4.0
117 | [1.5.0]: https://github.com/cronofy/cronofy-php/releases/tag/v1.5.0
118 | [1.5.1]: https://github.com/cronofy/cronofy-php/releases/tag/v1.5.1
119 | [1.5.2]: https://github.com/cronofy/cronofy-php/releases/tag/v1.5.2
120 | [1.5.3]: https://github.com/cronofy/cronofy-php/releases/tag/v1.5.3
121 | [1.6.0]: https://github.com/cronofy/cronofy-php/releases/tag/v1.6.0
122 | [1.7.0]: https://github.com/cronofy/cronofy-php/releases/tag/v1.7.0
123 | [1.7.1]: https://github.com/cronofy/cronofy-php/releases/tag/v1.7.1
124 | [1.7.2]: https://github.com/cronofy/cronofy-php/releases/tag/v1.7.2
125 | [1.7.3]: https://github.com/cronofy/cronofy-php/releases/tag/v1.7.3
126 |
127 | [#32]: https://github.com/cronofy/cronofy-php/pull/76
128 | [#33]: https://github.com/cronofy/cronofy-php/pull/74
129 | [#34]: https://github.com/cronofy/cronofy-php/pull/77
130 | [#94]: https://github.com/cronofy/cronofy-php/pull/94
131 | [#86]: https://github.com/cronofy/cronofy-php/pull/86
132 | [#97]: https://github.com/cronofy/cronofy-php/pull/97
133 | [#103]: https://github.com/cronofy/cronofy-php/pull/103
134 | [#104]: https://github.com/cronofy/cronofy-php/pull/104
135 | [#105]: https://github.com/cronofy/cronofy-php/pull/105
136 | [#106]: https://github.com/cronofy/cronofy-php/pull/106
137 | [#111]: https://github.com/cronofy/cronofy-php/pull/111
138 | [#116]: https://github.com/cronofy/cronofy-php/pull/116
139 | [#126]: https://github.com/cronofy/cronofy-php/pull/126
140 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Copyright (c) 2017 Cronofy
2 |
3 | MIT License
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining
6 | a copy of this software and associated documentation files (the
7 | "Software"), to deal in the Software without restriction, including
8 | without limitation the rights to use, copy, modify, merge, publish,
9 | distribute, sublicense, and/or sell copies of the Software, and to
10 | permit persons to whom the Software is furnished to do so, subject to
11 | the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be
14 | included in all copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | CURRENT_VERSION:=$(shell jq ".version" -r composer.json)
2 |
3 | .PHONY: all
4 | all: test
5 |
6 | .PHONY: install_composer
7 | install_composer:
8 | curl -sS https://getcomposer.org/installer | php
9 |
10 | .PHONY: install_dependencies
11 | install_dependencies: install_composer
12 | php composer.phar install
13 |
14 | .PHONY: update
15 | update:
16 | php composer.phar update
17 |
18 | .PHONY: test
19 | test: install_dependencies
20 | vendor/bin/phpunit tests/
21 | vendor/bin/phpcs tests/ src/Cronofy.php --standard=ruleset.xml
22 |
23 | .PHONY: smoke-test
24 | smoke-test:
25 | source .env && php ./dev-smoke-test.php
26 |
27 | .PHONY: ci
28 | ci: test
29 |
30 | .PHONY: check_dependencies
31 | check_dependencies:
32 | @command -v jq >/dev/null || (echo "jq not installed please install via homebrew - 'brew install jq'"; exit 1)
33 |
34 | .PHONY: release
35 | release: check_dependencies test
36 | git push
37 | git tag $(CURRENT_VERSION)
38 | git push --tags
39 |
40 | .PHONY: init
41 | init:
42 | ./init
43 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Cronofy
2 |
3 | [Cronofy](https://www.cronofy.com) - one API for all the calendars (Google, iCloud, Exchange, Office 365, Outlook.com)
4 | [](https://github.com/cronofy/cronofy-php/actions/workflows/ci.yml)
5 |
6 |
7 | ## Sample Application
8 |
9 | To see this API wrapper in action see our sample app [here](https://github.com/cronofy/cronofy-php-sample-app)
10 |
11 | ## Usage
12 |
13 | > Note: if upgrading from a v0.x.x version to v1.0.0, please read the [migration guide](#migration-guides)
14 |
15 | In order to use the Cronofy API you will need to [create a developer account](https://app.cronofy.com/sign_up/new).
16 |
17 | From there you can [use your Calendar Sandbox](https://app.cronofy.com/oauth/sandbox)
18 | to access your own calendars, or you can [create an OAuth application](https://app.cronofy.com/oauth/applications/new)
19 | to obtain an OAuth `client_id` and `client_secret` to be able to use the full
20 | API.
21 |
22 | ## Authorization
23 |
24 | [API documentation](https://www.cronofy.com/developers/api/#authorization)
25 |
26 | Generate a link for a user to grant access to their calendars:
27 |
28 | ```php
29 | $redirect_uri = "http://yoursite.dev/oauth2/callback";
30 |
31 | $cronofy = new Cronofy\Cronofy(["client_id" => "CRONOFY_CLIENT_ID"]);
32 | $params = [
33 | 'redirect_uri' => $redirect_uri,
34 | 'scope' => ['read_account','list_calendars','read_events','create_event','delete_event']
35 | ];
36 | $auth = $cronofy->getAuthorizationURL($params);
37 | ```
38 |
39 | The redirect URI is a page on your website that will handle the OAuth 2.0
40 | callback and receive a `code` parameter. You can then use that code to retrieve
41 | an OAuth token granting access to the user's Cronofy account:
42 |
43 | ```php
44 | $cronofy = new Cronofy\Cronofy([
45 | "client_id" => "CRONOFY_CLIENT_ID",
46 | "client_secret" => "CRONOFY_CLIENT_SECRET"
47 | ]);
48 |
49 | $params = [
50 | 'redirect_uri' => $redirect_uri,
51 | 'code' => $code
52 | ];
53 |
54 | $result = $cronofy->requestToken($params);
55 |
56 | // Retrieve credentials value
57 | $accessToken = $cronofy->accessToken;
58 | $refreshToken = $cronofy->refreshToken;
59 | $expiresIn = $cronofy->expiresIn;
60 | ```
61 |
62 | You should save the response's `AccessToken` and `RefreshToken` for later use.
63 |
64 | Note that the **exact same** redirect URI must be passed to both methods for
65 | access to be granted.
66 |
67 | `$result` will be `true` for a successful request; otherwise, it will be an error code.
68 | Please reference [our documentation](https://docs.cronofy.com/developers/api/authorization/request-authorization/#param-error) for possible error code.
69 |
70 | ## Refresh Access Token
71 |
72 | Refresh an access token for an account:
73 |
74 | ```php
75 | $cronofy = new Cronofy\Cronofy([
76 | "client_id" => "CRONOFY_CLIENT_ID",
77 | "client_secret" => "CRONOFY_CLIENT_SECRET",
78 | "grant_type" => "refresh_token",
79 | "refresh_token" => "YOUR_REFRESH_TOKEN"
80 | ]);
81 |
82 | $new_access_token = $cronofy->refreshToken();
83 | ```
84 |
85 | ## List calendars
86 |
87 | [API documentation](https://www.cronofy.com/developers/api/#calendars)
88 |
89 | Get a list of all the user's calendars:
90 |
91 | ```php
92 | $cronofy = new Cronofy\Cronofy([
93 | "client_id" => "CRONOFY_CLIENT_ID",
94 | "client_secret" => "CRONOFY_CLIENT_SECRET",
95 | "access_token" => "AccessToken",
96 | "refresh_token" => "RefreshToken"
97 | ]);
98 |
99 | $calendar = $cronofy->listCalendars();
100 | ```
101 |
102 | ## Read events
103 |
104 | [API documentation](https://www.cronofy.com/developers/api/#read-events)
105 |
106 | Get a list of all the user's events:
107 |
108 | ```php
109 | $cronofy = new Cronofy\Cronofy([
110 | "client_id" => "CRONOFY_CLIENT_ID",
111 | "client_secret" => "CRONOFY_CLIENT_SECRET",
112 | "access_token" => "AccessToken",
113 | "refresh_token" => "RefreshToken"
114 | ]);
115 |
116 | $params = [
117 | 'tzid' => 'Etc/UTC'
118 | ];
119 |
120 | $events = $cronofy->readEvents($params);
121 |
122 | foreach($events->each() as $event){
123 | // process event
124 | }
125 | ```
126 |
127 | ## Create or update events
128 |
129 | [API documentation](https://www.cronofy.com/developers/api/#upsert-event)
130 |
131 | To create or update an event in the user's calendar:
132 |
133 | ```php
134 | $cronofy = new Cronofy\Cronofy([
135 | "client_id" => "CRONOFY_CLIENT_ID",
136 | "client_secret" => "CRONOFY_CLIENT_SECRET",
137 | "access_token" => "AccessToken",
138 | "refresh_token" => "RefreshToken"
139 | ]);
140 |
141 | $params = [
142 | 'calendar_id' => 'CalendarID',
143 | 'event_id' => 'event_test_12345679',
144 | 'summary' => 'test event 2',
145 | 'description' => 'some event data here',
146 | 'start' => '2015-12-07T09:00:00Z',
147 | 'end' => '2015-12-08T10:00:00Z'
148 | ];
149 | $new_event = $cronofy->upsertEvent($params);
150 |
151 | ```
152 |
153 | ## Delete events
154 |
155 | [API documentation](https://www.cronofy.com/developers/api/#delete-event)
156 |
157 | To delete an event from user's calendar:
158 |
159 | ```php
160 | $cronofy = new Cronofy\Cronofy([
161 | "client_id" => "CRONOFY_CLIENT_ID",
162 | "client_secret" => "CRONOFY_CLIENT_SECRET",
163 | "access_token" => "AccessToken",
164 | "refresh_token" => "RefreshToken"
165 | ]);
166 |
167 | $params = [
168 | 'calendar_id' => 'CalendarID',
169 | 'event_id' => 'EventID'
170 | ];
171 |
172 | $delete = $cronofy->deleteEvent($params);
173 |
174 | ```
175 |
176 | ## Delete external events
177 |
178 | To delete an external event from a user's calendar:
179 |
180 | ```php
181 | $cronofy = new Cronofy\Cronofy([
182 | "client_id" => "CRONOFY_CLIENT_ID",
183 | "client_secret" => "CRONOFY_CLIENT_SECRET",
184 | "access_token" => "AccessToken",
185 | "refresh_token" => "RefreshToken"
186 | ]);
187 |
188 | $params = [
189 | 'calendar_id' => 'CalendarID',
190 | 'event_uid' => 'EventUID'
191 | ];
192 |
193 | $delete = $cronofy->deleteExternalEvent($params);
194 |
195 | ```
196 |
197 | ## Elevated permissions
198 |
199 | To elevate a client's permissions for a user's calendar(s):
200 |
201 | ```php
202 | $cronofy = new Cronofy\Cronofy([
203 | "client_id" => "CRONOFY_CLIENT_ID",
204 | "client_secret" => "CRONOFY_CLIENT_SECRET",
205 | "access_token" => "AccessToken",
206 | "refresh_token" => "RefreshToken"
207 | ]);
208 |
209 | $params = [
210 | 'permissions' => [
211 | [
212 | 'calendar_id' => 'CalendarID_1',
213 | 'permission_level' => 'unrestricted'
214 | ],
215 | [
216 | 'calendar_id' => 'CalendarID_2',
217 | 'permission_level' => 'unrestricted'
218 | ]
219 | ],
220 | 'redirect_uri' => 'http://yoursite.dev/elevate/callback'
221 | ];
222 |
223 | $response = $cronofy->elevatedPermissions($params);
224 |
225 | ```
226 |
227 | ## Authorize with a Service Account
228 |
229 | To authorize a user's account using a service account:
230 |
231 | ```php
232 | $cronofy = new Cronofy\Cronofy([
233 | "client_id" => "CRONOFY_CLIENT_ID",
234 | "client_secret" => "CRONOFY_CLIENT_SECRET",
235 | "access_token" => "AccessToken",
236 | "refresh_token" => "RefreshToken"
237 | ]);
238 |
239 | $params = [
240 | 'email' => $email,
241 | 'callback_url' => $callback_url,
242 | 'scope' => ['read_account','list_calendars','read_events','create_event','delete_event']
243 | ];
244 |
245 | $response = $cronofy->authorizeWithServiceAccount($params);
246 |
247 | ```
248 |
249 | Note: You will need to use a Service Account access token to perform this action.
250 |
251 | ## Create a Calendar
252 |
253 | To create a calendar for a user's account profile:
254 |
255 | ```php
256 | $cronofy = new Cronofy\Cronofy([
257 | "client_id" => "CRONOFY_CLIENT_ID",
258 | "client_secret" => "CRONOFY_CLIENT_SECRET",
259 | "access_token" => "AccessToken",
260 | "refresh_token" => "RefreshToken"
261 | ]);
262 |
263 | $params = [
264 | 'profile_id' => $account_profile_id,
265 | 'name' => $new_calendar_name
266 | ];
267 |
268 | $response = $cronofy->createCalendar($params);
269 |
270 | ```
271 |
272 | ## Using an Alternative Data Center
273 |
274 | To use an alternative data center:
275 |
276 | ```php
277 | $cronofy = new Cronofy\Cronofy([
278 | "client_id" => "CRONOFY_CLIENT_ID",
279 | "client_secret" => "CRONOFY_CLIENT_SECRET",
280 | "access_token" => "AccessToken",
281 | "refresh_token" => "RefreshToken",
282 | "data_center" => "DataCenter"
283 | ]);
284 |
285 | ```
286 |
287 | ## List Availability Rules
288 |
289 | To retrieve all availability rules saved against an account:
290 |
291 | ```php
292 | $cronofy = new Cronofy\Cronofy([
293 | "client_id" => "CRONOFY_CLIENT_ID",
294 | "client_secret" => "CRONOFY_CLIENT_SECRET",
295 | "access_token" => "AccessToken",
296 | "refresh_token" => "RefreshToken"
297 | ]);
298 |
299 | $response = $cronofy->listAvailabilityRules();
300 |
301 | ```
302 |
303 | ## Read Availability Rule
304 |
305 | To retrieve an availability rule:
306 |
307 | ```php
308 | $cronofy = new Cronofy\Cronofy([
309 | "client_id" => "CRONOFY_CLIENT_ID",
310 | "client_secret" => "CRONOFY_CLIENT_SECRET",
311 | "access_token" => "AccessToken",
312 | "refresh_token" => "RefreshToken"
313 | ]);
314 |
315 | // The String that uniquely identifies the availability rule.
316 | $rule_id = "default";
317 |
318 | $response = $cronofy->getAvailabilityRule($rule_id);
319 |
320 | ```
321 |
322 | ## Delete Availability Rule
323 |
324 | To delete an availability rule for the authenticated account:
325 |
326 | ```php
327 | $cronofy = new Cronofy\Cronofy([
328 | "client_id" => "CRONOFY_CLIENT_ID",
329 | "client_secret" => "CRONOFY_CLIENT_SECRET",
330 | "access_token" => "AccessToken",
331 | "refresh_token" => "RefreshToken"
332 | ]);
333 |
334 | // The String that uniquely identifies the availability rule.
335 | $rule_id = "default";
336 |
337 | $response = $cronofy->deleteAvailabilityRule($rule_id);
338 |
339 | ```
340 |
341 | ## Create or Update Availability Rule
342 |
343 | To create or update an availability rule for the authenticated account:
344 |
345 | ```php
346 | $cronofy = new Cronofy\Cronofy([
347 | "client_id" => "CRONOFY_CLIENT_ID",
348 | "client_secret" => "CRONOFY_CLIENT_SECRET",
349 | "access_token" => "AccessToken",
350 | "refresh_token" => "RefreshToken"
351 | ]);
352 |
353 | // The details of the event to create or update:
354 | $params = [
355 | "availability_rule_id" => "default",
356 | "calendar_ids" => ["cal_123"],
357 | "tzid" => "America/Chicago",
358 | "weekly_periods" => [
359 | [
360 | "day" => "monday",
361 | "start_time" => "09:30",
362 | "end_time" => "12:30"
363 | ],
364 | [
365 | "day" => "wednesday",
366 | "start_time" => "09:30",
367 | "end_time" => "12:30"
368 | ]
369 | ]
370 | ];
371 |
372 | $response = $cronofy->createAvailabilityRule($params);
373 |
374 | ```
375 |
376 | ## Make a Batch request
377 |
378 | Send multiple requests as a batch of operations via the [Batch][(https://docs.cronofy.com/developers/api/batch/) endpoint.
379 |
380 | ```php
381 | $cronofy = new Cronofy\Cronofy([
382 | "client_id" => "CRONOFY_CLIENT_ID",
383 | "client_secret" => "CRONOFY_CLIENT_SECRET",
384 | "access_token" => "AccessToken",
385 | "refresh_token" => "RefreshToken"
386 | ]);
387 |
388 | $eventData = [
389 | 'calendar_id' => 'CalendarID',
390 | 'event_id' => 'myapp-event-001',
391 | 'summary' => 'Wyld Stallyns band practice',
392 | 'start' => date("Y-m-d", strtotime('tomorrow')) . "T15:30:00Z",
393 | 'end' => date("Y-m-d", strtotime('tomorrow')) . "T17:00:00Z",
394 | ];
395 |
396 | $batch = Batch::create()
397 | ->upsertEvent($calendarId, $testEventData)
398 | ->deleteEvent($calendarId, $testEventId)
399 |
400 | try {
401 | $result = $cronofy->executeBatch($batch);
402 |
403 | foreach ($result->responses() as $response) {
404 | // $response->status();
405 | // $response->headers();
406 | // $response->data();
407 | // $response->request();
408 | }
409 | } catch (PartialBatchFailureException $exception) {
410 | $result = $exception->result();
411 |
412 | foreach ($result->errors() as $response) {
413 | // $response->status();
414 | // $response->headers();
415 | // $response->data();
416 | // $response->request();
417 | }
418 | }
419 | ```
420 |
421 | ## Running unit tests
422 |
423 | ```shell
424 | make test
425 | ```
426 |
427 | ## Links
428 |
429 | * [API documentation](https://www.cronofy.com/developers/api)
430 | * [API mailing list](https://groups.google.com/d/forum/cronofy-api)
431 |
432 | ## Migration guides
433 |
434 | * `v0.X.X` -> `v1.0.0`: [version `1.0.0`](https://github.com/cronofy/cronofy-php/releases/tag/v1.0.0) adds namespacing and standardizes the names of public methods to camelCase (whereas previously some methods were named with camel_case). Where in v0.29.0 you would have written `$cronofy = new Cronofy();` and `$calendar = $cronofy->list_calendars();`, for v1.0.0 you should write `$cronofy = new Cronofy\Cronofy();` and `$calendar = $cronofy->listCalendars();`.
435 |
436 | ## A feature I want is not in the SDK, how do I get it?
437 |
438 | We add features to this SDK as they are requested, to focus on developing the Cronofy API.
439 |
440 | If you're comfortable contributing support for an endpoint or attribute, then we love to receive pull requests!
441 | Please create a PR mentioning the feature/API endpoint you’ve added and we’ll review it as soon as we can.
442 |
443 | If you would like to request a feature is added by our team then please let us know by getting in touch via [support@cronofy.com](mailto:support@cronofy.com).
444 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cronofy/cronofy",
3 | "description": "SDK for Cronofy - the Scheduling Platform for Business",
4 | "version": "v1.7.3",
5 | "require": {
6 | "php": ">=7.1"
7 | },
8 | "autoload": {
9 | "files": [
10 | "src/Cronofy.php"
11 | ],
12 | "psr-4": {
13 | "Cronofy\\": "src/"
14 | }
15 | },
16 | "keywords": [
17 | "cronofy",
18 | "calendar",
19 | "oauth",
20 | "oauth2",
21 | "client",
22 | "authorization",
23 | "authentication"
24 | ],
25 | "minimum-stability": "beta",
26 | "license": "MIT",
27 | "require-dev": {
28 | "phpunit/phpunit": "^8",
29 | "squizlabs/php_codesniffer": "3.*"
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/composer.lock:
--------------------------------------------------------------------------------
1 | {
2 | "_readme": [
3 | "This file locks the dependencies of your project to a known state",
4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
5 | "This file is @generated automatically"
6 | ],
7 | "content-hash": "31781d4e30860fdd7d03648b6db71552",
8 | "packages": [],
9 | "packages-dev": [
10 | {
11 | "name": "doctrine/instantiator",
12 | "version": "1.5.0",
13 | "source": {
14 | "type": "git",
15 | "url": "https://github.com/doctrine/instantiator.git",
16 | "reference": "0a0fa9780f5d4e507415a065172d26a98d02047b"
17 | },
18 | "dist": {
19 | "type": "zip",
20 | "url": "https://api.github.com/repos/doctrine/instantiator/zipball/0a0fa9780f5d4e507415a065172d26a98d02047b",
21 | "reference": "0a0fa9780f5d4e507415a065172d26a98d02047b",
22 | "shasum": ""
23 | },
24 | "require": {
25 | "php": "^7.1 || ^8.0"
26 | },
27 | "require-dev": {
28 | "doctrine/coding-standard": "^9 || ^11",
29 | "ext-pdo": "*",
30 | "ext-phar": "*",
31 | "phpbench/phpbench": "^0.16 || ^1",
32 | "phpstan/phpstan": "^1.4",
33 | "phpstan/phpstan-phpunit": "^1",
34 | "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
35 | "vimeo/psalm": "^4.30 || ^5.4"
36 | },
37 | "type": "library",
38 | "autoload": {
39 | "psr-4": {
40 | "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
41 | }
42 | },
43 | "notification-url": "https://packagist.org/downloads/",
44 | "license": [
45 | "MIT"
46 | ],
47 | "authors": [
48 | {
49 | "name": "Marco Pivetta",
50 | "email": "ocramius@gmail.com",
51 | "homepage": "https://ocramius.github.io/"
52 | }
53 | ],
54 | "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
55 | "homepage": "https://www.doctrine-project.org/projects/instantiator.html",
56 | "keywords": [
57 | "constructor",
58 | "instantiate"
59 | ],
60 | "support": {
61 | "issues": "https://github.com/doctrine/instantiator/issues",
62 | "source": "https://github.com/doctrine/instantiator/tree/1.5.0"
63 | },
64 | "funding": [
65 | {
66 | "url": "https://www.doctrine-project.org/sponsorship.html",
67 | "type": "custom"
68 | },
69 | {
70 | "url": "https://www.patreon.com/phpdoctrine",
71 | "type": "patreon"
72 | },
73 | {
74 | "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator",
75 | "type": "tidelift"
76 | }
77 | ],
78 | "time": "2022-12-30T00:15:36+00:00"
79 | },
80 | {
81 | "name": "myclabs/deep-copy",
82 | "version": "1.11.0",
83 | "source": {
84 | "type": "git",
85 | "url": "https://github.com/myclabs/DeepCopy.git",
86 | "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614"
87 | },
88 | "dist": {
89 | "type": "zip",
90 | "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/14daed4296fae74d9e3201d2c4925d1acb7aa614",
91 | "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614",
92 | "shasum": ""
93 | },
94 | "require": {
95 | "php": "^7.1 || ^8.0"
96 | },
97 | "conflict": {
98 | "doctrine/collections": "<1.6.8",
99 | "doctrine/common": "<2.13.3 || >=3,<3.2.2"
100 | },
101 | "require-dev": {
102 | "doctrine/collections": "^1.6.8",
103 | "doctrine/common": "^2.13.3 || ^3.2.2",
104 | "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13"
105 | },
106 | "type": "library",
107 | "autoload": {
108 | "files": [
109 | "src/DeepCopy/deep_copy.php"
110 | ],
111 | "psr-4": {
112 | "DeepCopy\\": "src/DeepCopy/"
113 | }
114 | },
115 | "notification-url": "https://packagist.org/downloads/",
116 | "license": [
117 | "MIT"
118 | ],
119 | "description": "Create deep copies (clones) of your objects",
120 | "keywords": [
121 | "clone",
122 | "copy",
123 | "duplicate",
124 | "object",
125 | "object graph"
126 | ],
127 | "support": {
128 | "issues": "https://github.com/myclabs/DeepCopy/issues",
129 | "source": "https://github.com/myclabs/DeepCopy/tree/1.11.0"
130 | },
131 | "funding": [
132 | {
133 | "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy",
134 | "type": "tidelift"
135 | }
136 | ],
137 | "time": "2022-03-03T13:19:32+00:00"
138 | },
139 | {
140 | "name": "phar-io/manifest",
141 | "version": "2.0.3",
142 | "source": {
143 | "type": "git",
144 | "url": "https://github.com/phar-io/manifest.git",
145 | "reference": "97803eca37d319dfa7826cc2437fc020857acb53"
146 | },
147 | "dist": {
148 | "type": "zip",
149 | "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53",
150 | "reference": "97803eca37d319dfa7826cc2437fc020857acb53",
151 | "shasum": ""
152 | },
153 | "require": {
154 | "ext-dom": "*",
155 | "ext-phar": "*",
156 | "ext-xmlwriter": "*",
157 | "phar-io/version": "^3.0.1",
158 | "php": "^7.2 || ^8.0"
159 | },
160 | "type": "library",
161 | "extra": {
162 | "branch-alias": {
163 | "dev-master": "2.0.x-dev"
164 | }
165 | },
166 | "autoload": {
167 | "classmap": [
168 | "src/"
169 | ]
170 | },
171 | "notification-url": "https://packagist.org/downloads/",
172 | "license": [
173 | "BSD-3-Clause"
174 | ],
175 | "authors": [
176 | {
177 | "name": "Arne Blankerts",
178 | "email": "arne@blankerts.de",
179 | "role": "Developer"
180 | },
181 | {
182 | "name": "Sebastian Heuer",
183 | "email": "sebastian@phpeople.de",
184 | "role": "Developer"
185 | },
186 | {
187 | "name": "Sebastian Bergmann",
188 | "email": "sebastian@phpunit.de",
189 | "role": "Developer"
190 | }
191 | ],
192 | "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)",
193 | "support": {
194 | "issues": "https://github.com/phar-io/manifest/issues",
195 | "source": "https://github.com/phar-io/manifest/tree/2.0.3"
196 | },
197 | "time": "2021-07-20T11:28:43+00:00"
198 | },
199 | {
200 | "name": "phar-io/version",
201 | "version": "3.2.1",
202 | "source": {
203 | "type": "git",
204 | "url": "https://github.com/phar-io/version.git",
205 | "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74"
206 | },
207 | "dist": {
208 | "type": "zip",
209 | "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74",
210 | "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74",
211 | "shasum": ""
212 | },
213 | "require": {
214 | "php": "^7.2 || ^8.0"
215 | },
216 | "type": "library",
217 | "autoload": {
218 | "classmap": [
219 | "src/"
220 | ]
221 | },
222 | "notification-url": "https://packagist.org/downloads/",
223 | "license": [
224 | "BSD-3-Clause"
225 | ],
226 | "authors": [
227 | {
228 | "name": "Arne Blankerts",
229 | "email": "arne@blankerts.de",
230 | "role": "Developer"
231 | },
232 | {
233 | "name": "Sebastian Heuer",
234 | "email": "sebastian@phpeople.de",
235 | "role": "Developer"
236 | },
237 | {
238 | "name": "Sebastian Bergmann",
239 | "email": "sebastian@phpunit.de",
240 | "role": "Developer"
241 | }
242 | ],
243 | "description": "Library for handling version information and constraints",
244 | "support": {
245 | "issues": "https://github.com/phar-io/version/issues",
246 | "source": "https://github.com/phar-io/version/tree/3.2.1"
247 | },
248 | "time": "2022-02-21T01:04:05+00:00"
249 | },
250 | {
251 | "name": "phpunit/php-code-coverage",
252 | "version": "7.0.15",
253 | "source": {
254 | "type": "git",
255 | "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
256 | "reference": "819f92bba8b001d4363065928088de22f25a3a48"
257 | },
258 | "dist": {
259 | "type": "zip",
260 | "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/819f92bba8b001d4363065928088de22f25a3a48",
261 | "reference": "819f92bba8b001d4363065928088de22f25a3a48",
262 | "shasum": ""
263 | },
264 | "require": {
265 | "ext-dom": "*",
266 | "ext-xmlwriter": "*",
267 | "php": ">=7.2",
268 | "phpunit/php-file-iterator": "^2.0.2",
269 | "phpunit/php-text-template": "^1.2.1",
270 | "phpunit/php-token-stream": "^3.1.3 || ^4.0",
271 | "sebastian/code-unit-reverse-lookup": "^1.0.1",
272 | "sebastian/environment": "^4.2.2",
273 | "sebastian/version": "^2.0.1",
274 | "theseer/tokenizer": "^1.1.3"
275 | },
276 | "require-dev": {
277 | "phpunit/phpunit": "^8.2.2"
278 | },
279 | "suggest": {
280 | "ext-xdebug": "^2.7.2"
281 | },
282 | "type": "library",
283 | "extra": {
284 | "branch-alias": {
285 | "dev-master": "7.0-dev"
286 | }
287 | },
288 | "autoload": {
289 | "classmap": [
290 | "src/"
291 | ]
292 | },
293 | "notification-url": "https://packagist.org/downloads/",
294 | "license": [
295 | "BSD-3-Clause"
296 | ],
297 | "authors": [
298 | {
299 | "name": "Sebastian Bergmann",
300 | "email": "sebastian@phpunit.de",
301 | "role": "lead"
302 | }
303 | ],
304 | "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
305 | "homepage": "https://github.com/sebastianbergmann/php-code-coverage",
306 | "keywords": [
307 | "coverage",
308 | "testing",
309 | "xunit"
310 | ],
311 | "support": {
312 | "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
313 | "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/7.0.15"
314 | },
315 | "funding": [
316 | {
317 | "url": "https://github.com/sebastianbergmann",
318 | "type": "github"
319 | }
320 | ],
321 | "time": "2021-07-26T12:20:09+00:00"
322 | },
323 | {
324 | "name": "phpunit/php-file-iterator",
325 | "version": "2.0.5",
326 | "source": {
327 | "type": "git",
328 | "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
329 | "reference": "42c5ba5220e6904cbfe8b1a1bda7c0cfdc8c12f5"
330 | },
331 | "dist": {
332 | "type": "zip",
333 | "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/42c5ba5220e6904cbfe8b1a1bda7c0cfdc8c12f5",
334 | "reference": "42c5ba5220e6904cbfe8b1a1bda7c0cfdc8c12f5",
335 | "shasum": ""
336 | },
337 | "require": {
338 | "php": ">=7.1"
339 | },
340 | "require-dev": {
341 | "phpunit/phpunit": "^8.5"
342 | },
343 | "type": "library",
344 | "extra": {
345 | "branch-alias": {
346 | "dev-master": "2.0.x-dev"
347 | }
348 | },
349 | "autoload": {
350 | "classmap": [
351 | "src/"
352 | ]
353 | },
354 | "notification-url": "https://packagist.org/downloads/",
355 | "license": [
356 | "BSD-3-Clause"
357 | ],
358 | "authors": [
359 | {
360 | "name": "Sebastian Bergmann",
361 | "email": "sebastian@phpunit.de",
362 | "role": "lead"
363 | }
364 | ],
365 | "description": "FilterIterator implementation that filters files based on a list of suffixes.",
366 | "homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
367 | "keywords": [
368 | "filesystem",
369 | "iterator"
370 | ],
371 | "support": {
372 | "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues",
373 | "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/2.0.5"
374 | },
375 | "funding": [
376 | {
377 | "url": "https://github.com/sebastianbergmann",
378 | "type": "github"
379 | }
380 | ],
381 | "time": "2021-12-02T12:42:26+00:00"
382 | },
383 | {
384 | "name": "phpunit/php-text-template",
385 | "version": "1.2.1",
386 | "source": {
387 | "type": "git",
388 | "url": "https://github.com/sebastianbergmann/php-text-template.git",
389 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686"
390 | },
391 | "dist": {
392 | "type": "zip",
393 | "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
394 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
395 | "shasum": ""
396 | },
397 | "require": {
398 | "php": ">=5.3.3"
399 | },
400 | "type": "library",
401 | "autoload": {
402 | "classmap": [
403 | "src/"
404 | ]
405 | },
406 | "notification-url": "https://packagist.org/downloads/",
407 | "license": [
408 | "BSD-3-Clause"
409 | ],
410 | "authors": [
411 | {
412 | "name": "Sebastian Bergmann",
413 | "email": "sebastian@phpunit.de",
414 | "role": "lead"
415 | }
416 | ],
417 | "description": "Simple template engine.",
418 | "homepage": "https://github.com/sebastianbergmann/php-text-template/",
419 | "keywords": [
420 | "template"
421 | ],
422 | "support": {
423 | "issues": "https://github.com/sebastianbergmann/php-text-template/issues",
424 | "source": "https://github.com/sebastianbergmann/php-text-template/tree/1.2.1"
425 | },
426 | "time": "2015-06-21T13:50:34+00:00"
427 | },
428 | {
429 | "name": "phpunit/php-timer",
430 | "version": "2.1.3",
431 | "source": {
432 | "type": "git",
433 | "url": "https://github.com/sebastianbergmann/php-timer.git",
434 | "reference": "2454ae1765516d20c4ffe103d85a58a9a3bd5662"
435 | },
436 | "dist": {
437 | "type": "zip",
438 | "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/2454ae1765516d20c4ffe103d85a58a9a3bd5662",
439 | "reference": "2454ae1765516d20c4ffe103d85a58a9a3bd5662",
440 | "shasum": ""
441 | },
442 | "require": {
443 | "php": ">=7.1"
444 | },
445 | "require-dev": {
446 | "phpunit/phpunit": "^8.5"
447 | },
448 | "type": "library",
449 | "extra": {
450 | "branch-alias": {
451 | "dev-master": "2.1-dev"
452 | }
453 | },
454 | "autoload": {
455 | "classmap": [
456 | "src/"
457 | ]
458 | },
459 | "notification-url": "https://packagist.org/downloads/",
460 | "license": [
461 | "BSD-3-Clause"
462 | ],
463 | "authors": [
464 | {
465 | "name": "Sebastian Bergmann",
466 | "email": "sebastian@phpunit.de",
467 | "role": "lead"
468 | }
469 | ],
470 | "description": "Utility class for timing",
471 | "homepage": "https://github.com/sebastianbergmann/php-timer/",
472 | "keywords": [
473 | "timer"
474 | ],
475 | "support": {
476 | "issues": "https://github.com/sebastianbergmann/php-timer/issues",
477 | "source": "https://github.com/sebastianbergmann/php-timer/tree/2.1.3"
478 | },
479 | "funding": [
480 | {
481 | "url": "https://github.com/sebastianbergmann",
482 | "type": "github"
483 | }
484 | ],
485 | "time": "2020-11-30T08:20:02+00:00"
486 | },
487 | {
488 | "name": "phpunit/php-token-stream",
489 | "version": "4.0.4",
490 | "source": {
491 | "type": "git",
492 | "url": "https://github.com/sebastianbergmann/php-token-stream.git",
493 | "reference": "a853a0e183b9db7eed023d7933a858fa1c8d25a3"
494 | },
495 | "dist": {
496 | "type": "zip",
497 | "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/a853a0e183b9db7eed023d7933a858fa1c8d25a3",
498 | "reference": "a853a0e183b9db7eed023d7933a858fa1c8d25a3",
499 | "shasum": ""
500 | },
501 | "require": {
502 | "ext-tokenizer": "*",
503 | "php": "^7.3 || ^8.0"
504 | },
505 | "require-dev": {
506 | "phpunit/phpunit": "^9.0"
507 | },
508 | "type": "library",
509 | "extra": {
510 | "branch-alias": {
511 | "dev-master": "4.0-dev"
512 | }
513 | },
514 | "autoload": {
515 | "classmap": [
516 | "src/"
517 | ]
518 | },
519 | "notification-url": "https://packagist.org/downloads/",
520 | "license": [
521 | "BSD-3-Clause"
522 | ],
523 | "authors": [
524 | {
525 | "name": "Sebastian Bergmann",
526 | "email": "sebastian@phpunit.de"
527 | }
528 | ],
529 | "description": "Wrapper around PHP's tokenizer extension.",
530 | "homepage": "https://github.com/sebastianbergmann/php-token-stream/",
531 | "keywords": [
532 | "tokenizer"
533 | ],
534 | "support": {
535 | "issues": "https://github.com/sebastianbergmann/php-token-stream/issues",
536 | "source": "https://github.com/sebastianbergmann/php-token-stream/tree/master"
537 | },
538 | "funding": [
539 | {
540 | "url": "https://github.com/sebastianbergmann",
541 | "type": "github"
542 | }
543 | ],
544 | "abandoned": true,
545 | "time": "2020-08-04T08:28:15+00:00"
546 | },
547 | {
548 | "name": "phpunit/phpunit",
549 | "version": "8.5.31",
550 | "source": {
551 | "type": "git",
552 | "url": "https://github.com/sebastianbergmann/phpunit.git",
553 | "reference": "33c126b09a42de5c99e5e8032b54e8221264a74e"
554 | },
555 | "dist": {
556 | "type": "zip",
557 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/33c126b09a42de5c99e5e8032b54e8221264a74e",
558 | "reference": "33c126b09a42de5c99e5e8032b54e8221264a74e",
559 | "shasum": ""
560 | },
561 | "require": {
562 | "doctrine/instantiator": "^1.3.1",
563 | "ext-dom": "*",
564 | "ext-json": "*",
565 | "ext-libxml": "*",
566 | "ext-mbstring": "*",
567 | "ext-xml": "*",
568 | "ext-xmlwriter": "*",
569 | "myclabs/deep-copy": "^1.10.0",
570 | "phar-io/manifest": "^2.0.3",
571 | "phar-io/version": "^3.0.2",
572 | "php": ">=7.2",
573 | "phpunit/php-code-coverage": "^7.0.12",
574 | "phpunit/php-file-iterator": "^2.0.4",
575 | "phpunit/php-text-template": "^1.2.1",
576 | "phpunit/php-timer": "^2.1.2",
577 | "sebastian/comparator": "^3.0.5",
578 | "sebastian/diff": "^3.0.2",
579 | "sebastian/environment": "^4.2.3",
580 | "sebastian/exporter": "^3.1.5",
581 | "sebastian/global-state": "^3.0.0",
582 | "sebastian/object-enumerator": "^3.0.3",
583 | "sebastian/resource-operations": "^2.0.1",
584 | "sebastian/type": "^1.1.3",
585 | "sebastian/version": "^2.0.1"
586 | },
587 | "suggest": {
588 | "ext-soap": "*",
589 | "ext-xdebug": "*",
590 | "phpunit/php-invoker": "^2.0.0"
591 | },
592 | "bin": [
593 | "phpunit"
594 | ],
595 | "type": "library",
596 | "extra": {
597 | "branch-alias": {
598 | "dev-master": "8.5-dev"
599 | }
600 | },
601 | "autoload": {
602 | "classmap": [
603 | "src/"
604 | ]
605 | },
606 | "notification-url": "https://packagist.org/downloads/",
607 | "license": [
608 | "BSD-3-Clause"
609 | ],
610 | "authors": [
611 | {
612 | "name": "Sebastian Bergmann",
613 | "email": "sebastian@phpunit.de",
614 | "role": "lead"
615 | }
616 | ],
617 | "description": "The PHP Unit Testing framework.",
618 | "homepage": "https://phpunit.de/",
619 | "keywords": [
620 | "phpunit",
621 | "testing",
622 | "xunit"
623 | ],
624 | "support": {
625 | "issues": "https://github.com/sebastianbergmann/phpunit/issues",
626 | "source": "https://github.com/sebastianbergmann/phpunit/tree/8.5.31"
627 | },
628 | "funding": [
629 | {
630 | "url": "https://phpunit.de/sponsors.html",
631 | "type": "custom"
632 | },
633 | {
634 | "url": "https://github.com/sebastianbergmann",
635 | "type": "github"
636 | },
637 | {
638 | "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit",
639 | "type": "tidelift"
640 | }
641 | ],
642 | "time": "2022-10-28T05:57:37+00:00"
643 | },
644 | {
645 | "name": "sebastian/code-unit-reverse-lookup",
646 | "version": "1.0.2",
647 | "source": {
648 | "type": "git",
649 | "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git",
650 | "reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619"
651 | },
652 | "dist": {
653 | "type": "zip",
654 | "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/1de8cd5c010cb153fcd68b8d0f64606f523f7619",
655 | "reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619",
656 | "shasum": ""
657 | },
658 | "require": {
659 | "php": ">=5.6"
660 | },
661 | "require-dev": {
662 | "phpunit/phpunit": "^8.5"
663 | },
664 | "type": "library",
665 | "extra": {
666 | "branch-alias": {
667 | "dev-master": "1.0.x-dev"
668 | }
669 | },
670 | "autoload": {
671 | "classmap": [
672 | "src/"
673 | ]
674 | },
675 | "notification-url": "https://packagist.org/downloads/",
676 | "license": [
677 | "BSD-3-Clause"
678 | ],
679 | "authors": [
680 | {
681 | "name": "Sebastian Bergmann",
682 | "email": "sebastian@phpunit.de"
683 | }
684 | ],
685 | "description": "Looks up which function or method a line of code belongs to",
686 | "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/",
687 | "support": {
688 | "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues",
689 | "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/1.0.2"
690 | },
691 | "funding": [
692 | {
693 | "url": "https://github.com/sebastianbergmann",
694 | "type": "github"
695 | }
696 | ],
697 | "time": "2020-11-30T08:15:22+00:00"
698 | },
699 | {
700 | "name": "sebastian/comparator",
701 | "version": "3.0.5",
702 | "source": {
703 | "type": "git",
704 | "url": "https://github.com/sebastianbergmann/comparator.git",
705 | "reference": "1dc7ceb4a24aede938c7af2a9ed1de09609ca770"
706 | },
707 | "dist": {
708 | "type": "zip",
709 | "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/1dc7ceb4a24aede938c7af2a9ed1de09609ca770",
710 | "reference": "1dc7ceb4a24aede938c7af2a9ed1de09609ca770",
711 | "shasum": ""
712 | },
713 | "require": {
714 | "php": ">=7.1",
715 | "sebastian/diff": "^3.0",
716 | "sebastian/exporter": "^3.1"
717 | },
718 | "require-dev": {
719 | "phpunit/phpunit": "^8.5"
720 | },
721 | "type": "library",
722 | "extra": {
723 | "branch-alias": {
724 | "dev-master": "3.0-dev"
725 | }
726 | },
727 | "autoload": {
728 | "classmap": [
729 | "src/"
730 | ]
731 | },
732 | "notification-url": "https://packagist.org/downloads/",
733 | "license": [
734 | "BSD-3-Clause"
735 | ],
736 | "authors": [
737 | {
738 | "name": "Sebastian Bergmann",
739 | "email": "sebastian@phpunit.de"
740 | },
741 | {
742 | "name": "Jeff Welch",
743 | "email": "whatthejeff@gmail.com"
744 | },
745 | {
746 | "name": "Volker Dusch",
747 | "email": "github@wallbash.com"
748 | },
749 | {
750 | "name": "Bernhard Schussek",
751 | "email": "bschussek@2bepublished.at"
752 | }
753 | ],
754 | "description": "Provides the functionality to compare PHP values for equality",
755 | "homepage": "https://github.com/sebastianbergmann/comparator",
756 | "keywords": [
757 | "comparator",
758 | "compare",
759 | "equality"
760 | ],
761 | "support": {
762 | "issues": "https://github.com/sebastianbergmann/comparator/issues",
763 | "source": "https://github.com/sebastianbergmann/comparator/tree/3.0.5"
764 | },
765 | "funding": [
766 | {
767 | "url": "https://github.com/sebastianbergmann",
768 | "type": "github"
769 | }
770 | ],
771 | "time": "2022-09-14T12:31:48+00:00"
772 | },
773 | {
774 | "name": "sebastian/diff",
775 | "version": "3.0.3",
776 | "source": {
777 | "type": "git",
778 | "url": "https://github.com/sebastianbergmann/diff.git",
779 | "reference": "14f72dd46eaf2f2293cbe79c93cc0bc43161a211"
780 | },
781 | "dist": {
782 | "type": "zip",
783 | "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/14f72dd46eaf2f2293cbe79c93cc0bc43161a211",
784 | "reference": "14f72dd46eaf2f2293cbe79c93cc0bc43161a211",
785 | "shasum": ""
786 | },
787 | "require": {
788 | "php": ">=7.1"
789 | },
790 | "require-dev": {
791 | "phpunit/phpunit": "^7.5 || ^8.0",
792 | "symfony/process": "^2 || ^3.3 || ^4"
793 | },
794 | "type": "library",
795 | "extra": {
796 | "branch-alias": {
797 | "dev-master": "3.0-dev"
798 | }
799 | },
800 | "autoload": {
801 | "classmap": [
802 | "src/"
803 | ]
804 | },
805 | "notification-url": "https://packagist.org/downloads/",
806 | "license": [
807 | "BSD-3-Clause"
808 | ],
809 | "authors": [
810 | {
811 | "name": "Sebastian Bergmann",
812 | "email": "sebastian@phpunit.de"
813 | },
814 | {
815 | "name": "Kore Nordmann",
816 | "email": "mail@kore-nordmann.de"
817 | }
818 | ],
819 | "description": "Diff implementation",
820 | "homepage": "https://github.com/sebastianbergmann/diff",
821 | "keywords": [
822 | "diff",
823 | "udiff",
824 | "unidiff",
825 | "unified diff"
826 | ],
827 | "support": {
828 | "issues": "https://github.com/sebastianbergmann/diff/issues",
829 | "source": "https://github.com/sebastianbergmann/diff/tree/3.0.3"
830 | },
831 | "funding": [
832 | {
833 | "url": "https://github.com/sebastianbergmann",
834 | "type": "github"
835 | }
836 | ],
837 | "time": "2020-11-30T07:59:04+00:00"
838 | },
839 | {
840 | "name": "sebastian/environment",
841 | "version": "4.2.4",
842 | "source": {
843 | "type": "git",
844 | "url": "https://github.com/sebastianbergmann/environment.git",
845 | "reference": "d47bbbad83711771f167c72d4e3f25f7fcc1f8b0"
846 | },
847 | "dist": {
848 | "type": "zip",
849 | "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/d47bbbad83711771f167c72d4e3f25f7fcc1f8b0",
850 | "reference": "d47bbbad83711771f167c72d4e3f25f7fcc1f8b0",
851 | "shasum": ""
852 | },
853 | "require": {
854 | "php": ">=7.1"
855 | },
856 | "require-dev": {
857 | "phpunit/phpunit": "^7.5"
858 | },
859 | "suggest": {
860 | "ext-posix": "*"
861 | },
862 | "type": "library",
863 | "extra": {
864 | "branch-alias": {
865 | "dev-master": "4.2-dev"
866 | }
867 | },
868 | "autoload": {
869 | "classmap": [
870 | "src/"
871 | ]
872 | },
873 | "notification-url": "https://packagist.org/downloads/",
874 | "license": [
875 | "BSD-3-Clause"
876 | ],
877 | "authors": [
878 | {
879 | "name": "Sebastian Bergmann",
880 | "email": "sebastian@phpunit.de"
881 | }
882 | ],
883 | "description": "Provides functionality to handle HHVM/PHP environments",
884 | "homepage": "http://www.github.com/sebastianbergmann/environment",
885 | "keywords": [
886 | "Xdebug",
887 | "environment",
888 | "hhvm"
889 | ],
890 | "support": {
891 | "issues": "https://github.com/sebastianbergmann/environment/issues",
892 | "source": "https://github.com/sebastianbergmann/environment/tree/4.2.4"
893 | },
894 | "funding": [
895 | {
896 | "url": "https://github.com/sebastianbergmann",
897 | "type": "github"
898 | }
899 | ],
900 | "time": "2020-11-30T07:53:42+00:00"
901 | },
902 | {
903 | "name": "sebastian/exporter",
904 | "version": "3.1.5",
905 | "source": {
906 | "type": "git",
907 | "url": "https://github.com/sebastianbergmann/exporter.git",
908 | "reference": "73a9676f2833b9a7c36968f9d882589cd75511e6"
909 | },
910 | "dist": {
911 | "type": "zip",
912 | "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/73a9676f2833b9a7c36968f9d882589cd75511e6",
913 | "reference": "73a9676f2833b9a7c36968f9d882589cd75511e6",
914 | "shasum": ""
915 | },
916 | "require": {
917 | "php": ">=7.0",
918 | "sebastian/recursion-context": "^3.0"
919 | },
920 | "require-dev": {
921 | "ext-mbstring": "*",
922 | "phpunit/phpunit": "^8.5"
923 | },
924 | "type": "library",
925 | "extra": {
926 | "branch-alias": {
927 | "dev-master": "3.1.x-dev"
928 | }
929 | },
930 | "autoload": {
931 | "classmap": [
932 | "src/"
933 | ]
934 | },
935 | "notification-url": "https://packagist.org/downloads/",
936 | "license": [
937 | "BSD-3-Clause"
938 | ],
939 | "authors": [
940 | {
941 | "name": "Sebastian Bergmann",
942 | "email": "sebastian@phpunit.de"
943 | },
944 | {
945 | "name": "Jeff Welch",
946 | "email": "whatthejeff@gmail.com"
947 | },
948 | {
949 | "name": "Volker Dusch",
950 | "email": "github@wallbash.com"
951 | },
952 | {
953 | "name": "Adam Harvey",
954 | "email": "aharvey@php.net"
955 | },
956 | {
957 | "name": "Bernhard Schussek",
958 | "email": "bschussek@gmail.com"
959 | }
960 | ],
961 | "description": "Provides the functionality to export PHP variables for visualization",
962 | "homepage": "http://www.github.com/sebastianbergmann/exporter",
963 | "keywords": [
964 | "export",
965 | "exporter"
966 | ],
967 | "support": {
968 | "issues": "https://github.com/sebastianbergmann/exporter/issues",
969 | "source": "https://github.com/sebastianbergmann/exporter/tree/3.1.5"
970 | },
971 | "funding": [
972 | {
973 | "url": "https://github.com/sebastianbergmann",
974 | "type": "github"
975 | }
976 | ],
977 | "time": "2022-09-14T06:00:17+00:00"
978 | },
979 | {
980 | "name": "sebastian/global-state",
981 | "version": "3.0.2",
982 | "source": {
983 | "type": "git",
984 | "url": "https://github.com/sebastianbergmann/global-state.git",
985 | "reference": "de036ec91d55d2a9e0db2ba975b512cdb1c23921"
986 | },
987 | "dist": {
988 | "type": "zip",
989 | "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/de036ec91d55d2a9e0db2ba975b512cdb1c23921",
990 | "reference": "de036ec91d55d2a9e0db2ba975b512cdb1c23921",
991 | "shasum": ""
992 | },
993 | "require": {
994 | "php": ">=7.2",
995 | "sebastian/object-reflector": "^1.1.1",
996 | "sebastian/recursion-context": "^3.0"
997 | },
998 | "require-dev": {
999 | "ext-dom": "*",
1000 | "phpunit/phpunit": "^8.0"
1001 | },
1002 | "suggest": {
1003 | "ext-uopz": "*"
1004 | },
1005 | "type": "library",
1006 | "extra": {
1007 | "branch-alias": {
1008 | "dev-master": "3.0-dev"
1009 | }
1010 | },
1011 | "autoload": {
1012 | "classmap": [
1013 | "src/"
1014 | ]
1015 | },
1016 | "notification-url": "https://packagist.org/downloads/",
1017 | "license": [
1018 | "BSD-3-Clause"
1019 | ],
1020 | "authors": [
1021 | {
1022 | "name": "Sebastian Bergmann",
1023 | "email": "sebastian@phpunit.de"
1024 | }
1025 | ],
1026 | "description": "Snapshotting of global state",
1027 | "homepage": "http://www.github.com/sebastianbergmann/global-state",
1028 | "keywords": [
1029 | "global state"
1030 | ],
1031 | "support": {
1032 | "issues": "https://github.com/sebastianbergmann/global-state/issues",
1033 | "source": "https://github.com/sebastianbergmann/global-state/tree/3.0.2"
1034 | },
1035 | "funding": [
1036 | {
1037 | "url": "https://github.com/sebastianbergmann",
1038 | "type": "github"
1039 | }
1040 | ],
1041 | "time": "2022-02-10T06:55:38+00:00"
1042 | },
1043 | {
1044 | "name": "sebastian/object-enumerator",
1045 | "version": "3.0.4",
1046 | "source": {
1047 | "type": "git",
1048 | "url": "https://github.com/sebastianbergmann/object-enumerator.git",
1049 | "reference": "e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2"
1050 | },
1051 | "dist": {
1052 | "type": "zip",
1053 | "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2",
1054 | "reference": "e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2",
1055 | "shasum": ""
1056 | },
1057 | "require": {
1058 | "php": ">=7.0",
1059 | "sebastian/object-reflector": "^1.1.1",
1060 | "sebastian/recursion-context": "^3.0"
1061 | },
1062 | "require-dev": {
1063 | "phpunit/phpunit": "^6.0"
1064 | },
1065 | "type": "library",
1066 | "extra": {
1067 | "branch-alias": {
1068 | "dev-master": "3.0.x-dev"
1069 | }
1070 | },
1071 | "autoload": {
1072 | "classmap": [
1073 | "src/"
1074 | ]
1075 | },
1076 | "notification-url": "https://packagist.org/downloads/",
1077 | "license": [
1078 | "BSD-3-Clause"
1079 | ],
1080 | "authors": [
1081 | {
1082 | "name": "Sebastian Bergmann",
1083 | "email": "sebastian@phpunit.de"
1084 | }
1085 | ],
1086 | "description": "Traverses array structures and object graphs to enumerate all referenced objects",
1087 | "homepage": "https://github.com/sebastianbergmann/object-enumerator/",
1088 | "support": {
1089 | "issues": "https://github.com/sebastianbergmann/object-enumerator/issues",
1090 | "source": "https://github.com/sebastianbergmann/object-enumerator/tree/3.0.4"
1091 | },
1092 | "funding": [
1093 | {
1094 | "url": "https://github.com/sebastianbergmann",
1095 | "type": "github"
1096 | }
1097 | ],
1098 | "time": "2020-11-30T07:40:27+00:00"
1099 | },
1100 | {
1101 | "name": "sebastian/object-reflector",
1102 | "version": "1.1.2",
1103 | "source": {
1104 | "type": "git",
1105 | "url": "https://github.com/sebastianbergmann/object-reflector.git",
1106 | "reference": "9b8772b9cbd456ab45d4a598d2dd1a1bced6363d"
1107 | },
1108 | "dist": {
1109 | "type": "zip",
1110 | "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/9b8772b9cbd456ab45d4a598d2dd1a1bced6363d",
1111 | "reference": "9b8772b9cbd456ab45d4a598d2dd1a1bced6363d",
1112 | "shasum": ""
1113 | },
1114 | "require": {
1115 | "php": ">=7.0"
1116 | },
1117 | "require-dev": {
1118 | "phpunit/phpunit": "^6.0"
1119 | },
1120 | "type": "library",
1121 | "extra": {
1122 | "branch-alias": {
1123 | "dev-master": "1.1-dev"
1124 | }
1125 | },
1126 | "autoload": {
1127 | "classmap": [
1128 | "src/"
1129 | ]
1130 | },
1131 | "notification-url": "https://packagist.org/downloads/",
1132 | "license": [
1133 | "BSD-3-Clause"
1134 | ],
1135 | "authors": [
1136 | {
1137 | "name": "Sebastian Bergmann",
1138 | "email": "sebastian@phpunit.de"
1139 | }
1140 | ],
1141 | "description": "Allows reflection of object attributes, including inherited and non-public ones",
1142 | "homepage": "https://github.com/sebastianbergmann/object-reflector/",
1143 | "support": {
1144 | "issues": "https://github.com/sebastianbergmann/object-reflector/issues",
1145 | "source": "https://github.com/sebastianbergmann/object-reflector/tree/1.1.2"
1146 | },
1147 | "funding": [
1148 | {
1149 | "url": "https://github.com/sebastianbergmann",
1150 | "type": "github"
1151 | }
1152 | ],
1153 | "time": "2020-11-30T07:37:18+00:00"
1154 | },
1155 | {
1156 | "name": "sebastian/recursion-context",
1157 | "version": "3.0.1",
1158 | "source": {
1159 | "type": "git",
1160 | "url": "https://github.com/sebastianbergmann/recursion-context.git",
1161 | "reference": "367dcba38d6e1977be014dc4b22f47a484dac7fb"
1162 | },
1163 | "dist": {
1164 | "type": "zip",
1165 | "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/367dcba38d6e1977be014dc4b22f47a484dac7fb",
1166 | "reference": "367dcba38d6e1977be014dc4b22f47a484dac7fb",
1167 | "shasum": ""
1168 | },
1169 | "require": {
1170 | "php": ">=7.0"
1171 | },
1172 | "require-dev": {
1173 | "phpunit/phpunit": "^6.0"
1174 | },
1175 | "type": "library",
1176 | "extra": {
1177 | "branch-alias": {
1178 | "dev-master": "3.0.x-dev"
1179 | }
1180 | },
1181 | "autoload": {
1182 | "classmap": [
1183 | "src/"
1184 | ]
1185 | },
1186 | "notification-url": "https://packagist.org/downloads/",
1187 | "license": [
1188 | "BSD-3-Clause"
1189 | ],
1190 | "authors": [
1191 | {
1192 | "name": "Sebastian Bergmann",
1193 | "email": "sebastian@phpunit.de"
1194 | },
1195 | {
1196 | "name": "Jeff Welch",
1197 | "email": "whatthejeff@gmail.com"
1198 | },
1199 | {
1200 | "name": "Adam Harvey",
1201 | "email": "aharvey@php.net"
1202 | }
1203 | ],
1204 | "description": "Provides functionality to recursively process PHP variables",
1205 | "homepage": "http://www.github.com/sebastianbergmann/recursion-context",
1206 | "support": {
1207 | "issues": "https://github.com/sebastianbergmann/recursion-context/issues",
1208 | "source": "https://github.com/sebastianbergmann/recursion-context/tree/3.0.1"
1209 | },
1210 | "funding": [
1211 | {
1212 | "url": "https://github.com/sebastianbergmann",
1213 | "type": "github"
1214 | }
1215 | ],
1216 | "time": "2020-11-30T07:34:24+00:00"
1217 | },
1218 | {
1219 | "name": "sebastian/resource-operations",
1220 | "version": "2.0.2",
1221 | "source": {
1222 | "type": "git",
1223 | "url": "https://github.com/sebastianbergmann/resource-operations.git",
1224 | "reference": "31d35ca87926450c44eae7e2611d45a7a65ea8b3"
1225 | },
1226 | "dist": {
1227 | "type": "zip",
1228 | "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/31d35ca87926450c44eae7e2611d45a7a65ea8b3",
1229 | "reference": "31d35ca87926450c44eae7e2611d45a7a65ea8b3",
1230 | "shasum": ""
1231 | },
1232 | "require": {
1233 | "php": ">=7.1"
1234 | },
1235 | "type": "library",
1236 | "extra": {
1237 | "branch-alias": {
1238 | "dev-master": "2.0-dev"
1239 | }
1240 | },
1241 | "autoload": {
1242 | "classmap": [
1243 | "src/"
1244 | ]
1245 | },
1246 | "notification-url": "https://packagist.org/downloads/",
1247 | "license": [
1248 | "BSD-3-Clause"
1249 | ],
1250 | "authors": [
1251 | {
1252 | "name": "Sebastian Bergmann",
1253 | "email": "sebastian@phpunit.de"
1254 | }
1255 | ],
1256 | "description": "Provides a list of PHP built-in functions that operate on resources",
1257 | "homepage": "https://www.github.com/sebastianbergmann/resource-operations",
1258 | "support": {
1259 | "issues": "https://github.com/sebastianbergmann/resource-operations/issues",
1260 | "source": "https://github.com/sebastianbergmann/resource-operations/tree/2.0.2"
1261 | },
1262 | "funding": [
1263 | {
1264 | "url": "https://github.com/sebastianbergmann",
1265 | "type": "github"
1266 | }
1267 | ],
1268 | "time": "2020-11-30T07:30:19+00:00"
1269 | },
1270 | {
1271 | "name": "sebastian/type",
1272 | "version": "1.1.4",
1273 | "source": {
1274 | "type": "git",
1275 | "url": "https://github.com/sebastianbergmann/type.git",
1276 | "reference": "0150cfbc4495ed2df3872fb31b26781e4e077eb4"
1277 | },
1278 | "dist": {
1279 | "type": "zip",
1280 | "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/0150cfbc4495ed2df3872fb31b26781e4e077eb4",
1281 | "reference": "0150cfbc4495ed2df3872fb31b26781e4e077eb4",
1282 | "shasum": ""
1283 | },
1284 | "require": {
1285 | "php": ">=7.2"
1286 | },
1287 | "require-dev": {
1288 | "phpunit/phpunit": "^8.2"
1289 | },
1290 | "type": "library",
1291 | "extra": {
1292 | "branch-alias": {
1293 | "dev-master": "1.1-dev"
1294 | }
1295 | },
1296 | "autoload": {
1297 | "classmap": [
1298 | "src/"
1299 | ]
1300 | },
1301 | "notification-url": "https://packagist.org/downloads/",
1302 | "license": [
1303 | "BSD-3-Clause"
1304 | ],
1305 | "authors": [
1306 | {
1307 | "name": "Sebastian Bergmann",
1308 | "email": "sebastian@phpunit.de",
1309 | "role": "lead"
1310 | }
1311 | ],
1312 | "description": "Collection of value objects that represent the types of the PHP type system",
1313 | "homepage": "https://github.com/sebastianbergmann/type",
1314 | "support": {
1315 | "issues": "https://github.com/sebastianbergmann/type/issues",
1316 | "source": "https://github.com/sebastianbergmann/type/tree/1.1.4"
1317 | },
1318 | "funding": [
1319 | {
1320 | "url": "https://github.com/sebastianbergmann",
1321 | "type": "github"
1322 | }
1323 | ],
1324 | "time": "2020-11-30T07:25:11+00:00"
1325 | },
1326 | {
1327 | "name": "sebastian/version",
1328 | "version": "2.0.1",
1329 | "source": {
1330 | "type": "git",
1331 | "url": "https://github.com/sebastianbergmann/version.git",
1332 | "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019"
1333 | },
1334 | "dist": {
1335 | "type": "zip",
1336 | "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019",
1337 | "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019",
1338 | "shasum": ""
1339 | },
1340 | "require": {
1341 | "php": ">=5.6"
1342 | },
1343 | "type": "library",
1344 | "extra": {
1345 | "branch-alias": {
1346 | "dev-master": "2.0.x-dev"
1347 | }
1348 | },
1349 | "autoload": {
1350 | "classmap": [
1351 | "src/"
1352 | ]
1353 | },
1354 | "notification-url": "https://packagist.org/downloads/",
1355 | "license": [
1356 | "BSD-3-Clause"
1357 | ],
1358 | "authors": [
1359 | {
1360 | "name": "Sebastian Bergmann",
1361 | "email": "sebastian@phpunit.de",
1362 | "role": "lead"
1363 | }
1364 | ],
1365 | "description": "Library that helps with managing the version number of Git-hosted PHP projects",
1366 | "homepage": "https://github.com/sebastianbergmann/version",
1367 | "support": {
1368 | "issues": "https://github.com/sebastianbergmann/version/issues",
1369 | "source": "https://github.com/sebastianbergmann/version/tree/master"
1370 | },
1371 | "time": "2016-10-03T07:35:21+00:00"
1372 | },
1373 | {
1374 | "name": "squizlabs/php_codesniffer",
1375 | "version": "3.7.1",
1376 | "source": {
1377 | "type": "git",
1378 | "url": "https://github.com/squizlabs/PHP_CodeSniffer.git",
1379 | "reference": "1359e176e9307e906dc3d890bcc9603ff6d90619"
1380 | },
1381 | "dist": {
1382 | "type": "zip",
1383 | "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/1359e176e9307e906dc3d890bcc9603ff6d90619",
1384 | "reference": "1359e176e9307e906dc3d890bcc9603ff6d90619",
1385 | "shasum": ""
1386 | },
1387 | "require": {
1388 | "ext-simplexml": "*",
1389 | "ext-tokenizer": "*",
1390 | "ext-xmlwriter": "*",
1391 | "php": ">=5.4.0"
1392 | },
1393 | "require-dev": {
1394 | "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0"
1395 | },
1396 | "bin": [
1397 | "bin/phpcs",
1398 | "bin/phpcbf"
1399 | ],
1400 | "type": "library",
1401 | "extra": {
1402 | "branch-alias": {
1403 | "dev-master": "3.x-dev"
1404 | }
1405 | },
1406 | "notification-url": "https://packagist.org/downloads/",
1407 | "license": [
1408 | "BSD-3-Clause"
1409 | ],
1410 | "authors": [
1411 | {
1412 | "name": "Greg Sherwood",
1413 | "role": "lead"
1414 | }
1415 | ],
1416 | "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.",
1417 | "homepage": "https://github.com/squizlabs/PHP_CodeSniffer",
1418 | "keywords": [
1419 | "phpcs",
1420 | "standards"
1421 | ],
1422 | "support": {
1423 | "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues",
1424 | "source": "https://github.com/squizlabs/PHP_CodeSniffer",
1425 | "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki"
1426 | },
1427 | "time": "2022-06-18T07:21:10+00:00"
1428 | },
1429 | {
1430 | "name": "theseer/tokenizer",
1431 | "version": "1.2.1",
1432 | "source": {
1433 | "type": "git",
1434 | "url": "https://github.com/theseer/tokenizer.git",
1435 | "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e"
1436 | },
1437 | "dist": {
1438 | "type": "zip",
1439 | "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e",
1440 | "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e",
1441 | "shasum": ""
1442 | },
1443 | "require": {
1444 | "ext-dom": "*",
1445 | "ext-tokenizer": "*",
1446 | "ext-xmlwriter": "*",
1447 | "php": "^7.2 || ^8.0"
1448 | },
1449 | "type": "library",
1450 | "autoload": {
1451 | "classmap": [
1452 | "src/"
1453 | ]
1454 | },
1455 | "notification-url": "https://packagist.org/downloads/",
1456 | "license": [
1457 | "BSD-3-Clause"
1458 | ],
1459 | "authors": [
1460 | {
1461 | "name": "Arne Blankerts",
1462 | "email": "arne@blankerts.de",
1463 | "role": "Developer"
1464 | }
1465 | ],
1466 | "description": "A small library for converting tokenized PHP source code into XML and potentially other formats",
1467 | "support": {
1468 | "issues": "https://github.com/theseer/tokenizer/issues",
1469 | "source": "https://github.com/theseer/tokenizer/tree/1.2.1"
1470 | },
1471 | "funding": [
1472 | {
1473 | "url": "https://github.com/theseer",
1474 | "type": "github"
1475 | }
1476 | ],
1477 | "time": "2021-07-28T10:34:58+00:00"
1478 | }
1479 | ],
1480 | "aliases": [],
1481 | "minimum-stability": "beta",
1482 | "stability-flags": [],
1483 | "prefer-stable": false,
1484 | "prefer-lowest": false,
1485 | "platform": {
1486 | "php": ">=7.1"
1487 | },
1488 | "platform-dev": [],
1489 | "plugin-api-version": "2.3.0"
1490 | }
1491 |
--------------------------------------------------------------------------------
/dev-smoke-test.php:
--------------------------------------------------------------------------------
1 | getenv("CLIENT_ID"),
18 | "client_secret" => getenv("CLIENT_SECRET"),
19 | "access_token" => getenv("ACCESS_TOKEN"),
20 | "refresh_token" => getenv("REFRESH_TOKEN"),
21 | "data_center" => $dataCenter,
22 | ]);
23 |
24 | $sub = getenv("SUB");
25 | $calendarId = getenv("CALENDAR_ID");
26 | $start = date("Y-m-d", strtotime('tomorrow')) . "T09:30:00Z";
27 | $end = date("Y-m-d", strtotime('tomorrow')) . "T10:00:00Z";
28 |
29 | $yesterday = date("Y-m-d", strtotime('yesterday'));
30 | $next_week = date("Y-m-d", strtotime('next week'));
31 |
32 | $testEventId = 'php-smoke-test-001';
33 | $testEventData = [
34 | 'calendar_id' => $calendarId,
35 | 'event_id' => $testEventId,
36 | 'summary' => 'PHP SDK test event 001',
37 | 'description' => 'Just checking this thing is on!',
38 | 'start' => $start,
39 | 'end' => $end,
40 | ];
41 |
42 | echo "Writing test events to " . $dataCenter . ", account " . $sub . ", calendar " . $calendarId . "\n";
43 |
44 | if ( $testBatch ) {
45 | $batch = Batch::create()
46 | ->upsertEvent($calendarId, $testEventData)
47 | ->deleteEvent($calendarId, $testEventId)
48 | ->deleteEvent("fake-calendar-id", "just-want-it-to-fail")
49 | ->upsertEvent($calendarId, []);
50 |
51 | try {
52 | $result = $cronofy->executeBatch($batch);
53 |
54 | } catch (PartialBatchFailureException $exception) {
55 | echo "PARTIAL FAILURE\n\n";
56 | $result = $exception->result();
57 | } finally {
58 | foreach ($result->responses() as $index=>$response) {
59 | echo "Request " . $index . " - " . $response->request()->method() . " " . $response->request()->relativeUrl() . "\n";
60 | echo $response->hasSuccessStatus() ? " Success" : " Failed";
61 | echo "\n";
62 | echo " status " . $response->status() . "\n";
63 |
64 | echo " headers ";
65 | $headers = $response->headers();
66 | print_r($headers);
67 | echo "\n";
68 |
69 | echo " data ";
70 | $data = $response->data();
71 | print_r($data);
72 | echo "\n\n";
73 | }
74 | }
75 | }
76 |
77 | if( $testAvailablePeriod ) {
78 | echo "Creating AvailablePeriod\n";
79 | $ap_id = "test_available_period_001";
80 |
81 | $params = [
82 | "available_period_id" => $ap_id,
83 | "start" => $start,
84 | "end" => $end,
85 | ];
86 |
87 | $cronofy->createAvailablePeriod($params);
88 |
89 | echo "Reading Available Period\n";
90 |
91 | $readParams = [
92 | "from" => $yesterday,
93 | "to" => $next_week,
94 | "tzid" => "Europe/London",
95 | ];
96 |
97 | $periods = $cronofy->readAvailablePeriods($readParams);
98 | foreach($periods->each() as $available_period){
99 | print_r($available_period);
100 | }
101 |
102 | echo "\n";
103 | echo "Deleting Available Period\n";
104 |
105 | $params = [
106 | "available_period_id" => $ap_id,
107 | ];
108 |
109 | $result = $cronofy->deleteAvailablePeriod($params);
110 | print_r($result);
111 |
112 | $periods = $cronofy->readAvailablePeriods($readParams);
113 | foreach($periods->each() as $available_period){
114 | print_r($available_period);
115 | }
116 | }
117 |
118 | if( $testRecurrence ) {
119 | echo "\n";
120 | echo "Creating event with recurrence\n";
121 |
122 | $recurrenceEventParams = $testEventData;
123 | $recurrenceEventParams['recurrence'] = [
124 | "rules" => [
125 | [
126 | "frequency" => "daily",
127 | "interval" => 2,
128 | "count" => 3,
129 | ],
130 | ],
131 | ];
132 |
133 | $cronofy->upsertEvent($recurrenceEventParams);
134 | echo "\n";
135 | }
136 |
137 | if($testRTS){
138 | echo "Checking RTS\n";
139 |
140 | $event = [
141 | "event_id" => "php-smoke-test-002",
142 | "summary" => "Add to Calendar test event",
143 | ];
144 |
145 | $availability = [
146 | "participants" => [
147 | [
148 | "members" => [
149 | [
150 | "sub" => $sub,
151 | "calendar_ids" => [$calendarId]
152 | ]
153 | ],
154 | "required" => "all"
155 | ]
156 | ],
157 | "event" => $event,
158 | "required_duration" => [
159 | "minutes" => 60
160 | ],
161 | "available_periods" => [
162 | [
163 | "start" => $start,
164 | "end" => $end
165 | ]
166 | ]
167 | ];
168 | $target_calendars = [
169 | [
170 | "sub" => $sub,
171 | "calendar_id" => $calendarId
172 | ]
173 | ];
174 | $tzid = 'Europe/London';
175 |
176 | $params = [
177 | "event" => $event,
178 | "target_calendars" => $target_calendars,
179 | "availability" => $availability,
180 | "tzid" => $tzid,
181 | "oauth" => [
182 | "redirect_uri" => "http://local.cronofy.com/redirect"
183 | ],
184 | "formatting" => [
185 | "hour_format" => "H",
186 | ],
187 | "minimum_notice" => [
188 | "hours" => 2
189 | ],
190 | "redirect_urls" => [
191 | "completed_url" => "http://local.cronofy.com/complete",
192 | "no_times_suitable_url" => "http://local.cronofy.com/need_more_times_please",
193 | ],
194 | "callback_urls" => [
195 | "completed_url" => "http://local.cronofy.com/callback/complete",
196 | ],
197 | "event_creation" => "single",
198 | ];
199 |
200 | $rts = $cronofy->realTimeScheduling($params);
201 | echo "RTS Created:\n";
202 | print_r($rts);
203 |
204 | $rts_id = $rts["real_time_scheduling"]["real_time_scheduling_id"];
205 |
206 | echo "Cancelling RTS\n";
207 | $params =[
208 | "id" => $rts_id,
209 | "display_message" => "Testing disable"
210 | ];
211 |
212 | $cronofy->realTimeSchedulingDisable($params);
213 | }
214 |
--------------------------------------------------------------------------------
/init:
--------------------------------------------------------------------------------
1 | #! /bin/bash
2 |
3 | brew install php jq
4 |
--------------------------------------------------------------------------------
/phpunit.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | tests
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ruleset.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | The Cronofy coding standard based on PSR2 but relaxed slightly.
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/Batch/Batch.php:
--------------------------------------------------------------------------------
1 | buildEventsPath($calendarId);
20 |
21 | return $this->addPostRequest($path, $data);
22 | }
23 |
24 | public function deleteEvent(string $calendarId, string $eventId): self
25 | {
26 | $path = $this->buildEventsPath($calendarId);
27 | $data = ['event_id' => $eventId];
28 |
29 | return $this->addDeleteRequest($path, $data);
30 | }
31 |
32 | public function updateExternalEvent(string $calendarId, array $data): self
33 | {
34 | $path = $this->buildEventsPath($calendarId);
35 |
36 | return $this->addPostRequest($path, $data);
37 | }
38 |
39 | public function deleteExternalEvent(string $calendarId, string $eventUid): self
40 | {
41 | $path = $this->buildEventsPath($calendarId);
42 | $data = ['event_uid' => $eventUid];
43 |
44 | return $this->addDeleteRequest($path, $data);
45 | }
46 |
47 | public function upsertAvailablePeriod(array $data): self
48 | {
49 | $path = $this->buildAvailablePeriodsPath();
50 |
51 | return $this->addPostRequest($path, $data);
52 | }
53 |
54 | public function deleteAvailablePeriod(string $availablePeriodId): self
55 | {
56 | $path = $this->buildAvailablePeriodsPath();
57 | $data = ['available_period_id' => $availablePeriodId];
58 |
59 | return $this->addDeleteRequest($path, $data);
60 | }
61 |
62 | private function buildEventsPath(string $calendarId): string
63 | {
64 | return sprintf('/%s/calendars/%s/events', Cronofy::API_VERSION, $calendarId);
65 | }
66 |
67 | private function buildAvailablePeriodsPath(): string
68 | {
69 | return sprintf('/%s/available_periods', Cronofy::API_VERSION);
70 | }
71 |
72 | private function addPostRequest(string $relativeUrl, array $data): self
73 | {
74 | return $this->addRequest('POST', $relativeUrl, $data);
75 | }
76 |
77 | private function addDeleteRequest(string $relativeUrl, array $data): self
78 | {
79 | return $this->addRequest('DELETE', $relativeUrl, $data);
80 | }
81 |
82 | private function addRequest(string $method, string $relativeUrl, array $data): self
83 | {
84 | $this->requests[] = new BatchRequest($method, $relativeUrl, $data);
85 |
86 | return $this;
87 | }
88 |
89 | public function requests(): array
90 | {
91 | return $this->requests;
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/src/Batch/BatchRequest.php:
--------------------------------------------------------------------------------
1 | method = $method;
14 | $this->relativeUrl = $relativeUrl;
15 | $this->data = $data;
16 | }
17 |
18 | public function method(): string
19 | {
20 | return $this->method;
21 | }
22 |
23 | public function relativeUrl(): string
24 | {
25 | return $this->relativeUrl;
26 | }
27 |
28 | public function data(): array
29 | {
30 | return $this->data;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/Batch/BatchResponse.php:
--------------------------------------------------------------------------------
1 | status = $status;
15 | $this->headers = $headers;
16 | $this->data = $data;
17 | $this->request = $request;
18 | }
19 |
20 | public function status(): int
21 | {
22 | return $this->status;
23 | }
24 |
25 | public function hasSuccessStatus(): bool
26 | {
27 | $status = $this->status();
28 |
29 | return $status >= 200 && $status < 300;
30 | }
31 |
32 | public function hasErrorStatus(): bool
33 | {
34 | return !$this->hasSuccessStatus();
35 | }
36 |
37 | public function headers(): ?array
38 | {
39 | return $this->headers;
40 | }
41 |
42 | public function data(): ?array
43 | {
44 | return $this->data;
45 | }
46 |
47 | public function request(): BatchRequest
48 | {
49 | return $this->request;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/Batch/BatchResult.php:
--------------------------------------------------------------------------------
1 | responses = $responses;
13 | }
14 |
15 | public function responses(): array
16 | {
17 | return $this->responses;
18 | }
19 |
20 | public function errors(): array
21 | {
22 | if ($this->errors === null) {
23 | $this->errors = [];
24 |
25 | foreach ($this->responses as $response) {
26 | if ($response->hasErrorStatus()) {
27 | $this->errors[] = $response;
28 | }
29 | }
30 | }
31 |
32 | return $this->errors;
33 | }
34 |
35 | public function hasErrors(): bool
36 | {
37 | return count($this->errors()) > 0;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/Exception/CronofyException.php:
--------------------------------------------------------------------------------
1 | errorDetails = $errorDetails;
14 |
15 | parent::__construct($message, $code, null);
16 | }
17 |
18 | public function error_details()
19 | {
20 | return $this->errorDetails;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/Exception/PartialBatchFailureException.php:
--------------------------------------------------------------------------------
1 | result = $result;
15 |
16 | parent::__construct($message);
17 | }
18 |
19 | public function result(): BatchResult
20 | {
21 | return $this->result;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/Http/CurlRequest.php:
--------------------------------------------------------------------------------
1 | useragent = $useragent;
14 | }
15 |
16 | public function httpGet($url, array $auth_headers)
17 | {
18 | $curl = curl_init();
19 | curl_setopt($curl, CURLOPT_URL, $url);
20 | curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
21 | curl_setopt($curl, CURLOPT_HTTPHEADER, $auth_headers);
22 | curl_setopt($curl, CURLOPT_USERAGENT, $this->useragent);
23 | // empty string means send all supported encoding types
24 | curl_setopt($curl, CURLOPT_ENCODING, '');
25 | $result = curl_exec($curl);
26 | if (curl_errno($curl) > 0) {
27 | throw new CronofyException(curl_error($curl), 2);
28 | }
29 | $status_code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
30 | curl_close($curl);
31 |
32 | return [$result, $status_code];
33 | }
34 |
35 | public function getPage($url, array $auth_headers, $url_params = "")
36 | {
37 | return $this->httpGet($url.$url_params, $auth_headers);
38 | }
39 |
40 | public function httpPost($url, array $params, array $auth_headers)
41 | {
42 | $curl = curl_init();
43 | curl_setopt($curl, CURLOPT_URL, $url);
44 | curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
45 | curl_setopt($curl, CURLOPT_HTTPHEADER, $auth_headers);
46 | curl_setopt($curl, CURLOPT_USERAGENT, $this->useragent);
47 | curl_setopt($curl, CURLOPT_POST, 1);
48 | curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($params));
49 | curl_setopt($curl, CURLOPT_VERBOSE, false);
50 | // empty string means send all supported encoding types
51 | curl_setopt($curl, CURLOPT_ENCODING, '');
52 | $result = curl_exec($curl);
53 | if (curl_errno($curl) > 0) {
54 | throw new CronofyException(curl_error($curl), 3);
55 | }
56 | $status_code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
57 | curl_close($curl);
58 |
59 | return [$result, $status_code];
60 | }
61 |
62 | public function httpDelete($url, array $params, array $auth_headers)
63 | {
64 | $curl = curl_init();
65 | curl_setopt($curl, CURLOPT_URL, $url);
66 | curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
67 | curl_setopt($curl, CURLOPT_HTTPHEADER, $auth_headers);
68 | curl_setopt($curl, CURLOPT_USERAGENT, $this->useragent);
69 | curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'DELETE');
70 | curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($params));
71 | // empty string means send all supported encoding types
72 | curl_setopt($curl, CURLOPT_ENCODING, '');
73 | $result = curl_exec($curl);
74 | if (curl_errno($curl) > 0) {
75 | throw new CronofyException(curl_error($curl), 4);
76 | }
77 | $status_code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
78 | curl_close($curl);
79 |
80 | return [$result, $status_code];
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/src/Http/HttpRequest.php:
--------------------------------------------------------------------------------
1 | cronofy = $cronofy;
17 | $this->itemsKey = $itemsKey;
18 | $this->authHeaders = $authHeaders;
19 | $this->url = $url;
20 | $this->urlParams = $urlParams;
21 | $this->firstPage = $this->getPage($url, $urlParams);
22 | }
23 |
24 | public function each()
25 | {
26 | $page = $this->firstPage;
27 |
28 | for ($i = 0; $i < count($page[$this->itemsKey]); $i++) {
29 | yield $page[$this->itemsKey][$i];
30 | }
31 |
32 | while (isset($page["pages"]["next_page"])) {
33 | $page = $this->getPage($page["pages"]["next_page"]);
34 |
35 | for ($i = 0; $i < count($page[$this->itemsKey]); $i++) {
36 | yield $page[$this->itemsKey][$i];
37 | }
38 | }
39 | }
40 |
41 | public function getIterator()
42 | {
43 | return $this->each();
44 | }
45 |
46 | private function getPage($url, $urlParams = '')
47 | {
48 | list ($result, $status_code) = $this->cronofy->httpClient->getPage($url, $this->authHeaders, $urlParams);
49 |
50 | return $this->cronofy->handleResponse($result, $status_code);
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/tests/AccessibleCalendarsTest.php:
--------------------------------------------------------------------------------
1 | createMock(HttpRequest::class);
35 | $http->expects($this->once())
36 | ->method('httpGet')
37 | ->with(
38 | 'https://api.cronofy.com/v1/accessible_calendars?'
39 | . http_build_query(['profile_id' => $profileId = 'profile-id']),
40 | [
41 | 'Authorization: Bearer accessToken',
42 | 'Host: api.cronofy.com',
43 | ]
44 | )
45 | ->willReturn([$accessible_calendars_response, 200]);
46 |
47 | $cronofy = new Cronofy([
48 | "client_id" => "clientId",
49 | "client_secret" => "clientSecret",
50 | "access_token" => "accessToken",
51 | "refresh_token" => "refreshToken",
52 | "http_client" => $http,
53 | ]);
54 |
55 | $accesibleCalendars = $cronofy->listAccessibleCalendars($profileId);
56 |
57 | $this->assertEquals(
58 | json_decode($accessible_calendars_response, true),
59 | $accesibleCalendars
60 | );
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/tests/ApplicationCalendarTest.php:
--------------------------------------------------------------------------------
1 | "clientId",
16 | "client_secret" => "clientSecret",
17 | "application_calendar_id" => $application_calendar_id,
18 | ];
19 |
20 | $application_calendar_response = '{
21 | "token_type":"bearer",
22 | "access_token":"fffff",
23 | "expires_in":3600,
24 | "refresh_token":"2222",
25 | "scope":"read_write",
26 | "application_calendar_id":"my-unique-string",
27 | "sub":"apc_567236000909002",
28 | "linking_profile":{
29 | "provider_name":"cronofy",
30 | "profile_id":"pro_n23kjnwrw2",
31 | "profile_name":"n23kjnwrw2"
32 | }
33 | }';
34 |
35 | $http = $this->createMock(HttpRequest::class);
36 | $http->expects($this->once())
37 | ->method('httpPost')
38 | ->with(
39 | $this->equalTo('https://api.cronofy.com/v1/application_calendars'),
40 | $this->equalTo($request_params),
41 | $this->equalTo([
42 | 'Host: api.cronofy.com',
43 | 'Content-Type: application/json; charset=utf-8'
44 | ])
45 | )
46 | ->will($this->returnValue([$application_calendar_response, 200]));
47 |
48 | $cronofy = new Cronofy([
49 | "client_id" => "clientId",
50 | "client_secret" => "clientSecret",
51 | "http_client" => $http,
52 | ]);
53 |
54 |
55 | $actual = $cronofy->applicationCalendar($application_calendar_id);
56 |
57 | $this->assertEquals($actual['sub'], "apc_567236000909002");
58 | $this->assertEquals($cronofy->accessToken, "fffff");
59 | $this->assertEquals($cronofy->refreshToken, "2222");
60 | $this->assertEquals($cronofy->expiresIn, 3600);
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/tests/BatchTest.php:
--------------------------------------------------------------------------------
1 | httpClient = $this->createMock(HttpRequest::class);
28 |
29 | $this->cronofy = new Cronofy([
30 | 'client_id' => 'clientId',
31 | 'client_secret' => 'clientSecret',
32 | 'access_token' => 'accessToken',
33 | 'refresh_token' => 'refreshToken',
34 | 'http_client' => $this->httpClient,
35 | ]);
36 | }
37 |
38 | public function testUpsertEvent()
39 | {
40 | $calendarId = 'calendar_id';
41 | $data = $this->getUpsertEventData();
42 |
43 | $expectedRequestMethod = 'POST';
44 | $expectedRequestRelativeUrl = sprintf('/v1/calendars/%s/events', $calendarId);
45 | $expectedRequestData = $data;
46 |
47 | $expectedRequests = [
48 | [
49 | 'method' => $expectedRequestMethod,
50 | 'relative_url' => $expectedRequestRelativeUrl,
51 | 'data' => $expectedRequestData,
52 | ],
53 | ];
54 |
55 | $expectedResponseStatus = 202;
56 |
57 | $mockResponses = [
58 | [
59 | 'status' => $expectedResponseStatus,
60 | ],
61 | ];
62 |
63 | $this->makeBatchRequestExpectation($expectedRequests, $mockResponses);
64 |
65 | $batch = Batch::create()->upsertEvent($calendarId, $data);
66 | $result = $this->cronofy->executeBatch($batch);
67 |
68 | $this->assertInstanceOf(BatchResult::class, $result);
69 |
70 | $responses = $result->responses();
71 |
72 | $this->assertCount(1, $responses);
73 |
74 | $response = $responses[0];
75 |
76 | $this->assertEquals($expectedResponseStatus, $response->status());
77 | $this->assertNull($response->headers());
78 | $this->assertNull($response->data());
79 |
80 | $request = $response->request();
81 |
82 | $this->assertInstanceOf(BatchRequest::class, $request);
83 | $this->assertEquals($expectedRequestMethod, $request->method());
84 | $this->assertEquals($expectedRequestRelativeUrl, $request->relativeUrl());
85 | $this->assertEquals($expectedRequestData, $request->data());
86 | }
87 |
88 | public function testUpdateExternalEvent()
89 | {
90 | $calendarId = 'calendar_id';
91 | $data = $this->getUpdateExternalEventData();
92 |
93 | $expectedRequestMethod = 'POST';
94 | $expectedRequestRelativeUrl = sprintf('/v1/calendars/%s/events', $calendarId);
95 | $expectedRequestData = $data;
96 |
97 | $expectedRequests = [
98 | [
99 | 'method' => $expectedRequestMethod,
100 | 'relative_url' => $expectedRequestRelativeUrl,
101 | 'data' => $expectedRequestData,
102 | ],
103 | ];
104 |
105 | $expectedResponseStatus = 202;
106 |
107 | $mockResponses = [
108 | [
109 | 'status' => $expectedResponseStatus,
110 | ],
111 | ];
112 |
113 | $this->makeBatchRequestExpectation($expectedRequests, $mockResponses);
114 |
115 | $batch = Batch::create()->updateExternalEvent($calendarId, $data);
116 | $result = $this->cronofy->executeBatch($batch);
117 |
118 | $this->assertInstanceOf(BatchResult::class, $result);
119 |
120 | $responses = $result->responses();
121 |
122 | $this->assertCount(1, $responses);
123 |
124 | $response = $responses[0];
125 |
126 | $this->assertEquals($expectedResponseStatus, $response->status());
127 | $this->assertNull($response->headers());
128 | $this->assertNull($response->data());
129 |
130 | $request = $response->request();
131 |
132 | $this->assertInstanceOf(BatchRequest::class, $request);
133 | $this->assertEquals($expectedRequestMethod, $request->method());
134 | $this->assertEquals($expectedRequestRelativeUrl, $request->relativeUrl());
135 | $this->assertEquals($expectedRequestData, $request->data());
136 | }
137 |
138 | public function testDeleteEvent()
139 | {
140 | $calendarId = 'calendar_id';
141 | $eventId = 'event_id';
142 |
143 | $expectedRequestMethod = 'DELETE';
144 | $expectedRequestRelativeUrl = sprintf('/v1/calendars/%s/events', $calendarId);
145 | $expectedRequestData = [
146 | 'event_id' => $eventId,
147 | ];
148 |
149 | $expectedRequests = [
150 | [
151 | 'method' => $expectedRequestMethod,
152 | 'relative_url' => $expectedRequestRelativeUrl,
153 | 'data' => $expectedRequestData,
154 | ],
155 | ];
156 |
157 | $expectedResponseStatus = 204;
158 |
159 | $mockResponses = [
160 | [
161 | 'status' => $expectedResponseStatus,
162 | ],
163 | ];
164 |
165 | $this->makeBatchRequestExpectation($expectedRequests, $mockResponses);
166 |
167 | $batch = Batch::create()->deleteEvent($calendarId, $eventId);
168 | $result = $this->cronofy->executeBatch($batch);
169 |
170 | $this->assertInstanceOf(BatchResult::class, $result);
171 |
172 | $responses = $result->responses();
173 |
174 | $this->assertCount(1, $responses);
175 |
176 | $response = $responses[0];
177 |
178 | $this->assertEquals($expectedResponseStatus, $response->status());
179 | $this->assertNull($response->headers());
180 | $this->assertNull($response->data());
181 |
182 | $request = $response->request();
183 |
184 | $this->assertInstanceOf(BatchRequest::class, $request);
185 | $this->assertEquals($expectedRequestMethod, $request->method());
186 | $this->assertEquals($expectedRequestRelativeUrl, $request->relativeUrl());
187 | $this->assertEquals($expectedRequestData, $request->data());
188 | }
189 |
190 | public function testDeleteExternalEvent()
191 | {
192 | $calendarId = 'calendar_id';
193 | $externalEventId = 'external_event_id';
194 |
195 | $expectedRequestMethod = 'DELETE';
196 | $expectedRequestRelativeUrl = sprintf('/v1/calendars/%s/events', $calendarId);
197 | $expectedRequestData = [
198 | 'event_uid' => $externalEventId,
199 | ];
200 |
201 | $expectedRequests = [
202 | [
203 | 'method' => $expectedRequestMethod,
204 | 'relative_url' => $expectedRequestRelativeUrl,
205 | 'data' => $expectedRequestData,
206 | ],
207 | ];
208 |
209 | $expectedResponseStatus = 204;
210 | $expectedResponseHeaders = [
211 | 'Header' => 'Value',
212 | ];
213 |
214 | $mockResponses = [
215 | [
216 | 'status' => $expectedResponseStatus,
217 | 'headers' => $expectedResponseHeaders,
218 | ],
219 | ];
220 |
221 | $this->makeBatchRequestExpectation($expectedRequests, $mockResponses);
222 |
223 | $batch = Batch::create()->deleteExternalEvent($calendarId, $externalEventId);
224 | $result = $this->cronofy->executeBatch($batch);
225 |
226 | $this->assertInstanceOf(BatchResult::class, $result);
227 |
228 | $responses = $result->responses();
229 |
230 | $this->assertCount(1, $responses);
231 |
232 | $response = $responses[0];
233 |
234 | $this->assertEquals($expectedResponseStatus, $response->status());
235 | $this->assertEquals($expectedResponseHeaders, $response->headers());
236 | $this->assertNull($response->data());
237 |
238 | $request = $response->request();
239 |
240 | $this->assertInstanceOf(BatchRequest::class, $request);
241 | $this->assertEquals($expectedRequestMethod, $request->method());
242 | $this->assertEquals($expectedRequestRelativeUrl, $request->relativeUrl());
243 | $this->assertEquals($expectedRequestData, $request->data());
244 | }
245 |
246 | public function testUpsertAvailablePeriod()
247 | {
248 | $data = $this->getUpsertAvailablePeriodData();
249 |
250 | $expectedRequestMethod = 'POST';
251 | $expectedRequestRelativeUrl = '/v1/available_periods';
252 | $expectedRequestData = $data;
253 |
254 | $expectedRequests = [
255 | [
256 | 'method' => $expectedRequestMethod,
257 | 'relative_url' => $expectedRequestRelativeUrl,
258 | 'data' => $expectedRequestData,
259 | ],
260 | ];
261 |
262 | $expectedResponseStatus = 202;
263 |
264 | $mockResponses = [
265 | [
266 | 'status' => $expectedResponseStatus,
267 | ],
268 | ];
269 |
270 | $this->makeBatchRequestExpectation($expectedRequests, $mockResponses);
271 |
272 | $batch = Batch::create()->upsertAvailablePeriod($data);
273 | $result = $this->cronofy->executeBatch($batch);
274 |
275 | $this->assertInstanceOf(BatchResult::class, $result);
276 |
277 | $responses = $result->responses();
278 |
279 | $this->assertCount(1, $responses);
280 |
281 | $response = $responses[0];
282 |
283 | $this->assertEquals($expectedResponseStatus, $response->status());
284 | $this->assertNull($response->headers());
285 | $this->assertNull($response->data());
286 |
287 | $request = $response->request();
288 |
289 | $this->assertInstanceOf(BatchRequest::class, $request);
290 | $this->assertEquals($expectedRequestMethod, $request->method());
291 | $this->assertEquals($expectedRequestRelativeUrl, $request->relativeUrl());
292 | $this->assertEquals($expectedRequestData, $request->data());
293 | }
294 |
295 | public function testDeleteAvailablePeriod()
296 | {
297 | $availablePeriodId = 'available_period_id';
298 |
299 | $expectedRequestMethod = 'DELETE';
300 | $expectedRequestRelativeUrl = '/v1/available_periods';
301 | $expectedRequestData = [
302 | 'available_period_id' => $availablePeriodId,
303 | ];
304 |
305 | $expectedRequests = [
306 | [
307 | 'method' => $expectedRequestMethod,
308 | 'relative_url' => $expectedRequestRelativeUrl,
309 | 'data' => $expectedRequestData,
310 | ],
311 | ];
312 |
313 | $expectedResponseStatus = 204;
314 |
315 | $mockResponses = [
316 | [
317 | 'status' => $expectedResponseStatus,
318 | ],
319 | ];
320 |
321 | $this->makeBatchRequestExpectation($expectedRequests, $mockResponses);
322 |
323 | $batch = Batch::create()->deleteAvailablePeriod($availablePeriodId);
324 | $result = $this->cronofy->executeBatch($batch);
325 |
326 | $this->assertInstanceOf(BatchResult::class, $result);
327 |
328 | $responses = $result->responses();
329 |
330 | $this->assertCount(1, $responses);
331 |
332 | $response = $responses[0];
333 |
334 | $this->assertEquals($expectedResponseStatus, $response->status());
335 | $this->assertNull($response->headers());
336 | $this->assertNull($response->data());
337 |
338 | $request = $response->request();
339 |
340 | $this->assertInstanceOf(BatchRequest::class, $request);
341 | $this->assertEquals($expectedRequestMethod, $request->method());
342 | $this->assertEquals($expectedRequestRelativeUrl, $request->relativeUrl());
343 | $this->assertEquals($expectedRequestData, $request->data());
344 | }
345 |
346 | public function testPartialBatchFailure()
347 | {
348 | $data = $this->getUpsertAvailablePeriodData();
349 | unset($data['start']);
350 |
351 | $expectedRequestMethod = 'POST';
352 | $expectedRequestRelativeUrl = '/v1/available_periods';
353 | $expectedRequestData = $data;
354 |
355 | $expectedRequests = [
356 | [
357 | 'method' => $expectedRequestMethod,
358 | 'relative_url' => $expectedRequestRelativeUrl,
359 | 'data' => $expectedRequestData,
360 | ],
361 | ];
362 |
363 | $expectedResponseStatus = 422;
364 | $expectedResponseData = [
365 | 'errors' => [
366 | 'start' => [
367 | [
368 | 'key' => 'errors.required',
369 | 'description' => 'start must be specified',
370 | ],
371 | ],
372 | ],
373 | ];
374 |
375 | $mockResponses = [
376 | [
377 | 'status' => $expectedResponseStatus,
378 | 'data' => $expectedResponseData,
379 | ],
380 | ];
381 |
382 | $this->makeBatchRequestExpectation($expectedRequests, $mockResponses);
383 |
384 | $batch = Batch::create()->upsertAvailablePeriod($data);
385 |
386 | try {
387 | $this->cronofy->executeBatch($batch);
388 | } catch (PartialBatchFailureException $exception) {
389 | $result = $exception->result();
390 |
391 | $this->assertInstanceOf(BatchResult::class, $result);
392 | $this->assertTrue($result->hasErrors());
393 |
394 | $errors = $result->errors();
395 |
396 | $this->assertCount(1, $errors);
397 |
398 | $error = $errors[0];
399 |
400 | $this->assertInstanceOf(BatchResponse::class, $error);
401 | $this->assertEquals($expectedResponseStatus, $error->status());
402 | $this->assertNull($error->headers());
403 | $this->assertEquals($expectedResponseData, $error->data());
404 |
405 | $request = $error->request();
406 |
407 | $this->assertInstanceOf(BatchRequest::class, $request);
408 | $this->assertEquals($expectedRequestMethod, $request->method());
409 | $this->assertEquals($expectedRequestRelativeUrl, $request->relativeUrl());
410 | $this->assertEquals($expectedRequestData, $request->data());
411 |
412 | return;
413 | }
414 |
415 | $this->fail(sprintf('Expected exception of type "%s" to be thrown.', PartialBatchFailureException::class));
416 | }
417 |
418 | private function makeBatchRequestExpectation(array $requests, array $responses): void
419 | {
420 | $this->httpClient
421 | ->expects($this->once())
422 | ->method('httpPost')
423 | ->with(
424 | $this->equalTo('https://api.cronofy.com/v1/batch'),
425 | $this->equalTo([
426 | 'batch' => $requests,
427 | ])
428 | )
429 | ->will(
430 | $this->returnValue([
431 | json_encode([
432 | 'batch' => $responses,
433 | ]),
434 | 207,
435 | ])
436 | );
437 | }
438 |
439 | private function getUpsertEventData(): array
440 | {
441 | return array_merge(
442 | ['event_id' => 'event_id'],
443 | $this->getBaseEventData()
444 | );
445 | }
446 |
447 | private function getUpdateExternalEventData(): array
448 | {
449 | return array_merge(
450 | ['event_uid' => 'external_event_id'],
451 | $this->getBaseEventData()
452 | );
453 | }
454 |
455 | private function getBaseEventData(): array
456 | {
457 | return [
458 | 'summary' => 'Upsert Event Test',
459 | 'description' => 'description example',
460 | 'start' => '2017-01-01T12:00:00Z',
461 | 'end' => '2017-01-01T15:00:00Z',
462 | 'tzid' => 'Europe/London',
463 | 'location' => [
464 | 'description' => 'board room',
465 | 'latitude' => '12.2344',
466 | 'longitude' => '45.2444',
467 | ],
468 | 'reminders' => [
469 | ['minutes' => 30],
470 | ['minutes' => 1440],
471 | ],
472 | 'attendees' => [
473 | 'invite' => [
474 | ['email' => 'new_invitee@test.com', 'display_name' => 'New Invitee'],
475 | ],
476 | 'reject' => [
477 | ['email' => 'old_invitee@test.com', 'display_name' => 'Old Invitee'],
478 | ],
479 | ],
480 | 'event_private' => true,
481 | 'reminders_create_only' => true,
482 | 'transparency' => 'opaque',
483 | 'color' => '#c6040f',
484 | 'conferencing' => [
485 | 'profile_id' => 'default',
486 | ],
487 | ];
488 | }
489 |
490 | private function getUpsertAvailablePeriodData(): array
491 | {
492 | return [
493 | 'available_period_id' => 'available_period_id',
494 | 'start' => '2021-04-14T15:30:00Z',
495 | 'end' => '2021-04-14T17:00:00Z',
496 | ];
497 | }
498 | }
499 |
--------------------------------------------------------------------------------
/tests/CronofyTest.php:
--------------------------------------------------------------------------------
1 | "clientId"]);
16 | $params = [
17 | 'redirect_uri' => $redirect_uri,
18 | 'scope' => ['read_account','list_calendars']
19 | ];
20 | $auth = $cronofy->getAuthorizationURL($params);
21 |
22 | $this->assertEquals("https://app.cronofy.com/oauth/authorize?response_type=code&client_id=clientId"
23 | . "&redirect_uri=http%3A%2F%2Fyoursite.dev%2Foauth2%2Fcallback&scope=read_account%20list_calendars", $auth);
24 | }
25 |
26 | public function testDelegatedScopeInAuthorizationUrl()
27 | {
28 | $redirect_uri = "http://yoursite.dev/oauth2/callback";
29 |
30 | $cronofy = new Cronofy(["client_id" => "clientId"]);
31 | $params = [
32 | 'redirect_uri' => $redirect_uri,
33 | 'scope' => ['read_account','list_calendars'],
34 | 'delegated_scope' => ['create_calendar', 'read_free_busy']
35 | ];
36 | $auth = $cronofy->getAuthorizationURL($params);
37 |
38 | $this->assertEquals("https://app.cronofy.com/oauth/authorize?response_type=code&client_id=clientId"
39 | . "&redirect_uri=http%3A%2F%2Fyoursite.dev%2Foauth2%2Fcallback"
40 | . "&scope=read_account%20list_calendars&delegated_scope=create_calendar%20read_free_busy", $auth);
41 | }
42 |
43 | public function testProviderNameInAuthorizationUrl()
44 | {
45 | $redirect_uri = "http://yoursite.dev/oauth2/callback";
46 |
47 | $cronofy = new Cronofy(["client_id" => "clientId"]);
48 | $params = [
49 | 'redirect_uri' => $redirect_uri,
50 | 'scope' => ['read_account','list_calendars'],
51 | 'provider_name' => 'office365'
52 | ];
53 | $auth = $cronofy->getAuthorizationURL($params);
54 |
55 | $this->assertEquals("https://app.cronofy.com/oauth/authorize?response_type=code&client_id=clientId"
56 | . "&redirect_uri=http%3A%2F%2Fyoursite.dev%2Foauth2%2Fcallback&scope=read_account%20list_calendars&provider_name=office365", $auth);
57 | }
58 |
59 | public function testErrorHandling()
60 | {
61 | $args = [
62 | "profile_id" => "pro_123",
63 | "name" => "My Calendar",
64 | ];
65 |
66 | $error_response = '{"errors":{"event_id":[{"key":"errors.required","description":"required"}]}}';
67 |
68 | $http = $this->createMock(HttpRequest::class);
69 | $http->expects($this->once())
70 | ->method('httpPost')
71 | ->with(
72 | $this->equalTo('https://api.cronofy.com/v1/calendars'),
73 | $this->equalTo($args),
74 | $this->equalTo([
75 | 'Authorization: Bearer accessToken',
76 | 'Host: api.cronofy.com',
77 | 'Content-Type: application/json; charset=utf-8',
78 | ])
79 | )
80 | ->will($this->returnValue([$error_response, 422]));
81 |
82 | $cronofy = new Cronofy([
83 | "client_id" => "clientId",
84 | "client_secret" => "clientSecret",
85 | "access_token" => "accessToken",
86 | "refresh_token" => "refreshToken",
87 | "http_client" => $http,
88 | ]);
89 |
90 | $raised_error = false;
91 |
92 | try {
93 | $cronofy->createCalendar($args);
94 | } catch (CronofyException $exception) {
95 | $raised_error = true;
96 | $this->assertEquals(json_decode($error_response, true), $exception->error_details());
97 | $this->assertEquals(422, $exception->getCode());
98 | }
99 |
100 | $this->assertTrue($raised_error);
101 | }
102 |
103 | public function testRequestToken()
104 | {
105 | $request_params = [
106 | "client_id" => "clientId",
107 | "client_secret" => "clientSecret",
108 | "grant_type" => "authorization_code",
109 | "code" => "MY_SECRET_CODE",
110 | "redirect_uri" => "http://example.com",
111 | ];
112 |
113 | $token_response = '{
114 | "token_type":"bearer",
115 | "access_token":"fffff",
116 | "expires_in":3600,
117 | "refresh_token":"2222",
118 | "scope":"read_write",
119 | "application_calendar_id":"my-unique-string",
120 | "sub":"apc_567236000909002",
121 | "linking_profile":{
122 | "provider_name":"cronofy",
123 | "profile_id":"pro_n23kjnwrw2",
124 | "profile_name":"n23kjnwrw2"
125 | }
126 | }';
127 |
128 | $http = $this->createMock(HttpRequest::class);
129 | $http->expects($this->once())
130 | ->method('httpPost')
131 | ->with(
132 | $this->equalTo('https://api.cronofy.com/oauth/token'),
133 | $this->equalTo($request_params),
134 | $this->equalTo([
135 | 'Host: api.cronofy.com',
136 | 'Content-Type: application/json; charset=utf-8'
137 | ])
138 | )
139 | ->will($this->returnValue([$token_response, 200]));
140 |
141 | $cronofy = new Cronofy([
142 | "client_id" => "clientId",
143 | "client_secret" => "clientSecret",
144 | "http_client" => $http,
145 | ]);
146 |
147 | $args = [
148 | "code" => "MY_SECRET_CODE",
149 | "redirect_uri" => "http://example.com",
150 | ];
151 |
152 | $actual = $cronofy->requestToken($args);
153 | $this->assertTrue($actual);
154 | $this->assertEquals($cronofy->accessToken, "fffff");
155 | $this->assertEquals($cronofy->refreshToken, "2222");
156 | $this->assertEquals($cronofy->expiresIn, 3600);
157 | $this->assertEquals($cronofy->tokens, json_decode($token_response, true));
158 | }
159 |
160 | public function testGetAccount()
161 | {
162 | $http = $this->createMock(HttpRequest::class);
163 | $http->expects($this->once())
164 | ->method('httpGet')
165 | ->with(
166 | $this->equalTo('https://api.cronofy.com/v1/account'),
167 | $this->equalTo([
168 | 'Authorization: Bearer accessToken',
169 | 'Host: api.cronofy.com'
170 | ])
171 | )
172 | ->will($this->returnValue(["{'foo': 'bar'}", 200]));
173 |
174 | $cronofy = new Cronofy([
175 | "client_id" => "clientId",
176 | "client_secret" => "clientSecret",
177 | "access_token" => "accessToken",
178 | "refresh_token" => "refreshToken",
179 | "http_client" => $http,
180 | ]);
181 |
182 | $actual = $cronofy->getAccount();
183 | $this->assertNotNull($actual);
184 | }
185 |
186 | public function testRevokeAuthorizationWithString()
187 | {
188 | $http = $this->createMock(HttpRequest::class);
189 | $http->expects($this->once())
190 | ->method('httpPost')
191 | ->with(
192 | $this->equalTo('https://api.cronofy.com/oauth/token/revoke'),
193 | $this->equalTo([
194 | 'client_id' => 'clientId',
195 | 'client_secret' => 'clientSecret',
196 | 'token' => 'sometoken'
197 | ]),
198 | $this->equalTo([
199 | 'Host: api.cronofy.com',
200 | 'Content-Type: application/json; charset=utf-8'
201 | ])
202 | )
203 | ->will($this->returnValue(["{'foo': 'bar'}", 200]));
204 |
205 | $cronofy = new Cronofy([
206 | "client_id" => "clientId",
207 | "client_secret" => "clientSecret",
208 | "http_client" => $http,
209 | ]);
210 |
211 | $actual = $cronofy->revokeAuthorization('sometoken');
212 | $this->assertNotNull($actual);
213 | }
214 |
215 |
216 |
217 | public function testRevokeAuthorizationWithToken()
218 | {
219 | $http = $this->createMock(HttpRequest::class);
220 | $http->expects($this->once())
221 | ->method('httpPost')
222 | ->with(
223 | $this->equalTo('https://api.cronofy.com/oauth/token/revoke'),
224 | $this->equalTo([
225 | 'client_id' => 'clientId',
226 | 'client_secret' => 'clientSecret',
227 | 'token' => 'sometoken'
228 | ]),
229 | $this->equalTo([
230 | 'Host: api.cronofy.com',
231 | 'Content-Type: application/json; charset=utf-8'
232 | ])
233 | )
234 | ->will($this->returnValue(["{'foo': 'bar'}", 200]));
235 |
236 | $cronofy = new Cronofy([
237 | "client_id" => "clientId",
238 | "client_secret" => "clientSecret",
239 | "http_client" => $http,
240 | ]);
241 |
242 | $actual = $cronofy->revokeAuthorization(['token' => 'sometoken']);
243 | $this->assertNotNull($actual);
244 | }
245 |
246 |
247 |
248 | public function testRevokeAuthorizationWithSub()
249 | {
250 | $http = $this->createMock(HttpRequest::class);
251 | $http->expects($this->once())
252 | ->method('httpPost')
253 | ->with(
254 | $this->equalTo('https://api.cronofy.com/oauth/token/revoke'),
255 | $this->equalTo([
256 | 'client_id' => 'clientId',
257 | 'client_secret' => 'clientSecret',
258 | 'sub' => 'somesub'
259 | ]),
260 | $this->equalTo([
261 | 'Host: api.cronofy.com',
262 | 'Content-Type: application/json; charset=utf-8'
263 | ])
264 | )
265 | ->will($this->returnValue(["{'foo': 'bar'}", 200]));
266 |
267 | $cronofy = new Cronofy([
268 | "client_id" => "clientId",
269 | "client_secret" => "clientSecret",
270 | "http_client" => $http,
271 | ]);
272 |
273 | $actual = $cronofy->revokeAuthorization(['sub' => 'somesub']);
274 | $this->assertNotNull($actual);
275 | }
276 |
277 | public function testDeleteEvent()
278 | {
279 | $params = ["event_id" => "evt_456"];
280 |
281 | $http = $this->createMock(HttpRequest::class);
282 | $http->expects($this->once())
283 | ->method('httpDelete')
284 | ->with(
285 | $this->equalTo('https://api.cronofy.com/v1/calendars/cal_123/events'),
286 | $this->equalTo($params),
287 | $this->equalTo([
288 | 'Authorization: Bearer accessToken',
289 | 'Host: api.cronofy.com',
290 | 'Content-Type: application/json; charset=utf-8',
291 | ])
292 | )
293 | ->will($this->returnValue(["{'foo': 'bar'}", 200]));
294 |
295 | $cronofy = new Cronofy([
296 | "client_id" => "clientId",
297 | "client_secret" => "clientSecret",
298 | "access_token" => "accessToken",
299 | "refresh_token" => "refreshToken",
300 | "http_client" => $http,
301 | ]);
302 |
303 | $actual = $cronofy->deleteEvent([
304 | "calendar_id" => "cal_123",
305 | "event_id" => "evt_456",
306 | ]);
307 | $this->assertNotNull($actual);
308 | }
309 |
310 | public function testBulkDeleteEventsFromSpecificCalendar()
311 | {
312 | $params = ["calendar_ids" => ["cal_123"]];
313 |
314 | $http = $this->createMock(HttpRequest::class);
315 | $http->expects($this->once())
316 | ->method('httpDelete')
317 | ->with(
318 | $this->equalTo('https://api.cronofy.com/v1/events'),
319 | $this->equalTo($params),
320 | $this->equalTo([
321 | 'Authorization: Bearer accessToken',
322 | 'Host: api.cronofy.com',
323 | 'Content-Type: application/json; charset=utf-8',
324 | ])
325 | )
326 | ->will($this->returnValue(["{'foo': 'bar'}", 202]));
327 |
328 | $cronofy = new Cronofy([
329 | "client_id" => "clientId",
330 | "client_secret" => "clientSecret",
331 | "access_token" => "accessToken",
332 | "refresh_token" => "refreshToken",
333 | "http_client" => $http,
334 | ]);
335 |
336 | $actual = $cronofy->bulkDeleteEvents([
337 | "calendar_ids" => ["cal_123"]
338 | ]);
339 | $this->assertNotNull($actual);
340 | }
341 |
342 | public function testBulkDeleteEventsFromAllCalendars()
343 | {
344 | $params = ["delete_all" => true];
345 |
346 | $http = $this->createMock(HttpRequest::class);
347 | $http->expects($this->once())
348 | ->method('httpDelete')
349 | ->with(
350 | $this->equalTo('https://api.cronofy.com/v1/events'),
351 | $this->equalTo($params),
352 | $this->equalTo([
353 | 'Authorization: Bearer accessToken',
354 | 'Host: api.cronofy.com',
355 | 'Content-Type: application/json; charset=utf-8',
356 | ])
357 | )
358 | ->will($this->returnValue(["{'foo': 'bar'}", 202]));
359 |
360 | $cronofy = new Cronofy([
361 | "client_id" => "clientId",
362 | "client_secret" => "clientSecret",
363 | "access_token" => "accessToken",
364 | "refresh_token" => "refreshToken",
365 | "http_client" => $http,
366 | ]);
367 |
368 | $actual = $cronofy->bulkDeleteEvents([
369 | "delete_all" => true
370 | ]);
371 | $this->assertNotNull($actual);
372 | }
373 |
374 | public function testDeleteExternalEvent()
375 | {
376 | $params = ["event_uid" => "evt_456"];
377 |
378 | $http = $this->createMock(HttpRequest::class);
379 | $http->expects($this->once())
380 | ->method('httpDelete')
381 | ->with(
382 | $this->equalTo('https://api.cronofy.com/v1/calendars/cal_123/events'),
383 | $this->equalTo($params),
384 | $this->equalTo([
385 | 'Authorization: Bearer accessToken',
386 | 'Host: api.cronofy.com',
387 | 'Content-Type: application/json; charset=utf-8',
388 | ])
389 | )
390 | ->will($this->returnValue(["{'foo': 'bar'}", 200]));
391 |
392 | $cronofy = new Cronofy([
393 | "client_id" => "clientId",
394 | "client_secret" => "clientSecret",
395 | "access_token" => "accessToken",
396 | "refresh_token" => "refreshToken",
397 | "http_client" => $http,
398 | ]);
399 |
400 | $actual = $cronofy->deleteExternalEvent([
401 | "calendar_id" => "cal_123",
402 | "event_uid" => "evt_456",
403 | ]);
404 | $this->assertNotNull($actual);
405 | }
406 |
407 | public function testFreeBusy()
408 | {
409 | $page_1 = '{
410 | "pages": {
411 | "current": 1,
412 | "total": 1,
413 | },
414 | "events": [
415 | {
416 | "calendar_id": "cal_U9uuErStTG@EAAAB_IsAsykA2DBTWqQTf-f0kJw",
417 | "event_uid": "evt_external_event_one",
418 | "summary": "Company Retreat"
419 | }
420 | ]
421 | }';
422 |
423 | $http = $this->createMock(HttpRequest::class);
424 | $http->expects($this->at(0))
425 | ->method('getPage')
426 | ->with(
427 | $this->equalTo('https://api.cronofy.com/v1/free_busy'),
428 | $this->equalTo([
429 | 'Authorization: Bearer accessToken',
430 | 'Host: api.cronofy.com'
431 | ]),
432 | "?localized_times=true"
433 | )
434 | ->will($this->returnValue([$page_1, 200]));
435 |
436 | $cronofy = new Cronofy([
437 | "client_id" => "clientId",
438 | "client_secret" => "clientSecret",
439 | "access_token" => "accessToken",
440 | "refresh_token" => "refreshToken",
441 | "http_client" => $http,
442 | ]);
443 |
444 | $params = [ "localized_times" => true ];
445 | $actual = $cronofy->freeBusy($params);
446 | $this->assertNotNull($actual);
447 | }
448 |
449 | public function testGetSmartInvite()
450 | {
451 | $http = $this->createMock(HttpRequest::class);
452 | $http->expects($this->once())
453 | ->method('httpGet')
454 | ->with(
455 | $this->equalTo('https://api.cronofy.com/v1/smart_invites?smart_invite_id=foo&recipient_email=foo%40example.com'),
456 | $this->equalTo([
457 | 'Authorization: Bearer clientSecret',
458 | 'Host: api.cronofy.com'
459 | ])
460 | )
461 | ->will($this->returnValue(["{'foo': 'bar'}", 200]));
462 |
463 | $cronofy = new Cronofy([
464 | "client_id" => "clientId",
465 | "client_secret" => "clientSecret",
466 | "access_token" => "accessToken",
467 | "refresh_token" => "refreshToken",
468 | "http_client" => $http,
469 | ]);
470 |
471 | $actual = $cronofy->getSmartInvite("foo", "foo@example.com");
472 | $this->assertNotNull($actual);
473 | }
474 |
475 | public function testCancelSmartInvite()
476 | {
477 | $recipient = ["email" => "example@example.com"];
478 | $smart_invite_id = "foo";
479 |
480 | $request_params = [
481 | "method" => "cancel",
482 | "recipient" => $recipient,
483 | "smart_invite_id" => $smart_invite_id,
484 | ];
485 |
486 | $http = $this->createMock(HttpRequest::class);
487 | $http->expects($this->once())
488 | ->method('httpPost')
489 | ->with(
490 | $this->equalTo('https://api.cronofy.com/v1/smart_invites'),
491 | $this->equalTo($request_params),
492 | $this->equalTo([
493 | 'Authorization: Bearer clientSecret',
494 | 'Host: api.cronofy.com',
495 | 'Content-Type: application/json; charset=utf-8'
496 | ])
497 | )
498 | ->will($this->returnValue(["{'foo': 'bar'}", 200]));
499 |
500 | $cronofy = new Cronofy([
501 | "client_id" => "clientId",
502 | "client_secret" => "clientSecret",
503 | "access_token" => "accessToken",
504 | "refresh_token" => "refreshToken",
505 | "http_client" => $http,
506 | ]);
507 |
508 | $params = [
509 | "recipient" => $recipient,
510 | "smart_invite_id" => $smart_invite_id,
511 | ];
512 |
513 | $actual = $cronofy->cancelSmartInvite($params);
514 | $this->assertNotNull($actual);
515 | }
516 |
517 | public function testCancelSmartInviteWithMultipleRecipients()
518 | {
519 | $recipients = array(
520 | array("email" => "example@example.com"),
521 | array("email" => "example@example.org"),
522 | );
523 | $smart_invite_id = "foo";
524 |
525 | $request_params = array(
526 | "method" => "cancel",
527 | "recipients" => $recipients,
528 | "smart_invite_id" => $smart_invite_id,
529 | );
530 |
531 | $http = $this->createMock(HttpRequest::class);
532 | $http->expects($this->once())
533 | ->method('httpPost')
534 | ->with(
535 | $this->equalTo('https://api.cronofy.com/v1/smart_invites'),
536 | $this->equalTo($request_params),
537 | $this->equalTo(array(
538 | 'Authorization: Bearer clientSecret',
539 | 'Host: api.cronofy.com',
540 | 'Content-Type: application/json; charset=utf-8'
541 | ))
542 | )
543 | ->will($this->returnValue(array("{'foo': 'bar'}", 200)));
544 |
545 | $cronofy = new Cronofy(array(
546 | "client_id" => "clientId",
547 | "client_secret" => "clientSecret",
548 | "access_token" => "accessToken",
549 | "refresh_token" => "refreshToken",
550 | "http_client" => $http,
551 | ));
552 |
553 | $params = array(
554 | "recipients" => $recipients,
555 | "smart_invite_id" => $smart_invite_id,
556 | );
557 |
558 | $actual = $cronofy->cancelSmartInvite($params);
559 | $this->assertNotNull($actual);
560 | }
561 |
562 | public function testCreateSmartInvite()
563 | {
564 | $event = [
565 | "summary" => "Add to Calendar test event",
566 | "start" => "2017-01-01T12:00:00Z",
567 | "end" => "2017-01-01T15:00:00Z"
568 | ];
569 | $recipient = ["email" => "example@example.com"];
570 | $organizer = ["name" => "Smart invite application"];
571 | $smart_invite_id = "foo";
572 | $callback_url = "http://www.example.com/callback";
573 |
574 | $params = [
575 | "recipient" => $recipient,
576 | "event" => $event,
577 | "smart_invite_id" => $smart_invite_id,
578 | "callback_url" => $callback_url,
579 | "organizer" => $organizer,
580 | ];
581 |
582 | $http = $this->createMock(HttpRequest::class);
583 | $http->expects($this->once())
584 | ->method('httpPost')
585 | ->with(
586 | $this->equalTo('https://api.cronofy.com/v1/smart_invites'),
587 | $this->equalTo($params),
588 | $this->equalTo([
589 | 'Authorization: Bearer clientSecret',
590 | 'Host: api.cronofy.com',
591 | 'Content-Type: application/json; charset=utf-8'
592 | ])
593 | )
594 | ->will($this->returnValue(["{'foo': 'bar'}", 200]));
595 |
596 | $cronofy = new Cronofy([
597 | "client_id" => "clientId",
598 | "client_secret" => "clientSecret",
599 | "access_token" => "accessToken",
600 | "refresh_token" => "refreshToken",
601 | "http_client" => $http,
602 | ]);
603 |
604 | $actual = $cronofy->createSmartInvite($params);
605 | $this->assertNotNull($actual);
606 | }
607 |
608 | public function testCreateSmartInviteWithMultipleRecipients()
609 | {
610 | $event = [
611 | "summary" => "Add to Calendar test event",
612 | "start" => "2017-01-01T12:00:00Z",
613 | "end" => "2017-01-01T15:00:00Z"
614 | ];
615 | $organizer = ["name" => "Smart invite application"];
616 | $smart_invite_id = "foo";
617 | $callback_url = "http://www.example.com/callback";
618 |
619 | $params = [
620 | "recipients" => [
621 | ["email" => "example@example.com"],
622 | ["email" => "example@example.org"],
623 | ],
624 | "event" => $event,
625 | "smart_invite_id" => $smart_invite_id,
626 | "callback_url" => $callback_url,
627 | "organizer" => $organizer,
628 | ];
629 |
630 | $http = $this->createMock(HttpRequest::class);
631 | $http->expects($this->once())
632 | ->method('httpPost')
633 | ->with(
634 | $this->equalTo('https://api.cronofy.com/v1/smart_invites'),
635 | $this->equalTo($params),
636 | $this->equalTo([
637 | 'Authorization: Bearer clientSecret',
638 | 'Host: api.cronofy.com',
639 | 'Content-Type: application/json; charset=utf-8'
640 | ])
641 | )
642 | ->will($this->returnValue(["{'foo': 'bar'}", 200]));
643 |
644 | $cronofy = new Cronofy([
645 | "client_id" => "clientId",
646 | "client_secret" => "clientSecret",
647 | "access_token" => "accessToken",
648 | "refresh_token" => "refreshToken",
649 | "http_client" => $http,
650 | ]);
651 |
652 | $actual = $cronofy->createSmartInvite($params);
653 | $this->assertNotNull($actual);
654 | }
655 |
656 | public function testRequestElementToken()
657 | {
658 | $params = [
659 | "version" => "1",
660 | "permissions" => ["agenda", "availability"],
661 | 'subs' => ['acc_12345678'],
662 | "origin" => 'http://local.test'
663 | ];
664 |
665 | $response = [
666 | "element_token" => [
667 | "permissions" => ["agenda", "availability"],
668 | "origin" => 'http://local.test',
669 | "token" => "ELEMENT_TOKEN",
670 | "expires_in" => 64800
671 | ]
672 | ];
673 |
674 | $http = $this->createMock(HttpRequest::class);
675 | $http->expects($this->once())
676 | ->method('httpPost')
677 | ->with(
678 | $this->equalTo('https://api.cronofy.com/v1/element_tokens'),
679 | $this->equalTo($params),
680 | $this->equalTo([
681 | 'Authorization: Bearer clientSecret',
682 | 'Host: api.cronofy.com',
683 | 'Content-Type: application/json; charset=utf-8'
684 | ])
685 | )
686 | ->will($this->returnValue([json_encode($response), 200]))
687 | ;
688 |
689 | $cronofy = new Cronofy([
690 | "client_id" => "clientId",
691 | "client_secret" => "clientSecret",
692 | "access_token" => "accessToken",
693 | "refresh_token" => "refreshToken",
694 | "http_client" => $http,
695 | ]);
696 |
697 | $actual = $cronofy->requestElementToken($params);
698 | $this->assertNotNull($actual);
699 | }
700 |
701 | public function testConferencingServiceAuthorization()
702 | {
703 | $request_params = [
704 | "redirect_uri" => "http://example.com",
705 | ];
706 |
707 | $response = [
708 | "authorization_request" => [
709 | "url" => "https://app.cronofy.com/conferencing_services/xxxxx"
710 | ],
711 | ];
712 |
713 | $http = $this->createMock(HttpRequest::class);
714 | $http->expects($this->once())
715 | ->method('httpPost')
716 | ->with(
717 | $this->equalTo('https://api.cronofy.com/v1/conferencing_service_authorizations'),
718 | $this->equalTo($request_params),
719 | $this->equalTo([
720 | 'Authorization: Bearer accessToken',
721 | 'Host: api.cronofy.com',
722 | 'Content-Type: application/json; charset=utf-8',
723 | ])
724 | )
725 | ->will($this->returnValue([json_encode($response), 200]));
726 |
727 | $cronofy = new Cronofy([
728 | "client_id" => "clientId",
729 | "client_secret" => "clientSecret",
730 | "access_token" => "accessToken",
731 | "refresh_token" => "refreshToken",
732 | "http_client" => $http,
733 | ]);
734 |
735 | $params = [
736 | 'redirect_uri' => "http://example.com",
737 | ];
738 |
739 | $actual = $cronofy->conferencingServiceAuthorization($params);
740 | $this->assertNotNull($actual);
741 | $this->assertEquals($actual, $response);
742 | }
743 |
744 | public function testDeleteAvailablePeriod()
745 | {
746 | $params = ["available_period_id" => "avp_456"];
747 |
748 | $http = $this->createMock(HttpRequest::class);
749 | $http->expects($this->once())
750 | ->method('httpDelete')
751 | ->with(
752 | $this->equalTo('https://api.cronofy.com/v1/available_periods/'),
753 | $this->equalTo($params),
754 | $this->equalTo([
755 | 'Authorization: Bearer accessToken',
756 | 'Host: api.cronofy.com',
757 | 'Content-Type: application/json; charset=utf-8',
758 | ])
759 | )
760 | ->will($this->returnValue(["{'foo': 'bar'}", 200]));
761 |
762 | $cronofy = new Cronofy([
763 | "client_id" => "clientId",
764 | "client_secret" => "clientSecret",
765 | "access_token" => "accessToken",
766 | "refresh_token" => "refreshToken",
767 | "http_client" => $http,
768 | ]);
769 |
770 | $actual = $cronofy->deleteAvailablePeriod([
771 | "available_period_id" => "avp_456",
772 | ]);
773 | $this->assertNotNull($actual);
774 | }
775 |
776 | public function testHmacValidation()
777 | {
778 | $cronofy = new Cronofy([
779 | "client_id" => "clientId",
780 | "client_secret" => "clientSecret",
781 | "access_token" => "accessToken",
782 | "refresh_token" => "refreshToken",
783 | "http_client" => null,
784 | ]);
785 |
786 | $body = '{"example":"well-known"}';
787 |
788 | $actual = $cronofy->hmacValid("QuGlxxssNDaxUjd6RY4wxGf+5KDrmobMmjkGQPtB3WQ=", $body);
789 | $this->assertTrue($actual);
790 |
791 | $actual = $cronofy->hmacValid("something-else", $body);
792 | $this->assertFalse($actual);
793 |
794 | $actual = $cronofy->hmacValid("something-else,QuGlxxssNDaxUjd6RY4wxGf+5KDrmobMmjkGQPtB3WQ=", $body);
795 | $this->assertTrue($actual);
796 |
797 | $actual = $cronofy->hmacValid("something-else,something-else2", $body);
798 | $this->assertFalse($actual);
799 |
800 | $actual = $cronofy->hmacValid(null, $body);
801 | $this->assertFalse($actual);
802 |
803 | $actual = $cronofy->hmacValid("", $body);
804 | $this->assertFalse($actual);
805 | }
806 | }
807 |
--------------------------------------------------------------------------------
/tests/DelegatedAuthorizationsTest.php:
--------------------------------------------------------------------------------
1 | $profileId,
21 | "email" => $email,
22 | "callback_url" => $callback_url,
23 | "scope" => $scopes,
24 | "state" => $state
25 | ];
26 |
27 | $http = $this->createMock(HttpRequest::class);
28 | $http->expects($this->once())
29 | ->method('httpPost')
30 | ->with(
31 | $this->equalTo('https://api.cronofy.com/v1/delegated_authorizations'),
32 | $this->equalTo([
33 | "profile_id" => $profileId,
34 | "email" => $email,
35 | "callback_url" => $callback_url,
36 | "scope" => "list_calendars read_free_busy",
37 | "state" => $state
38 | ]),
39 | $this->equalTo([
40 | 'Authorization: Bearer accessToken',
41 | 'Host: api.cronofy.com',
42 | 'Content-Type: application/json; charset=utf-8',
43 | ])
44 | )
45 | ->will($this->returnValue(["", 202]));
46 |
47 | $cronofy = new Cronofy([
48 | "client_id" => "clientId",
49 | "client_secret" => "clientSecret",
50 | "access_token" => "accessToken",
51 | "refresh_token" => "refreshToken",
52 | "http_client" => $http,
53 | ]);
54 |
55 | $cronofy->requestDelegatedAuthorization($args);
56 | }
57 |
58 | public function testErrorHandling()
59 | {
60 | $profileId = "profileId";
61 | $email = "emailOfAccountToAccess";
62 | $callback_url = "http://www.example.com/callback";
63 | $scopes = ["list_calendars", "read_free_busy"];
64 | $state = "user-state";
65 |
66 | $args = [
67 | "profile_id" => $profileId,
68 | "email" => $email,
69 | "callback_url" => $callback_url,
70 | "scope" => $scopes,
71 | "state" => $state
72 | ];
73 |
74 | $errorResponse = '{
75 | "errors": {
76 | "email": [
77 | {
78 | "key": "errors.required",
79 | "description": "required"
80 | }
81 | ]
82 | }
83 | }';
84 |
85 | $http = $this->createMock(HttpRequest::class);
86 | $http->expects($this->once())
87 | ->method('httpPost')
88 | ->with(
89 | $this->equalTo('https://api.cronofy.com/v1/delegated_authorizations'),
90 | $this->equalTo([
91 | "profile_id" => $profileId,
92 | "email" => $email,
93 | "callback_url" => $callback_url,
94 | "scope" => "list_calendars read_free_busy",
95 | "state" => $state
96 | ]),
97 | $this->equalTo([
98 | 'Authorization: Bearer accessToken',
99 | 'Host: api.cronofy.com',
100 | 'Content-Type: application/json; charset=utf-8',
101 | ])
102 | )
103 | ->will($this->returnValue([$errorResponse, 422]));
104 |
105 | $cronofy = new Cronofy([
106 | "client_id" => "clientId",
107 | "client_secret" => "clientSecret",
108 | "access_token" => "accessToken",
109 | "refresh_token" => "refreshToken",
110 | "http_client" => $http,
111 | ]);
112 |
113 | $raised_error = false;
114 |
115 | try {
116 | $cronofy->requestDelegatedAuthorization($args);
117 | } catch (CronofyException $exception) {
118 | $raised_error = true;
119 | $this->assertEquals(json_decode($errorResponse, true), $exception->error_details());
120 | $this->assertEquals(422, $exception->getCode());
121 | }
122 |
123 | $this->assertTrue($raised_error);
124 | }
125 | }
126 |
--------------------------------------------------------------------------------
/tests/ReadEventsTest.php:
--------------------------------------------------------------------------------
1 | createMock(HttpRequest::class);
27 | $http->expects($this->once())
28 | ->method('getPage')
29 | ->with(
30 | $this->equalTo('https://api.cronofy.com/v1/events'),
31 | $this->equalTo([
32 | 'Authorization: Bearer accessToken',
33 | 'Host: api.cronofy.com'
34 | ]),
35 | "?tzid=Etc%2FUTC"
36 | )
37 | ->will($this->returnValue([$events_page, 200]));
38 |
39 | $cronofy = new Cronofy([
40 | "client_id" => "clientId",
41 | "client_secret" => "clientSecret",
42 | "access_token" => "accessToken",
43 | "refresh_token" => "refreshToken",
44 | "http_client" => $http,
45 | ]);
46 |
47 | $params = [
48 | 'tzid' => 'Etc/UTC'
49 | ];
50 |
51 | $actual = $cronofy->readEvents($params);
52 | $this->assertNotNull($actual);
53 | $this->assertCount(1, $actual);
54 | $this->assertCount(1, $actual->each());
55 |
56 | foreach ($actual->each() as $event) {
57 | $this->assertNotNull($event);
58 | $this->assertEquals($event["event_uid"], "evt_external_54008b1a4a41730f8d5c6037");
59 | }
60 |
61 | foreach ($actual as $event) {
62 | $this->assertNotNull($event);
63 | $this->assertEquals($event["event_uid"], "evt_external_54008b1a4a41730f8d5c6037");
64 | }
65 | }
66 |
67 | public function testReadEventsTwoPageSingleEvent()
68 | {
69 | $page_1 = '{
70 | "pages": {
71 | "current": 1,
72 | "total": 2,
73 | "next_page": "https://api.cronofy.com/v1/events/pages/08a07b034306679e"
74 | },
75 | "events": [
76 | {
77 | "calendar_id": "cal_U9uuErStTG@EAAAB_IsAsykA2DBTWqQTf-f0kJw",
78 | "event_uid": "evt_external_event_one",
79 | "summary": "Company Retreat"
80 | }
81 | ]
82 | }';
83 |
84 | $page_2 = '{
85 | "pages": {
86 | "current": 2,
87 | "total": 2
88 | },
89 | "events": [
90 | {
91 | "calendar_id": "cal_U9uuErStTG@EAAAB_IsAsykA2DBTWqQTf-f0kJw",
92 | "event_uid": "evt_external_event_two",
93 | "summary": "Company Retreat"
94 | }
95 | ]
96 | }';
97 |
98 | $http = $this->createMock(HttpRequest::class);
99 | $http->expects($this->exactly(2))
100 | ->method('getPage')
101 | ->will($this->onConsecutiveCalls([$page_1, 200], [$page_2, 200]));
102 |
103 | $cronofy = new Cronofy([
104 | "client_id" => "clientId",
105 | "client_secret" => "clientSecret",
106 | "access_token" => "accessToken",
107 | "refresh_token" => "refreshToken",
108 | "http_client" => $http,
109 | ]);
110 |
111 | $params = [
112 | 'tzid' => 'Etc/UTC'
113 | ];
114 |
115 | $actual = $cronofy->readEvents($params);
116 | $this->assertNotNull($actual);
117 | $this->assertCount(2, $actual);
118 | }
119 |
120 | public function testReadEventsCanBeConvertedToArray()
121 | {
122 | $page_1 = '{
123 | "pages": {
124 | "current": 1,
125 | "total": 2,
126 | "next_page": "https://api.cronofy.com/v1/events/pages/08a07b034306679e"
127 | },
128 | "events": [
129 | {
130 | "calendar_id": "cal_U9uuErStTG@EAAAB_IsAsykA2DBTWqQTf-f0kJw",
131 | "event_uid": "evt_external_event_one",
132 | "summary": "Company Retreat"
133 | }
134 | ]
135 | }';
136 |
137 | $page_2 = '{
138 | "pages": {
139 | "current": 2,
140 | "total": 2
141 | },
142 | "events": [
143 | {
144 | "calendar_id": "cal_U9uuErStTG@EAAAB_IsAsykA2DBTWqQTf-f0kJw",
145 | "event_uid": "evt_external_event_two",
146 | "summary": "Company Retreat"
147 | }
148 | ]
149 | }';
150 |
151 | $http = $this->createMock(HttpRequest::class);
152 | $http->expects($this->exactly(2))
153 | ->method('getPage')
154 | ->will($this->onConsecutiveCalls([$page_1, 200], [$page_2, 200]));
155 |
156 | $cronofy = new Cronofy([
157 | "client_id" => "clientId",
158 | "client_secret" => "clientSecret",
159 | "access_token" => "accessToken",
160 | "refresh_token" => "refreshToken",
161 | "http_client" => $http,
162 | ]);
163 |
164 | $params = [
165 | 'tzid' => 'Etc/UTC'
166 | ];
167 |
168 | $actual = $cronofy->readEvents($params);
169 | $event_uids = array_map(function (array $event) {
170 | return $event['event_uid'];
171 | }, iterator_to_array($actual));
172 |
173 | $this->assertContains('evt_external_event_one', $event_uids);
174 | $this->assertContains('evt_external_event_two', $event_uids);
175 | }
176 | }
177 |
--------------------------------------------------------------------------------
/tests/RulesTest.php:
--------------------------------------------------------------------------------
1 | [
14 | "availability_rule_id" => "default",
15 | "tzid" => "Etc/UTC",
16 | "weekly_periods" => [
17 | [
18 | "day" => "monday",
19 | "start_time" => "09:00",
20 | "end_time" => "13:00"
21 | ],
22 | [
23 | "day" => "monday",
24 | "start_time" => "14:00",
25 | "end_time" => "17:00"
26 | ],
27 | [
28 | "day" => "tuesday",
29 | "start_time" => "09:00",
30 | "end_time" => "17:00"
31 | ]
32 | ]
33 | ]
34 | ];
35 | $http = $this->createMock(HttpRequest::class);
36 | $http->expects($this->once())
37 | ->method('httpGet')
38 | ->with(
39 | $this->equalTo('https://api.cronofy.com/v1/availability_rules/default')
40 | )
41 | ->will($this->returnValue([json_encode($expected_rule), 200]));
42 |
43 | $cronofy = new Cronofy([
44 | "client_id" => "clientId",
45 | "client_secret" => "clientSecret",
46 | "access_token" => "accessToken",
47 | "refresh_token" => "refreshToken",
48 | "http_client" => $http,
49 | ]);
50 |
51 | $response = $cronofy->getAvailabilityRule("default");
52 |
53 | $this->assertNotNull($response);
54 | $this->assertEquals(3, count($response['availability_rule']));
55 | $this->assertEquals("default", $response['availability_rule']['availability_rule_id']);
56 | }
57 |
58 | public function testListAvailabilityRules()
59 | {
60 | $expected_rules = [
61 | "availability_rules" => [
62 | [
63 | "availability_rule_id" => "default",
64 | "calendar_ids" => ["cal_123"],
65 | "tzid" => "Etc/UTC",
66 | "weekly_periods" => [
67 | [
68 | "day" => "monday",
69 | "start_time" => "09:00",
70 | "end_time" => "13:00"
71 | ],
72 | [
73 | "day" => "monday",
74 | "start_time" => "14:00",
75 | "end_time" => "17:00"
76 | ],
77 | [
78 | "day" => "tuesday",
79 | "start_time" => "09:00",
80 | "end_time" => "17:00"
81 | ]
82 | ]
83 | ],
84 | [
85 | "availability_rule_id" => "work_hours",
86 | "calendar_ids" => ["cal_321"],
87 | "tzid" => "Etc/UTC",
88 | "weekly_periods" => [
89 | [
90 | "day" => "tuesday",
91 | "start_time" => "09:00",
92 | "end_time" => "17:00"
93 | ],
94 | [
95 | "day" => "wednesday",
96 | "start_time" => "09:00",
97 | "end_time" => "17:00"
98 | ]
99 | ]
100 | ],
101 | ]
102 | ];
103 | $http = $this->createMock(HttpRequest::class);
104 | $http->expects($this->once())
105 | ->method('httpGet')
106 | ->with(
107 | $this->equalTo('https://api.cronofy.com/v1/availability_rules')
108 | )
109 | ->will($this->returnValue([json_encode($expected_rules), 200]));
110 |
111 | $cronofy = new Cronofy([
112 | "client_id" => "clientId",
113 | "client_secret" => "clientSecret",
114 | "access_token" => "accessToken",
115 | "refresh_token" => "refreshToken",
116 | "http_client" => $http,
117 | ]);
118 |
119 | $response = $cronofy->listAvailabilityRules();
120 |
121 | $this->assertNotNull($response);
122 | $this->assertEquals(2, count($response['availability_rules']));
123 | $this->assertEquals(4, count($response['availability_rules'][0]));
124 | $this->assertEquals("default", $response['availability_rules'][0]['availability_rule_id']);
125 | $this->assertEquals("work_hours", $response['availability_rules'][1]['availability_rule_id']);
126 | }
127 |
128 | public function testDeleteAvailabilityRules()
129 | {
130 |
131 | $http = $this->createMock(HttpRequest::class);
132 | $http->expects($this->once())
133 | ->method('httpDelete')
134 | ->with(
135 | $this->equalTo('https://api.cronofy.com/v1/availability_rules/rule_123')
136 | )
137 | ->will($this->returnValue(["{'foo': 'bar'}", 200]));
138 |
139 | $cronofy = new Cronofy([
140 | "client_id" => "clientId",
141 | "client_secret" => "clientSecret",
142 | "access_token" => "accessToken",
143 | "refresh_token" => "refreshToken",
144 | "http_client" => $http,
145 | ]);
146 |
147 | $actual = $cronofy->deleteAvailabilityRule("rule_123");
148 | $this->assertNotNull($actual);
149 | }
150 |
151 | public function testCreateAvailabilityRule()
152 | {
153 | $expected_output = [
154 | "availability_rule_id" => "default",
155 | "calendar_ids" => ["cal_123"],
156 | "tzid" => "America/Chicago",
157 | "weekly_periods" => [
158 | [
159 | "day" => "monday",
160 | "start_time" => "09:30",
161 | "end_time" => "12:30"
162 | ],
163 | [
164 | "day" => "wednesday",
165 | "start_time" => "09:30",
166 | "end_time" => "12:30"
167 | ]
168 | ]
169 | ];
170 |
171 | $params = [
172 | "availability_rule_id" => "default",
173 | "calendar_ids" => ["cal_123"],
174 | "tzid" => "America/Chicago",
175 | "weekly_periods" => [
176 | [
177 | "day" => "monday",
178 | "start_time" => "09:30",
179 | "end_time" => "12:30"
180 | ],
181 | [
182 | "day" => "wednesday",
183 | "start_time" => "09:30",
184 | "end_time" => "12:30"
185 | ]
186 | ]
187 | ];
188 |
189 | $http = $this->createMock(HttpRequest::class);
190 | $http->expects($this->once())
191 | ->method('httpPost')
192 | ->with(
193 | $this->equalTo('https://api.cronofy.com/v1/availability_rules'),
194 | $this->equalTo($params)
195 | )
196 | ->will($this->returnValue([json_encode($expected_output), 200]));
197 |
198 | $cronofy = new Cronofy([
199 | "client_id" => "clientId",
200 | "client_secret" => "clientSecret",
201 | "access_token" => "accessToken",
202 | "refresh_token" => "refreshToken",
203 | "http_client" => $http,
204 | ]);
205 |
206 | $response = $cronofy->createAvailabilityRule($params);
207 |
208 | $this->assertNotNull($response);
209 | $this->assertEquals(4, count($response));
210 | $this->assertEquals("default", $response['availability_rule_id']);
211 | $this->assertEquals(2, count($response['weekly_periods']));
212 | }
213 | }
214 |
--------------------------------------------------------------------------------
/tests/SchedulingTest.php:
--------------------------------------------------------------------------------
1 | "PERIODS",
15 | "participants" => "PARTICIPANTS",
16 | "required_duration" => "DURATION",
17 | "response_format" => "FORMAT"
18 | ];
19 |
20 | $http = $this->createMock(HttpRequest::class);
21 | $http->expects($this->once())
22 | ->method('httpPost')
23 | ->with(
24 | $this->equalTo('https://api.cronofy.com/v1/availability'),
25 | $this->equalTo($parsedParams)
26 | )
27 | ->will($this->returnValue([json_encode($parsedParams), 200]));
28 |
29 | $cronofy = new Cronofy([
30 | "client_id" => "clientId",
31 | "client_secret" => "clientSecret",
32 | "access_token" => "accessToken",
33 | "refresh_token" => "refreshToken",
34 | "http_client" => $http,
35 | ]);
36 |
37 | $params = [
38 | "participants" => "PARTICIPANTS",
39 | "available_periods" => "PERIODS",
40 | "required_duration" => "DURATION",
41 | "response_format" => "FORMAT"
42 | ];
43 |
44 | $response = $cronofy->availability($params);
45 | $this->assertNotNull($response);
46 | }
47 |
48 | public function testRealTimeScheduling()
49 | {
50 | $oauth = [
51 | "redirect_uri" => "http://test.com/",
52 | "scope" => "test_scope"
53 | ];
54 | $event = [
55 | "event_id" => "test_event_id",
56 | "summary" => "Add to Calendar test event",
57 | ];
58 | $availability = [
59 | "participants" => [
60 | [
61 | "members" => [
62 | [
63 | "sub" => "acc_567236000909002",
64 | "calendar_ids" => ["cal_n23kjnwrw2_jsdfjksn234"]
65 | ]
66 | ],
67 | "required" => "all"
68 | ]
69 | ],
70 | "required_duration" => [
71 | "minutes" => 60
72 | ],
73 | "start_interval" => [
74 | "minutes" => 60
75 | ],
76 | "buffer" => [
77 | "before" => [
78 | "minutes" => 60
79 | ]
80 | ],
81 | "available_periods" => [
82 | [
83 | "start" => "2017-01-01T09:00:00Z",
84 | "end" => "2017-01-01T17:00:00Z"
85 | ]
86 | ]
87 | ];
88 | $target_calendars = [
89 | [
90 | "sub" => "acc_567236000909002",
91 | "calendar_id" => "cal_n23kjnwrw2_jsdfjksn234"
92 | ]
93 | ];
94 | $tzid = 'Europe/London';
95 | $callback_url = "http://example.com/callback";
96 | $completed_redirect_url = "http://example.com/redirect";
97 |
98 | $params = [
99 | "client_id" => "clientId",
100 | "client_secret" => "clientSecret",
101 | "event" => $event,
102 | "target_calendars" => $target_calendars,
103 | "availability" => $availability,
104 | "oauth" => $oauth,
105 | "tzid" => $tzid,
106 | "callback_urls" => [
107 | "completed_url" => $callback_url,
108 | ],
109 | "redirect_urls" => [
110 | "completed_url" => $completed_redirect_url,
111 | ],
112 | "formatting" => [
113 | "hour_format" => "12",
114 | ],
115 | "minimum_notice" => [
116 | "hours" => 2
117 | ],
118 | "event_creation" => "single",
119 | ];
120 |
121 | $http = $this->createMock(HttpRequest::class);
122 | $http->expects($this->once())
123 | ->method('httpPost')
124 | ->with(
125 | $this->equalTo('https://api.cronofy.com/v1/real_time_scheduling'),
126 | $this->equalTo($params),
127 | $this->equalTo([
128 | 'Authorization: Bearer accessToken',
129 | 'Host: api.cronofy.com',
130 | 'Content-Type: application/json; charset=utf-8'
131 | ])
132 | )
133 | ->will($this->returnValue(["{'foo': 'bar'}", 200]));
134 |
135 | $cronofy = new Cronofy([
136 | "client_id" => "clientId",
137 | "client_secret" => "clientSecret",
138 | "access_token" => "accessToken",
139 | "refresh_token" => "refreshToken",
140 | "http_client" => $http,
141 | ]);
142 |
143 | $actual = $cronofy->realTimeScheduling($params);
144 | $this->assertNotNull($actual);
145 | }
146 |
147 | public function testRealTimeSchedulingWhenDeprecatedCallbackUrlPassed()
148 | {
149 | $oauth = [
150 | "redirect_uri" => "http://test.com/",
151 | "scope" => "test_scope"
152 | ];
153 | $event = [
154 | "event_id" => "test_event_id",
155 | "summary" => "Add to Calendar test event",
156 | ];
157 | $availability = [
158 | "participants" => [
159 | [
160 | "members" => [
161 | [
162 | "sub" => "acc_567236000909002",
163 | "calendar_ids" => ["cal_n23kjnwrw2_jsdfjksn234"]
164 | ]
165 | ],
166 | "required" => "all"
167 | ]
168 | ],
169 | "required_duration" => [
170 | "minutes" => 60
171 | ],
172 | "start_interval" => [
173 | "minutes" => 60
174 | ],
175 | "buffer" => [
176 | "before" => [
177 | "minutes" => 60
178 | ]
179 | ],
180 | "available_periods" => [
181 | [
182 | "start" => "2017-01-01T09:00:00Z",
183 | "end" => "2017-01-01T17:00:00Z"
184 | ]
185 | ]
186 | ];
187 | $target_calendars = [
188 | [
189 | "sub" => "acc_567236000909002",
190 | "calendar_id" => "cal_n23kjnwrw2_jsdfjksn234"
191 | ]
192 | ];
193 | $tzid = 'Europe/London';
194 | $callback_url = "http://example.com/callback";
195 |
196 | $params = [
197 | "client_id" => "clientId",
198 | "client_secret" => "clientSecret",
199 | "event" => $event,
200 | "target_calendars" => $target_calendars,
201 | "availability" => $availability,
202 | "oauth" => $oauth,
203 | "tzid" => $tzid,
204 | "callback_url" => "http://example.com/THIS_ONE_GETS_OVERRIDEN",
205 | "callback_urls" => [
206 | "completed_url" => $callback_url
207 | ]
208 | ];
209 |
210 | $sentParams = $params;
211 | unset($sentParams["callback_url"]);
212 |
213 | $http = $this->createMock(HttpRequest::class);
214 | $http->expects($this->once())
215 | ->method('httpPost')
216 | ->with(
217 | $this->equalTo('https://api.cronofy.com/v1/real_time_scheduling'),
218 | $this->equalTo($sentParams),
219 | $this->equalTo([
220 | 'Authorization: Bearer accessToken',
221 | 'Host: api.cronofy.com',
222 | 'Content-Type: application/json; charset=utf-8'
223 | ])
224 | )
225 | ->will($this->returnValue(["{'foo': 'bar'}", 200]));
226 |
227 | $cronofy = new Cronofy([
228 | "client_id" => "clientId",
229 | "client_secret" => "clientSecret",
230 | "access_token" => "accessToken",
231 | "refresh_token" => "refreshToken",
232 | "http_client" => $http,
233 | ]);
234 |
235 | $actual = $cronofy->realTimeScheduling($params);
236 | $this->assertNotNull($actual);
237 | }
238 |
239 | public function testRealTimeSchedulingWhenDeprecatedCallbackUrlPassedAndNewCallbackUrlsCompletedUrlPassed()
240 | {
241 | $oauth = [
242 | "redirect_uri" => "http://test.com/",
243 | "scope" => "test_scope"
244 | ];
245 | $event = [
246 | "event_id" => "test_event_id",
247 | "summary" => "Add to Calendar test event",
248 | ];
249 | $availability = [
250 | "participants" => [
251 | [
252 | "members" => [
253 | [
254 | "sub" => "acc_567236000909002",
255 | "calendar_ids" => ["cal_n23kjnwrw2_jsdfjksn234"]
256 | ]
257 | ],
258 | "required" => "all"
259 | ]
260 | ],
261 | "required_duration" => [
262 | "minutes" => 60
263 | ],
264 | "start_interval" => [
265 | "minutes" => 60
266 | ],
267 | "buffer" => [
268 | "before" => [
269 | "minutes" => 60
270 | ]
271 | ],
272 | "available_periods" => [
273 | [
274 | "start" => "2017-01-01T09:00:00Z",
275 | "end" => "2017-01-01T17:00:00Z"
276 | ]
277 | ]
278 | ];
279 | $target_calendars = [
280 | [
281 | "sub" => "acc_567236000909002",
282 | "calendar_id" => "cal_n23kjnwrw2_jsdfjksn234"
283 | ]
284 | ];
285 | $tzid = 'Europe/London';
286 | $callback_url = "http://example.com/callback";
287 |
288 | $params = [
289 | "client_id" => "clientId",
290 | "client_secret" => "clientSecret",
291 | "event" => $event,
292 | "target_calendars" => $target_calendars,
293 | "availability" => $availability,
294 | "oauth" => $oauth,
295 | "tzid" => $tzid,
296 | "callback_url" => "http://example.com/THIS_GETS_MOVED_TO_CALLBACK_URLS_COMPLETED_URL",
297 | "callback_urls" => [
298 | "no_times_suitable_url" => "https://example.com/no_times_suitable"
299 | ]
300 | ];
301 |
302 | $sentParams = $params;
303 | $sentParams["callback_urls"]["completed_url"] = $params["callback_url"];
304 | unset($sentParams["callback_url"]);
305 |
306 | $http = $this->createMock(HttpRequest::class);
307 | $http->expects($this->once())
308 | ->method('httpPost')
309 | ->with(
310 | $this->equalTo('https://api.cronofy.com/v1/real_time_scheduling'),
311 | $this->equalTo($sentParams),
312 | $this->equalTo([
313 | 'Authorization: Bearer accessToken',
314 | 'Host: api.cronofy.com',
315 | 'Content-Type: application/json; charset=utf-8'
316 | ])
317 | )
318 | ->will($this->returnValue(["{'foo': 'bar'}", 200]));
319 |
320 | $cronofy = new Cronofy([
321 | "client_id" => "clientId",
322 | "client_secret" => "clientSecret",
323 | "access_token" => "accessToken",
324 | "refresh_token" => "refreshToken",
325 | "http_client" => $http,
326 | ]);
327 |
328 | $actual = $cronofy->realTimeScheduling($params);
329 | $this->assertNotNull($actual);
330 | }
331 |
332 | public function testDisableRealTimeScheduling()
333 | {
334 | $rts_id = 'sch_1234567890123456786453';
335 | $display_message = "rtsDisplayMessage";
336 |
337 | $params = [
338 | "id" => $rts_id,
339 | "display_message" => $display_message
340 | ];
341 |
342 | $postFields = [
343 | "display_message" => $display_message
344 | ];
345 |
346 | $http = $this->createMock(HttpRequest::class);
347 | $http->expects($this->once())
348 | ->method('httpPost')
349 | ->with(
350 | $this->equalTo('https://api.cronofy.com/v1/real_time_scheduling/'.$rts_id.'/disable'),
351 | $this->equalTo($postFields),
352 | $this->equalTo([
353 | 'Authorization: Bearer clientSecret',
354 | 'Host: api.cronofy.com',
355 | 'Content-Type: application/json; charset=utf-8',
356 | ])
357 | )
358 | ->will($this->returnValue(["{'foo': 'bar'}", 200]));
359 |
360 | $cronofy = new Cronofy([
361 | "client_id" => "clientId",
362 | "client_secret" => "clientSecret",
363 | "access_token" => "accessToken",
364 | "refresh_token" => "refreshToken",
365 | "http_client" => $http,
366 | ]);
367 |
368 | $actual = $cronofy->disableRealTimeScheduling($params);
369 | $this->assertNotNull($actual);
370 | }
371 |
372 | public function testRealTimeSequencing()
373 | {
374 | $oauth = [
375 | "redirect_uri" => "http://test.com/",
376 | "scope" => "test_scope"
377 | ];
378 | $event = [
379 | "event_id" => "test_event_id",
380 | "summary" => "Add to Calendar test event",
381 | ];
382 | $availability = [
383 | "sequence" => [
384 | [
385 | "sequence_id" => "123",
386 | "ordinal" => 1,
387 | "participants" => [
388 | [
389 | "members" => [
390 | [
391 | "sub" => "acc_567236000909002",
392 | "calendar_ids" => ["cal_n23kjnwrw2_jsdfjksn234"]
393 | ]
394 | ],
395 | "required" => "all"
396 | ]
397 | ],
398 | "event" => $event,
399 | "required_duration" => [
400 | "minutes" => 60
401 | ],
402 | ],
403 | ],
404 | "available_periods" => [
405 | [
406 | "start" => "2017-01-01T09:00:00Z",
407 | "end" => "2017-01-01T17:00:00Z"
408 | ]
409 | ]
410 | ];
411 | $target_calendars = [
412 | [
413 | "sub" => "acc_567236000909002",
414 | "calendar_id" => "cal_n23kjnwrw2_jsdfjksn234"
415 | ]
416 | ];
417 | $tzid = 'Europe/London';
418 |
419 | $params = [
420 | "client_id" => "clientId",
421 | "client_secret" => "clientSecret",
422 | "event" => $event,
423 | "target_calendars" => $target_calendars,
424 | "availability" => $availability,
425 | "oauth" => $oauth,
426 | "tzid" => $tzid,
427 | ];
428 |
429 | $http = $this->createMock(HttpRequest::class);
430 | $http->expects($this->once())
431 | ->method('httpPost')
432 | ->with(
433 | $this->equalTo('https://api.cronofy.com/v1/real_time_sequencing'),
434 | $this->equalTo($params),
435 | $this->equalTo([
436 | 'Authorization: Bearer accessToken',
437 | 'Host: api.cronofy.com',
438 | 'Content-Type: application/json; charset=utf-8'
439 | ])
440 | )
441 | ->will($this->returnValue(["{'foo': 'bar'}", 200]));
442 |
443 | $cronofy = new Cronofy([
444 | "client_id" => "clientId",
445 | "client_secret" => "clientSecret",
446 | "access_token" => "accessToken",
447 | "refresh_token" => "refreshToken",
448 | "http_client" => $http,
449 | ]);
450 |
451 | $actual = $cronofy->realTimeSequencing($params);
452 | $this->assertNotNull($actual);
453 | }
454 | }
455 |
--------------------------------------------------------------------------------
/tests/UpsertEventTest.php:
--------------------------------------------------------------------------------
1 | "board room",
14 | "latitude" => "12.2344",
15 | "longitude" => "45.2444",
16 | ];
17 |
18 | $reminders = [
19 | ["minutes" => 30],
20 | ["minutes" => 1440]
21 | ];
22 |
23 | $attendees = [
24 | "invite" => [["email" => "new_invitee@test.com", "display_name" => "New Invitee"]],
25 | "reject" => [["email" => "old_invitee@test.com", "display_name" => "Old Invitee"]]
26 | ];
27 |
28 | $calendarId = "cal_123";
29 |
30 | $event = [
31 | "event_id" => "partner_event_id",
32 | "summary" => "Upsert Event Test",
33 | "description" => "description example",
34 | "start" => "2017-01-01T12:00:00Z",
35 | "end" => "2017-01-01T15:00:00Z",
36 | "tzid" => "Europe/London",
37 | "location" => $location,
38 | "reminders" => $reminders,
39 | "attendees" => $attendees,
40 | "event_private" => true,
41 | "reminders_create_only" => true,
42 | "transparency" => "opaque",
43 | "color" => "#c6040f",
44 | "conferencing" => [
45 | "profile_id" => "default"
46 | ],
47 | "locale" => "it",
48 | "event_classes" => "event_classes"
49 | ];
50 |
51 | $params = $event + ["calendar_id" => $calendarId];
52 |
53 | $http = $this->createMock(HttpRequest::class);
54 | $http->expects($this->once())
55 | ->method('httpPost')
56 | ->with(
57 | $this->equalTo('https://api.cronofy.com/v1/calendars/'.$calendarId.'/events'),
58 | $this->equalTo($event),
59 | $this->equalTo([
60 | 'Authorization: Bearer accessToken',
61 | 'Host: api.cronofy.com',
62 | 'Content-Type: application/json; charset=utf-8'
63 | ])
64 | )
65 | ->will($this->returnValue(["{'foo': 'bar'}", 200]));
66 |
67 | $cronofy = new Cronofy([
68 | "client_id" => "clientId",
69 | "client_secret" => "clientSecret",
70 | "access_token" => "accessToken",
71 | "refresh_token" => "refreshToken",
72 | "http_client" => $http,
73 | ]);
74 |
75 | $actual = $cronofy->upsertEvent($params);
76 | $this->assertNotNull($actual);
77 | }
78 |
79 | public function testUpsertExternalEvent()
80 | {
81 | $location = [
82 | "description" => "board room",
83 | "latitude" => "12.2344",
84 | "longitude" => "45.2444",
85 | ];
86 |
87 | $reminders = [
88 | ["minutes" => 30],
89 | ["minutes" => 1440]
90 | ];
91 |
92 | $attendees = [
93 | "invite" => [["email" => "new_invitee@test.com", "display_name" => "New Invitee"]],
94 | "reject" => [["email" => "old_invitee@test.com", "display_name" => "Old Invitee"]]
95 | ];
96 |
97 | $calendarId = "cal_123";
98 |
99 | $event = [
100 | "event_uid" => "evt_external_22343948494",
101 | "summary" => "Upsert Event Test",
102 | "description" => "description example",
103 | "start" => "2017-01-01T12:00:00Z",
104 | "end" => "2017-01-01T15:00:00Z",
105 | "tzid" => "Europe/London",
106 | "location" => $location,
107 | "reminders" => $reminders,
108 | "attendees" => $attendees,
109 | "event_private" => true,
110 | "reminders_create_only" => true,
111 | "transparency" => "opaque",
112 | ];
113 |
114 | $params = $event + ["calendar_id" => $calendarId];
115 |
116 | $http = $this->createMock(HttpRequest::class);
117 | $http->expects($this->once())
118 | ->method('httpPost')
119 | ->with(
120 | $this->equalTo('https://api.cronofy.com/v1/calendars/'.$calendarId.'/events'),
121 | $this->equalTo($event),
122 | $this->equalTo([
123 | 'Authorization: Bearer accessToken',
124 | 'Host: api.cronofy.com',
125 | 'Content-Type: application/json; charset=utf-8'
126 | ])
127 | )
128 | ->will($this->returnValue(["{'foo': 'bar'}", 200]));
129 |
130 | $cronofy = new Cronofy([
131 | "client_id" => "clientId",
132 | "client_secret" => "clientSecret",
133 | "access_token" => "accessToken",
134 | "refresh_token" => "refreshToken",
135 | "http_client" => $http,
136 | ]);
137 |
138 | $actual = $cronofy->upsertExternalEvent($params);
139 | $this->assertNotNull($actual);
140 | }
141 | }
142 |
--------------------------------------------------------------------------------
/tests/bootstrap.php:
--------------------------------------------------------------------------------
1 |