Completed
Push — master ( e47c17...035b95 )
by
unknown
04:49
created

shared.php ➔ simcal_get_timezone_from_gmt_offset()   C

Complexity

Conditions 7
Paths 5

Size

Total Lines 32
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 15
nc 5
nop 1
dl 0
loc 32
rs 6.7272
c 0
b 0
f 0
1
<?php
2
/**
3
 * Shared functions
4
 *
5
 * Functions shared by both back end and front end components.
6
 *
7
 * @package SimpleCalendar/Functions
8
 */
9
10
if ( ! defined( 'ABSPATH' ) ) {
11
	exit;
12
}
13
14
/**
15
 * Check if there is a calendar.
16
 *
17
 * @since  3.0.0
18
 *
19
 * @return bool
20
 */
21
function is_simple_calendar() {
22
23
	if ( is_singular() ) {
24
25
		global $post, $post_type;
26
27
		if ( 'calendar' == $post_type ) {
28
			return true;
29
		} else {
30
			if ( false !== get_post_meta( $post->ID, '_simcal_attach_calendar_id', true ) ) {
31
				return true;
32
			}
33
			if ( has_shortcode( $post->post_content, 'calendar' ) ) {
34
				return true;
35
			}
36
		}
37
	}
38
39
	return false;
40
}
41
42
/**
43
 * Get plugin URL.
44
 *
45
 * @param  string $url
46
 *
47
 * @return string
48
 */
49
function simcal_get_url( $url ) {
50
	return \SimpleCalendar\plugin()->get_url( $url );
51
}
52
53
/**
54
 * Get events feed types.
55
 *
56
 * @since  3.0.0
57
 *
58
 * @return array
59
 */
60
function simcal_get_feed_types() {
61
	$objects = \SimpleCalendar\plugin()->objects;
62
	return $objects instanceof \SimpleCalendar\Objects ? $objects->get_feed_types() : array();
63
}
64
65
/**
66
 * Get an events feed.
67
 *
68
 * @since  3.0.0
69
 *
70
 * @param  string|int|object $object
71
 *
72
 * @return null|\SimpleCalendar\Abstracts\Feed
0 ignored issues
show
Documentation introduced by
Should the return type not be object|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
73
 */
74
function simcal_get_feed( $object ) {
75
	$objects = \SimpleCalendar\plugin()->objects;
76
	return $objects instanceof \SimpleCalendar\Objects ? $objects->get_feed( $object ) : null;
77
}
78
79
/**
80
 * Get calendar types.
81
 *
82
 * @since  3.0.0
83
 *
84
 * @return array
85
 */
86
function simcal_get_calendar_types() {
87
	$objects = \SimpleCalendar\plugin()->objects;
88
	return $objects instanceof \SimpleCalendar\Objects ? $objects->get_calendar_types() : array();
89
}
90
91
/**
92
 * Get a calendar.
93
 *
94
 * @since  3.0.0
95
 *
96
 * @param  string|int|object|WP_Post $object
97
 *
98
 * @return null|\SimpleCalendar\Abstracts\Calendar
0 ignored issues
show
Documentation introduced by
Should the return type not be object|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
99
 */
100
function simcal_get_calendar( $object ) {
101
	$objects = \SimpleCalendar\plugin()->objects;
102
	return $objects instanceof \SimpleCalendar\Objects ? $objects->get_calendar( $object ) : null;
103
}
104
105
/**
106
 * Get a calendar view.
107
 *
108
 * @since  3.0.0
109
 *
110
 * @param  int    $id
111
 * @param  string $name
112
 *
113
 * @return mixed
114
 */
115
function simcal_get_calendar_view( $id = 0, $name = '' ) {
116
	$objects = \SimpleCalendar\plugin()->objects;
117
	return $objects instanceof \SimpleCalendar\Objects ? $objects->get_calendar_view( $id, $name ) : false;
118
}
119
120
/**
121
 * Print a calendar.
122
 *
123
 * @since  3.0.0
124
 *
125
 * @param  int|object|WP_Post $object
126
 *
127
 * @return void
128
 */
