1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* Google Calendar Feed |
4
|
|
|
* |
5
|
|
|
* @package SimpleCalendar/Feeds |
6
|
|
|
*/ |
7
|
|
|
namespace SimpleCalendar\Feeds; |
8
|
|
|
|
9
|
|
|
use Carbon\Carbon; |
10
|
|
|
use Carbon\CarbonInterval; |
11
|
|
|
use SimpleCalendar\Abstracts\Calendar; |
12
|
|
|
use SimpleCalendar\Abstracts\Feed; |
13
|
|
|
use SimpleCalendar\Feeds\Admin\Google_Admin as Admin; |
14
|
|
|
|
15
|
|
|
if ( ! defined( 'ABSPATH' ) ) { |
16
|
|
|
exit; |
17
|
|
|
} |
18
|
|
|
|
19
|
|
|
/** |
20
|
|
|
* Google Calendar feed. |
21
|
|
|
* |
22
|
|
|
* A feed using a simple Google API key to pull events from public calendars. |
23
|
|
|
* |
24
|
|
|
* @since 3.0.0 |
25
|
|
|
*/ |
26
|
|
|
class Google extends Feed { |
27
|
|
|
|
28
|
|
|
|
29
|
|
|
/** |
30
|
|
|
* Google API Client. |
31
|
|
|
* |
32
|
|
|
* @access private |
33
|
|
|
* @var \Google_Client |
34
|
|
|
*/ |
35
|
|
|
protected $google_client = null; |
36
|
|
|
|
37
|
|
|
/** |
38
|
|
|
* Client scopes. |
39
|
|
|
* |
40
|
|
|
* @access private |
41
|
|
|
* @var array |
42
|
|
|
*/ |
43
|
|
|
protected $google_client_scopes = array(); |
44
|
|
|
|
45
|
|
|
/** |
46
|
|
|
* Google Calendar API key. |
47
|
|
|
* |
48
|
|
|
* @access protected |
49
|
|
|
* @var string |
50
|
|
|
*/ |
51
|
|
|
protected $google_api_key = ''; |
52
|
|
|
|
53
|
|
|
/** |
54
|
|
|
* Google Calendar ID. |
55
|
|
|
* |
56
|
|
|
* @access protected |
57
|
|
|
* @var string |
58
|
|
|
*/ |
59
|
|
|
protected $google_calendar_id = ''; |
60
|
|
|
|
61
|
|
|
/** |
62
|
|
|
* Google recurring events query setting. |
63
|
|
|
* |
64
|
|
|
* @access protected |
65
|
|
|
* @var string |
66
|
|
|
*/ |
67
|
|
|
protected $google_events_recurring = ''; |
68
|
|
|
|
69
|
|
|
/** |
70
|
|
|
* Google search query setting. |
71
|
|
|
* |
72
|
|
|
* @access protected |
73
|
|
|
* @var string |
74
|
|
|
*/ |
75
|
|
|
protected $google_search_query = ''; |
76
|
|
|
|
77
|
|
|
/** |
78
|
|
|
* Google max results query setting. |
79
|
|
|
* |
80
|
|
|
* @access protected |
81
|
|
|
* @var int |
82
|
|
|
*/ |
83
|
|
|
protected $google_max_results = 2500; |
84
|
|
|
|
85
|
|
|
/** |
86
|
|
|
* Set properties. |
87
|
|
|
* |
88
|
|
|
* @since 3.0.0 |
89
|
|
|
* |
90
|
|
|
* @param string|Calendar $calendar |
91
|
|
|
* @param bool $load_admin |
92
|
|
|
*/ |
93
|
|
|
public function __construct( $calendar = '', $load_admin = true ) { |
94
|
|
|
|
95
|
|
|
parent::__construct( $calendar ); |
96
|
|
|
|
97
|
|
|
$this->type = 'google'; |
98
|
|
|
$this->name = __( 'Google Calendar', 'google-calendar-events' ); |
99
|
|
|
|
100
|
|
|
// Google client config. |
101
|
|
|
$settings = get_option( 'simple-calendar_settings_feeds' ); |
102
|
|
|
$this->google_api_key = isset( $settings['google']['api_key'] ) ? esc_attr( $settings['google']['api_key'] ) : ''; |
103
|
|
|
$this->google_client_scopes = array( \Google_Service_Calendar::CALENDAR_READONLY ); |
104
|
|
|
$this->google_client = $this->get_client(); |
105
|
|
|
|
106
|
|
|
if ( $this->post_id > 0 ) { |
107
|
|
|
|
108
|
|
|
// Google query args. |
109
|
|
|
$this->google_calendar_id = $this->esc_google_calendar_id( get_post_meta( $this->post_id, '_google_calendar_id', true ) ); |
110
|
|
|
$this->google_events_recurring = esc_attr( get_post_meta( $this->post_id, '_google_events_recurring', true ) ); |
111
|
|
|
// note that google_search_query is used in a URL param and not as HTML output, so don't use esc_attr() on it |
112
|
|
|
$this->google_search_query = get_post_meta( $this->post_id, '_google_events_search_query', true ); |
113
|
|
|
$this->google_max_results = max( absint( get_post_meta( $this->post_id, '_google_events_max_results', true ) ), 1 ); |
114
|
|
|
|
115
|
|
|
if ( ! is_admin() || defined( 'DOING_AJAX' ) ) { |
116
|
|
|
$this->events = ! empty( $this->google_api_key ) ? $this->get_events() : array(); |
|
|
|
|
117
|
|
|
} |
118
|
|
|
} |
119
|
|
|
|
120
|
|
|
if ( is_admin() && $load_admin ) { |
121
|
|
|
$admin = new Admin( $this, $this->google_api_key, $this->google_calendar_id ); |
122
|
|
|
$this->settings = $admin->settings_fields(); |
123
|
|
|
} |
124
|
|
|
} |
125
|
|
|
|
126
|
|
|
/** |
127
|
|
|
* Decode a calendar id. |
128
|
|
|
* |
129
|
|
|
* @since 3.0.0 |
130
|
|
|
* |
131
|
|
|
* @param string $id Base64 encoded id. |
132
|
|
|
* |
133
|
|
|
* @return string |
134
|
|
|
*/ |
135
|
|
|
public function esc_google_calendar_id( $id ) { |
136
|
|
|
return base64_decode( $id ); |
137
|
|
|
} |
138
|
|
|
|
139
|
|
|
/** |
140
|
|
|
* Get events feed. |
141
|
|
|
* |
142
|
|
|
* Normalizes Google data into a standard array object to list events. |
143
|
|
|
* |
144
|
|
|
* @since 3.0.0 |
145
|
|
|
* |
146
|
|
|
* @return string|array |
147
|
|
|
*/ |
148
|
|
|
public function get_events() { |
149
|
|
|
|
150
|
|
|
$calendar = get_transient( '_simple-calendar_feed_id_' . strval( $this->post_id ) . '_' . $this->type ); |
151
|
|
|
|
152
|
|
|
if ( empty( $calendar ) && ! empty( $this->google_calendar_id ) ) { |
153
|
|
|
|
154
|
|
|
$error = ''; |
155
|
|
|
|
156
|
|
|
try { |
157
|
|
|
$response = $this->make_request( $this->google_calendar_id ); |
158
|
|
|
} catch ( \Exception $e ) { |
159
|
|
|
$error .= $e->getMessage(); |
160
|
|
|
} |
161
|
|
|
|
162
|
|
|
if ( empty( $error ) && isset( $response['events'] ) && isset( $response['timezone'] ) ) { |
163
|
|
|
|
164
|
|
|
$calendar = array_merge( $response, array( 'events' => array() ) ); |
165
|
|
|
|
166
|
|
|
// If no timezone has been set, use calendar feed. |
167
|
|
|
if ( 'use_calendar' == $this->timezone_setting ) { |
168
|
|
|
$this->timezone = $calendar['timezone']; |
169
|
|
|
} |
170
|
|
|
|
171
|
|
|
$source = isset( $response['title'] ) ? sanitize_text_field( $response['title'] ) : ''; |
172
|
|
|
|
173
|
|
|
if ( ! empty( $response['events'] ) && is_array( $response['events'] ) ) { |
174
|
|
|
foreach ( $response['events'] as $event ) { |
175
|
|
|
if ( $event instanceof \Google_Service_Calendar_Event ) { |
176
|
|
|
|
177
|
|
|
// Visibility and status. |
178
|
|
|
// Public calendars may have private events which can't be properly accessed by simple api key method. |
179
|
|
|
// Also want to skip cancelled events (single occurences deleted from repeating events) |
180
|
|
|
$visibility = $event->getVisibility(); |
181
|
|
|
$status = $event->getStatus(); |
182
|
|
|
if ( $this->type == 'google' && ( $visibility == 'private' || $visibility == 'confidential' || $status == 'cancelled' ) ) { |
183
|
|
|
continue; |
184
|
|
|
} |
185
|
|
|
|
186
|
|
|
// Event title & description. |
187
|
|
|
$title = strip_tags( $event->getSummary() ); |
188
|
|
|
$title = sanitize_text_field( iconv( mb_detect_encoding( $title, mb_detect_order(), true ), 'UTF-8', $title ) ); |
189
|
|
|
$description = wp_kses_post( iconv( mb_detect_encoding( $event->getDescription(), mb_detect_order(), true ), 'UTF-8', $event->getDescription() ) ); |
190
|
|
|
|
191
|
|
|
$whole_day = false; |
192
|
|
|
|
193
|
|
|
// Event start properties. |
194
|
|
View Code Duplication |
if( 'use_calendar' == $this->timezone_setting ) { |
|
|
|
|
195
|
|
|
$start_timezone = ! $event->getStart()->timeZone ? $calendar['timezone'] : $event->getStart()->timeZone; |
196
|
|
|
} else { |
197
|
|
|
$start_timezone = $this->timezone; |
198
|
|
|
} |
199
|
|
|
|
200
|
|
|
if ( is_null( $event->getStart()->dateTime ) ) { |
201
|
|
|
// Whole day event. |
202
|
|
|
$date = Carbon::parse( $event->getStart()->date ); |
203
|
|
|
$google_start = Carbon::createFromDate( $date->year, $date->month, $date->day, $start_timezone )->startOfDay()->addSeconds( 59 ); |
204
|
|
|
$google_start_utc = Carbon::createFromDate( $date->year, $date->month, $date->day, 'UTC' )->startOfDay()->addSeconds( 59 ); |
205
|
|
|
$whole_day = true; |
206
|
|
View Code Duplication |
} else { |
|
|
|
|
207
|
|
|
$date = Carbon::parse( $event->getStart()->dateTime ); |
208
|
|
|
|
209
|
|
|
// Check if there is an event level timezone |
210
|
|
|
if( $event->getStart()->timeZone && 'use_calendar' == $this->timezone_setting ) { |
211
|
|
|
|
212
|
|
|
// Get the two different times with the separate timezones so we can check the offsets next |
213
|
|
|
$google_start1 = Carbon::create( $date->year, $date->month, $date->day, $date->hour, $date->minute, $date->second, $date->timezone ); |
214
|
|
|
$google_start2 = Carbon::create( $date->year, $date->month, $date->day, $date->hour, $date->minute, $date->second, $event->getStart()->timeZone ); |
215
|
|
|
|
216
|
|
|
// Get the offset in hours |
217
|
|
|
$offset1 = $google_start1->offsetHours; |
218
|
|
|
$offset2 = $google_start2->offsetHours; |
219
|
|
|
|
220
|
|
|
// Get the difference between the two timezones |
221
|
|
|
$total_offset = ( $offset2 - $offset1 ); |
222
|
|
|
|
223
|
|
|
// Add the hours offset to the date hour |
224
|
|
|
$date->hour += $total_offset; |
225
|
|
|
} |
226
|
|
|
|
227
|
|
|
$google_start = Carbon::create( $date->year, $date->month, $date->day, $date->hour, $date->minute, $date->second, $start_timezone ); |
228
|
|
|
$google_start_utc = Carbon::create( $date->year, $date->month, $date->day, $date->hour, $date->minute, $date->second, 'UTC' ); |
229
|
|
|
|
230
|
|
|
$this->timezone = $start_timezone; |
231
|
|
|
} |
232
|
|
|
// Start. |
233
|
|
|
$start = $google_start->getTimestamp(); |
234
|
|
|
// Start UTC. |
235
|
|
|
$start_utc = $google_start_utc->getTimestamp(); |
236
|
|
|
|
237
|
|
|
$end = $end_utc = $end_timezone = ''; |
238
|
|
|
$span = 0; |
239
|
|
|
if ( false == $event->getEndTimeUnspecified() ) { |
240
|
|
|
|
241
|
|
|
// Event end properties. |
242
|
|
View Code Duplication |
if( 'use_calendar' == $this->timezone_setting ) { |
|
|
|
|
243
|
|
|
$end_timezone = ! $event->getEnd()->timeZone ? $calendar['timezone'] : $event->getEnd()->timeZone; |
244
|
|
|
} else { |
245
|
|
|
$end_timezone = $this->timezone; |
246
|
|
|
} |
247
|
|
|
|
248
|
|
|
if ( is_null( $event->getEnd()->dateTime ) ) { |
249
|
|
|
// Whole day event. |
250
|
|
|
$date = Carbon::parse( $event->getEnd()->date ); |
251
|
|
|
$google_end = Carbon::createFromDate( $date->year, $date->month, $date->day, $end_timezone )->startOfDay()->subSeconds( 59 ); |
252
|
|
|
$google_end_utc = Carbon::createFromDate( $date->year, $date->month, $date->day, 'UTC' )->startOfDay()->subSeconds( 59 ); |
253
|
|
View Code Duplication |
} else { |
|
|
|
|
254
|
|
|
$date = Carbon::parse( $event->getEnd()->dateTime ); |
255
|
|
|
|
256
|
|
|
// Check if there is an event level timezone |
257
|
|
|
if( $event->getEnd()->timeZone && 'use_calendar' == $this->timezone_setting ) { |
258
|
|
|
|
259
|
|
|
// Get the two different times with the separate timezones so we can check the offsets next |
260
|
|
|
$google_start1 = Carbon::create( $date->year, $date->month, $date->day, $date->hour, $date->minute, $date->second, $date->timezone ); |
261
|
|
|
$google_start2 = Carbon::create( $date->year, $date->month, $date->day, $date->hour, $date->minute, $date->second, $event->getEnd()->timeZone ); |
262
|
|
|
|
263
|
|
|
// Get the offset in hours |
264
|
|
|
$offset1 = $google_start1->offsetHours; |
265
|
|
|
$offset2 = $google_start2->offsetHours; |
266
|
|
|
|
267
|
|
|
// Get the difference between the two timezones |
268
|
|
|
$total_offset = ( $offset2 - $offset1 ); |
269
|
|
|
|
270
|
|
|
// Add the hours offset to the date hour |
271
|
|
|
$date->hour += $total_offset; |
272
|
|
|
} |
273
|
|
|
|
274
|
|
|
$google_end = Carbon::create( $date->year, $date->month, $date->day, $date->hour, $date->minute, $date->second, $end_timezone ); |
275
|
|
|
$google_end_utc = Carbon::create( $date->year, $date->month, $date->day, $date->hour, $date->minute, $date->second, 'UTC' ); |
276
|
|
|
} |
277
|
|
|
// End. |
278
|
|
|
$end = $google_end->getTimestamp(); |
279
|
|
|
// End UTC. |
280
|
|
|
$end_utc = $google_end_utc->getTimestamp(); |
281
|
|
|
|
282
|
|
|
// Count multiple days. |
283
|
|
|
$span = $google_start->diffInDays( $google_end ); |
284
|
|
|
|
285
|
|
|
if ( $span == 0 ) { |
286
|
|
|
if ( ( $google_start->toDateString() !== $google_end->toDateString() ) && $google_end->toTimeString() != '00:00:00' ) { |
287
|
|
|
$span = 1; |
288
|
|
|
} |
289
|
|
|
} |
290
|
|
|
} |
291
|
|
|
|
292
|
|
|
// Multiple days. |
293
|
|
|
$multiple_days = $span > 0 ? $span : false; |
294
|
|
|
|
295
|
|
|
// Google cannot have two different locations for start and end time. |
296
|
|
|
$start_location = $end_location = $event->getLocation(); |
297
|
|
|
|
298
|
|
|
// Recurring event. |
299
|
|
|
$recurrence = $event->getRecurrence(); |
300
|
|
|
$recurring_id = $event->getRecurringEventId(); |
301
|
|
|
if ( ! $recurrence && $recurring_id ) { |
302
|
|
|
$recurrence = true; |
303
|
|
|
} |
304
|
|
|
|
305
|
|
|
// Event link. |
306
|
|
|
if ( 'use_calendar' == $this->timezone_setting ) { |
307
|
|
|
$link = add_query_arg( array( 'ctz' => $this->timezone ), $event->getHtmlLink() ); |
308
|
|
|
} else { |
309
|
|
|
$link = $event->getHtmlLink(); |
310
|
|
|
} |
311
|
|
|
|
312
|
|
|
// Build the event. |
313
|
|
|
$calendar['events'][ intval( $start ) ][] = array( |
314
|
|
|
'type' => 'google-calendar', |
315
|
|
|
'source' => $source, |
316
|
|
|
'title' => $title, |
317
|
|
|
'description' => $description, |
318
|
|
|
'link' => $link, |
319
|
|
|
'visibility' => $visibility, |
320
|
|
|
'uid' => $event->id, |
321
|
|
|
'ical_id' => $event->getICalUID(), |
322
|
|
|
'calendar' => $this->post_id, |
323
|
|
|
'timezone' => $this->timezone, |
324
|
|
|
'start' => $start, |
325
|
|
|
'start_utc' => $start_utc, |
326
|
|
|
'start_timezone' => $start_timezone, |
327
|
|
|
'start_location' => $start_location, |
328
|
|
|
'end' => $end, |
329
|
|
|
'end_utc' => $end_utc, |
330
|
|
|
'end_timezone' => $end_timezone, |
331
|
|
|
'end_location' => $end_location, |
332
|
|
|
'whole_day' => $whole_day, |
333
|
|
|
'multiple_days' => $multiple_days, |
334
|
|
|
'recurrence' => $recurrence, |
335
|
|
|
'template' => $this->events_template, |
336
|
|
|
); |
337
|
|
|
|
338
|
|
|
} |
339
|
|
|
} |
340
|
|
|
|
341
|
|
|
if ( ! empty( $calendar['events'] ) ) { |
342
|
|
|
|
343
|
|
|
ksort( $calendar['events'], SORT_NUMERIC ); |
344
|
|
|
|
345
|
|
|
set_transient( |
346
|
|
|
'_simple-calendar_feed_id_' . strval( $this->post_id ) . '_' . $this->type, |
347
|
|
|
$calendar, |
348
|
|
|
max( absint( $this->cache ), 1 ) // Since a value of 0 means forever we set the minimum here to 1 if the user has set it to be 0 |
349
|
|
|
); |
350
|
|
|
} |
351
|
|
|
} |
352
|
|
|
|
353
|
|
|
} else { |
354
|
|
|
|
355
|
|
|
$message = __( 'While trying to retrieve events, Google returned an error:', 'google-calendar-events' ); |
356
|
|
|
$message .= '<br><br>' . $error . '<br><br>'; |
357
|
|
|
$message .= __( 'Please ensure that both your Google Calendar ID and API Key are valid and that the Google Calendar you want to display is public.', 'google-calendar-events' ) . '<br><br>'; |
358
|
|
|
$message .= __( 'Only you can see this notice.', 'google-calendar-events' ); |
359
|
|
|
|
360
|
|
|
return $message; |
361
|
|
|
} |
362
|
|
|
|
363
|
|
|
} |
364
|
|
|
|
365
|
|
|
// If no timezone has been set, use calendar feed. |
366
|
|
|
if ( 'use_calendar' == $this->timezone_setting && isset( $calendar['timezone'] ) ) { |
367
|
|
|
$this->timezone = $calendar['timezone']; |
368
|
|
|
} |
369
|
|
|
|
370
|
|
|
return isset( $calendar['events'] ) ? $calendar['events'] : array(); |
371
|
|
|
} |
372
|
|
|
|
373
|
|
|
/** |
374
|
|
|
* Query Google Calendar. |
375
|
|
|
* |
376
|
|
|
* @since 3.0.0 |
377
|
|
|
* |
378
|
|
|
* @param string $id A valid Google Calendar ID. |
379
|
|
|
* @param int $time_min Lower bound timestamp. |
380
|
|
|
* @param int $time_max Upper bound timestamp. |
381
|
|
|
* |
382
|
|
|
* @return array |
383
|
|
|
* |
384
|
|
|
* @throws \Exception On request failure will throw an exception from Google. |
385
|
|
|
*/ |
386
|
|
|
public function make_request( $id = '', $time_min = 0, $time_max = 0 ) { |
387
|
|
|
|
388
|
|
|
$calendar = array(); |
389
|
|
|
$google = $this->get_service(); |
390
|
|
|
|
391
|
|
|
if ( ! is_null( $google ) && ! empty( $id ) ) { |
392
|
|
|
|
393
|
|
|
// Build the request args. |
394
|
|
|
$args = array(); |
395
|
|
|
|
396
|
|
|
// Expand recurring events. |
397
|
|
|
if ( $this->google_events_recurring == 'show' ) { |
398
|
|
|
$args['singleEvents'] = true; |
399
|
|
|
} |
400
|
|
|
|
401
|
|
|
// Query events using search terms. |
402
|
|
|
if ( ! empty( $this->google_search_query ) ) { |
403
|
|
|
$args['q'] = rawurlencode( $this->google_search_query ); |
404
|
|
|
} |
405
|
|
|
|
406
|
|
|
// Max results to query. |
407
|
|
|
$args['maxResults'] = strval( min( absint( $this->google_max_results ), 2500 ) ); |
408
|
|
|
|
409
|
|
|
// Specify a timezone. |
410
|
|
|
$timezone = ''; |
411
|
|
|
if ( 'use_calendar' != get_post_meta( $this->post_id, '_feed_timezone_setting', true ) ) { |
412
|
|
|
$args['timeZone'] = $timezone = $this->timezone; |
413
|
|
|
} |
414
|
|
|
|
415
|
|
|
// Lower bound (inclusive) for an event's end time to filter by. |
416
|
|
|
$earliest_event = intval( $this->time_min ); |
417
|
|
|
if ( $earliest_event > 0 ) { |
418
|
|
|
$timeMin = Carbon::now(); |
419
|
|
|
if ( ! empty( $timezone ) ) { |
420
|
|
|
$timeMin->setTimezone( $timezone ); |
421
|
|
|
} |
422
|
|
|
$timeMin->setTimestamp( $earliest_event ); |
423
|
|
|
$args['timeMin'] = $timeMin->toRfc3339String(); |
424
|
|
|
} |
425
|
|
|
|
426
|
|
|
// Upper bound (exclusive) for an event's start time to filter by. |
427
|
|
|
$latest_event = intval( $this->time_max ); |
428
|
|
|
if ( $latest_event > 0 ) { |
429
|
|
|
$timeMax = Carbon::now(); |
430
|
|
|
if ( ! empty( $timezone ) ) { |
431
|
|
|
$timeMax->setTimezone( $timezone ); |
432
|
|
|
} |
433
|
|
|
$timeMax->setTimestamp( $latest_event ); |
434
|
|
|
$args['timeMax'] = $timeMax->toRfc3339String(); |
435
|
|
|
} |
436
|
|
|
|
437
|
|
|
// Query events in calendar. |
438
|
|
|
$response = $google->events->listEvents( $id, $args ); |
439
|
|
|
|
440
|
|
|
if ( $response instanceof \Google_Service_Calendar_Events ) { |
441
|
|
|
$calendar = array( |
442
|
|
|
'id' => $id, |
443
|
|
|
'title' => $response->getSummary(), |
444
|
|
|
'description' => $response->getDescription(), |
445
|
|
|
'timezone' => $response->getTimeZone(), |
446
|
|
|
'url' => esc_url( '//www.google.com/calendar/embed?src=' . $id ), |
447
|
|
|
'events' => $response->getItems(), |
448
|
|
|
); |
449
|
|
|
} |
450
|
|
|
} |
451
|
|
|
|
452
|
|
|
return $calendar; |
453
|
|
|
} |
454
|
|
|
|
455
|
|
|
/** |
456
|
|
|
* Google API Client. |
457
|
|
|
* |
458
|
|
|
* @since 3.0.0 |
459
|
|
|
* @access private |
460
|
|
|
* |
461
|
|
|
* @return \Google_Client |
462
|
|
|
*/ |
463
|
|
|
private function get_client() { |
464
|
|
|
|
465
|
|
|
$client = new \Google_Client(); |
466
|
|
|
$client->setApplicationName( 'Simple Calendar' ); |
467
|
|
|
$client->setScopes( $this->google_client_scopes ); |
468
|
|
|
$client->setDeveloperKey( $this->google_api_key ); |
469
|
|
|
$client->setAccessType( 'online' ); |
470
|
|
|
|
471
|
|
|
return $client; |
472
|
|
|
} |
473
|
|
|
|
474
|
|
|
/** |
475
|
|
|
* Google Calendar Service. |
476
|
|
|
* |
477
|
|
|
* @since 3.0.0 |
478
|
|
|
* @access protected |
479
|
|
|
* |
480
|
|
|
* @return null|\Google_Service_Calendar |
481
|
|
|
*/ |
482
|
|
|
protected function get_service() { |
483
|
|
|
return $this->google_client instanceof \Google_Client ? new \Google_Service_Calendar( $this->google_client ) : null; |
484
|
|
|
} |
485
|
|
|
|
486
|
|
|
} |
487
|
|
|
|
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.
For example, imagine you have a variable
$accountId
that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to theid
property of an instance of theAccount
class. This class holds a proper account, so the id value must no longer be false.Either this assignment is in error or a type check should be added for that assignment.