129
function simcal_print_calendar( $object ) {
130
131
	$calendar = simcal_get_calendar( $object );
132
133
	if ( $calendar instanceof \SimpleCalendar\Abstracts\Calendar ) {
134
		$calendar->html();
135
	}
136
}
137
138
/**
139
 * Common scripts variables.
140
 *
141
 * Variables to print in scripts localization
142
 *
143
 * @since  3.0.0
144
 *
145
 * @return array
146
 */
147
function simcal_common_scripts_variables() {
148
149
	$vars = array(
150
		'ajax_url'  => \SimpleCalendar\plugin()->ajax_url(),
151
		'nonce'     => wp_create_nonce( 'simcal' ),
152
		'locale'    => \SimpleCalendar\plugin()->locale,
153
		'text_dir'  => is_rtl() ? 'rtl' : 'ltr',
154
		'months'    => array(
155
			'full'  => simcal_get_calendar_names_i18n( 'month', 'full' ),
156
			'short' => simcal_get_calendar_names_i18n( 'month', 'short' ),
157
		),
158
		'days'      => array(
159
			'full'  => simcal_get_calendar_names_i18n( 'day', 'full' ),
160
			'short' => simcal_get_calendar_names_i18n( 'day', 'short' ),
161
		),
162
		'meridiem' => simcal_get_calendar_names_i18n( 'meridiem' ),
163
	);
164
165
	return array_merge( $vars, apply_filters( 'simcal_common_scripts_variables', array() ) );
166
}
167
168
/**
169
 * Get feed IDs and names.
170
 *
171
 * @since  3.0.0
172
 *
173
 * @param  string|int|array $exclude Id or array of ids to drop from results.
174
 * @param  bool $cached Use cached query.
175
 *
176
 * @return array Associative array with ids as keys and feed titles as values.
177
 */
178
function simcal_get_calendars( $exclude = '', $cached = true ) {
179
180
	$calendars = get_transient( '_simple-calendar_feed_ids' );
181
182
	if ( ! $calendars || $cached === false ) {
0 ignored issues
show
introduced by
Found "=== false". Use Yoda Condition checks, you must
Loading history...
183
184
		$posts = get_posts( array(
185
			'post_type' => 'calendar',
186
			'nopaging'  => true,
187
		) );
188
189
		$calendars = array();
190
		foreach ( $posts as $post ) {
191
			$calendars[ $post->ID ] = $post->post_title;
192
		}
193
		asort( $calendars );
194
195
		set_transient( '_simple-calendar_feed_ids', $calendars, 604800 );
196
	}
197
198
	if ( ! empty( $exclude ) ) {
199
		if ( is_numeric( $exclude ) ) {
200
			unset( $calendars[ intval( $exclude ) ] );
201
		} elseif ( is_array( $exclude ) ) {
202
			array_diff_key( $calendars, array_map( 'intval', array_keys( $exclude ) ) );
203
		}
204
	}
205
206
	return $calendars;
207
}
208
209
/**
210
 * Get localized list of months or day names.
211
 *
212
 * Each day or month matches the array index (0-11 for months or 0-6 for days).
213
 *
214
 * @since  3.0.0
215
 *
216
 * @param  string $group Either 'month', 'day' or 'meridiem' names to localize.
217
 * @param  string $style Return names in 'short' or 'full' form (default full long form).
218
 *
219
 * @return array
220
 */
221
function simcal_get_calendar_names_i18n( $group, $style = 'full' ) {
222
223
	$names = array();
224
225
	if ( in_array( $group, array( 'month', 'day', 'meridiem' ) ) ) {
226
227
		$format = '';
228
		$length = 0;
229
230
		$date = \Carbon\Carbon::now();
231
232
		if ( 'month' == $group ) {
233
			$date->month( 0 )->startOfMonth();
234
			$format = 'short' == $style ? 'M' : 'F';
235
			$length = 11;
236
		} elseif ( 'day' == $group ) {
237
			$date->next( 6 );
238
			$format = 'short' == $style ? 'D' : 'l';
239
			$length = 6;
240
		} elseif ( 'meridiem' == $group ) {
241
			$date->startOfDay();
242
			$am = $date->addHour( 1 )->getTimestamp();
243
			$pm = $date->addHours( 13 )->getTimestamp();
244
			return array(
245
				'AM' => date_i18n( 'A', $am ),
246
				'am' => date_i18n( 'a', $am ),
247
				'PM' => date_i18n( 'A', $pm ),
248
				'pm' => date_i18n( 'a', $pm ),
249
			);
250
		}
251
252
		$i = 0;
253
		while ( $i <= $length ) {
254
			if ( 'month' == $group ) {
255
				$date->addMonths( 1 );
256
			} else {
257
				$date->addDays( 1 );
258
			}
259
			$names[ strval( $i ) ] = date_i18n( $format, $date->getTimestamp() );
260
			$i++;
261
		}
262
263
	}
264
265
	return $names;
266
}
267
268
/**
269
 * Default event template.
270
 *
271
 * @since  3.0.0
272
 *
273
 * @return string
274
 */
275
function simcal_default_event_template() {
276
277
	$content  = '<strong>' . '[title]' . '</strong>';
278
	$content .= "\n\n";
279
	$content .= '[when]' . "\n";
280
	$content .= '[location]';
281
	$content .= "\n";
282
	$content .= '<div>' . '[description]' . '</div>';
283
	$content .= "\n" . '[link newwindow="yes"]' . __( 'See more details', 'google-calendar-events' ) . '[/link]';
284
285
	return apply_filters( 'simcal_default_event_template', $content );
286
}
287
288
/**
289
 * Get day, month, year order in a datetime format string.
290
 *
291
 * Returns an array with d, m, y for keys and a order number.
292
 * If either d, m, y is not found in date format, order value is false.
293
 *
294
 * @since  3.0.0
295
 *
296
 * @param  string $date_format
297
 *
298
 * @return array
299
 */
300
function simcal_get_date_format_order( $date_format ) {
301
302
	$pos = array(
303
		'd' => strpos( $date_format, strpbrk( $date_format, 'Dj' ) ),
304
		'm' => strpos( $date_format, strpbrk( $date_format, 'FMmn' ) ),
305
		'y' => strpos( $date_format, strpbrk( $date_format, 'Yy' ) ),
306
	);
307
308
	// @TODO When one date piece is not found, perhaps fallback to ISO standard position.
309
310
	$order = array();
311
	foreach ( $pos as $k => $v ) {
312
		$order[ $k ] = $v;
313
	}
314
	ksort( $order );
315
316
	return $order;
317
}
318
319
/**
320
 * Get WordPress timezone setting.
321
 *
322
 * Always returns a valid timezone string even when the setting is a GMT offset.
323
 *
324
 * @since  3.0.0
325
 *
326
 * @return null|string
327
 */
328
function simcal_get_wp_timezone() {
329
330
	$timezone = get_option( 'timezone_string' );
331
332
	if ( empty( $timezone ) ) {
333
		$gmt = get_option( 'gmt_offset' );
334
		$timezone = simcal_get_timezone_from_gmt_offset( $gmt );
335
	}
336
337
	return $timezone;
338
}
339
340
/**
341
 * Get a timezone from a GMT offset.
342
 *
343
 * Converts a numeric offset into a valid timezone string.
344
 *
345
 * @since  3.0.0
346
 *
347
 * @param  string|float $offset
348
 *
349
 * @return null|string
350
 */
351
function simcal_get_timezone_from_gmt_offset( $offset ) {
352
353
	if ( is_numeric( $offset ) ) {
354
355
		if ( 0 === intval( $offset ) ) {
356
			return 'UTC';
357
		} else {
358
			$offset = floatval( $offset ) * 3600;
359
		}
360
361
		$timezone = timezone_name_from_abbr( null, $offset, false );
362
		// This is buggy and might return false:
363
		// @see http://php.net/manual/en/function.timezone-name-from-abbr.php#86928
364
		// Therefore:
365
		if ( false == $timezone ) {
366
367
			$list = timezone_abbreviations_list();
368
			foreach ( $list as $abbr ) {
369
				foreach ( $abbr as $city ) {
370
					if ( $offset == $city['offset'] ) {
371
						return $city['timezone_id'];
372
					}
373
				}
374
			}
375
376
		}
377
378
		return $timezone;
379
	}
380
381
	return null;
382
}
383
384
/**
385
 * Convert a timezone string to a numeric offset.
386
 *
387
 * @since  3.0.0
388
 *
389
 * @param  string $timezone
390
 *
391
 * @return int Unix time offset
392
 */
393
function simcal_get_timezone_offset( $timezone ) {
394
	return \Carbon\Carbon::now( $timezone )->offset;
395
}
396
397
/**
398
 * Escape timezone string.
399
 *
400
 * @since  3.0.0
401
 *
402
 * @param  string $tz
403
 * @param  mixed  $default
404
 *
405
 * @return mixed|string
406
 */
407
function simcal_esc_timezone( $tz, $default = 'UTC' ) {
408
	return in_array( $tz, timezone_identifiers_list() ) ? $tz : $default;
409
}
410
411
/**
412
 * Clear feed transients cache.
413
 *
414
 * @since  3.0.0
415
 *
416
 * @param  string|int|array|\WP_Post $id
417
 *
418
 * @return bool
419
 */
420
function simcal_delete_feed_transients( $id = '' ) {
421
422
	$grouped_ids = get_post_meta( $id, '_grouped_calendars_ids', true );
423
424
	// If there are group IDs we need to construct an array to pass along with the grouped IDs + the original $post_id
425
	if ( is_array( $grouped_ids ) ) {
426
		$temp_id = $id;
427
		$id = $grouped_ids;
428
		$id[] = $temp_id;
429
	}
430
431
	if ( is_numeric( $id ) ) {
432
		$id = intval( $id ) > 0 ? absint( $id ) : simcal_get_calendars();
433
	} elseif ( $id instanceof WP_Post ) {
434
		$id = $id->ID;
435
	} elseif ( is_array( $id ) ) {
436
		$id = array_map( 'absint', $id );
437
	} else {
438
		$id = simcal_get_calendars( '', true );
439
	}
440
441
	$feed_types = simcal_get_feed_types();
442
443
	if ( is_array( $id ) ) {
444
445
		$posts = get_posts( array(
446
				'post_type' => 'calendar',
447
				'fields'    => 'ids',
448
				'post__in'  => $id,
449
				'nopaging'  => true,
450
		) );
451
452
		foreach ( $posts as $post ) {
453
			$calendar = simcal_get_calendar( $post );
454
			if ( $calendar instanceof \SimpleCalendar\Abstracts\Calendar ) {
455
				foreach ( $feed_types as $feed_type ) {
456
					delete_transient( '_simple-calendar_feed_id_' . strval( $calendar->id ) . '_' . $feed_type );
457
				}
458
			}
459
		}
460
461
	} else {
462
463
		$post = get_post( $id );
0 ignored issues
show
introduced by
Overridding WordPress globals is prohibited
Loading history...
464
		$calendar = simcal_get_calendar( $post );
465
		if ( $calendar instanceof \SimpleCalendar\Abstracts\Calendar ) {
466
			foreach ( $feed_types as $feed_type ) {
467
				delete_transient( '_simple-calendar_feed_id_' . strval( $calendar->id ) . '_' . $feed_type );
468
			}
469
		}
470
	}
471
472
	return delete_transient( '_simple-calendar_feed_ids' );
473
}