PluginProbe
Radio Station by netmix® – Manage and play your Show Schedule in WordPress! / 2.7.1
Radio Station by netmix® – Manage and play your Show Schedule in WordPress! v2.7.1
2.7.1 trunk 2.2.6 2.2.7 2.2.8 2.3.0 2.3.1 2.3.2 2.3.3 2.3.3.1 2.3.3.2 2.3.3.3 2.3.3.4 2.3.3.5 2.3.3.6 2.3.3.7 2.3.3.8 2.3.3.9 2.4.0 2.4.0.3 2.4.0.4 2.4.0.5 2.4.0.6 2.4.0.7 2.4.0.8 All 44 releases
radio-station / radio-station.php

radio-station.php in Radio Station by netmix® – Manage and play your Show Schedule in WordPress! 2.7.1, at radio-station.php

1,329 lines 47.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /*
4
5 Plugin Name: Radio Station
6 Plugin URI: https://radiostation.pro/radio-station
7 Description: Adds Show pages, DJ role, playlist and on-air programming functionality to your site.
8 Author: Tony Zeoli, Tony Hayes
9 Version: 2.7.1
10 Requires at least: 3.3.1
11 Text Domain: radio-station
12 Domain Path: /languages
13 Author URI: https://netmix.com/
14 GitHub Plugin URI: netmix/radio-station
15
16 Copyright 2019 Digital Strategy Works (email : info@digitalstrategyworks.com)
17
18 This program is free software; you can redistribute it and/or modify
19 it under the terms of the GNU General Public License, version 2, as
20 published by the Free Software Foundation.
21
22 This program is distributed in the hope that it will be useful,
23 but WITHOUT ANY WARRANTY; without even the implied warranty of
24 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 GNU General Public License for more details.
26
27 You should have received a copy of the GNU General Public License
28 along with this program; if not, write to the Free Software
29 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
30 */
31
32 if ( !defined( 'ABSPATH' ) ) exit;
33
34 // === Plugin Setup ===
35 // - Define Plugin Constants
36 // - Set Debug Mode Constant
37 // - Define Plugin Data Slugs
38 // - Include Plugin Files
39 // - Plugin Options and Defaults
40 // - Plugin Loader Settings
41 // - Bundle Plan Settings Filter
42 // - Start Plugin Loader Instance
43 // - Include Plugin Admin Files
44 // - Load Plugin Text Domain
45 // x Add Pricing Page Path Filter
46 // x Freemius Pricing Page Path Filter
47 // === Plugin Functions ===
48 // - Check Plan Options
49 // - Check Plugin Version
50 // - Plugin Activation Action
51 // x Activation Welcome Redirect
52 // - Plugin Deactivation Action
53 // - Filter Plugin Updates Transient
54 // - Filter Freemius Plugin Icon Path
55 // - Set Allowed Origins for Radio Player
56 // === Resource Handling ===
57 // - Enqueue Plugin Scripts
58 // - Register Moment JS
59 // - Enqueue Plugin Script
60 // - Add Inline Script
61 // - Enqueue Footer Scripts
62 // x Print Admin Footer Scripts
63 // - Enqueue Plugin Stylesheet
64 // - Add Inline Style
65 // - Enqueue Footer Styles
66 // x Print Admin Footer Styles
67 // - Print Missed Footer Resources
68 // - Enqueue Datepicker
69 // - Enqueue Localized Script Values
70 // - Localization Script
71 // - Filter Streaming Data
72 // - Filter Player Script
73 // === Transient Caching ===
74 // - Delete Prefixed Transients
75 // - Clear Cached Data
76 // - Clear Cache on Status Transitions
77 // === Debugging ===
78 // - maybe Clear Transient Data
79 // - Debug Output and Logging
80 // - Freemius Object Debug
81
82
83 // --------------------
84 // === Plugin Setup ===
85 // --------------------
86
87 // -----------------------
88 // Define Plugin Constants
89 // -----------------------
90 // 2.3.1: added constant for Netmix Directory
91 // 2.4.0.3: remove separate constant for API docs link
92 // 2.4.0.3: update home URLs to radiostation.pro
93 // 2.4.0.8: added RADIO_STATION_SLUG constant
94 // 2.5.0: added RADIO_STATION_PATREON constant
95 define( 'RADIO_STATION_SLUG', 'radio-station' );
96 define( 'RADIO_STATION_FILE', __FILE__ );
97 define( 'RADIO_STATION_DIR', dirname( __FILE__ ) );
98 define( 'RADIO_STATION_BASENAME', plugin_basename( __FILE__ ) );
99 define( 'RADIO_STATION_HOME_URL', 'https://radiostation.pro/radio-station/' );
100 define( 'RADIO_STATION_DOCS_URL', 'https://radiostation.pro/docs/' );
101 // define( 'RADIO_STATION_API_DOCS_URL', 'https://radiostation.pro/docs/api/' );
102 define( 'RADIO_STATION_PRO_URL', 'https://radiostation.pro/' );
103 define( 'RADIO_STATION_NETMIX_DIR', 'https://netmix.com/' );
104 define( 'RADIO_STATION_PATREON', 'https://patreon.com/radiostation' );
105
106 // ------------------------
107 // Define Plugin Data Slugs
108 // ------------------------
109 define( 'RADIO_STATION_LANGUAGES_SLUG', 'rs-languages' );
110 define( 'RADIO_STATION_HOST_SLUG', 'rs-host' );
111 define( 'RADIO_STATION_PRODUCER_SLUG', 'rs-producer' );
112
113 // --- check and define CPT slugs ---
114 // TODO: prefix original slugs and update post/taxonomy data
115 if ( get_option( 'radio_show_cpts_prefixed' ) ) {
116 define( 'RADIO_STATION_SHOW_SLUG', 'rs-show' );
117 define( 'RADIO_STATION_PLAYLIST_SLUG', 'rs-playlist' );
118 define( 'RADIO_STATION_OVERRIDE_SLUG', 'rs-override' );
119 define( 'RADIO_STATION_GENRES_SLUG', 'rs-genres' );
120 } else {
121 define( 'RADIO_STATION_SHOW_SLUG', 'show' );
122 define( 'RADIO_STATION_PLAYLIST_SLUG', 'playlist' );
123 define( 'RADIO_STATION_OVERRIDE_SLUG', 'override' );
124 define( 'RADIO_STATION_GENRES_SLUG', 'genres' );
125 }
126
127 // -----------------------
128 // Set Debug Mode Constant
129 // -----------------------
130 // 2.3.0: added debug mode constant
131 // 2.3.2: added saving debug mode constant
132 if ( !defined( 'RADIO_STATION_DEBUG' ) ) {
133 // 2.5.0: use simplified single line condition
134 $rs_debug = ( isset( $_REQUEST['rs-debug'] ) && ( '1' === sanitize_text_field( $_REQUEST['rs-debug'] ) ) ) ? true : false;
135 define( 'RADIO_STATION_DEBUG', $rs_debug );
136 }
137 if ( !defined( 'RADIO_STATION_SAVE_DEBUG' ) ) {
138 // 2.5.0: use simplified single line condition
139 $rs_save_debug = ( isset( $_REQUEST['rs-save-debug'] ) && ( '1' === sanitize_text_field( $_REQUEST['rs-save-debug'] ) ) ) ? true : false;
140 define( 'RADIO_STATION_SAVE_DEBUG', $rs_save_debug );
141 }
142
143 // --------------------
144 // Include Plugin Files
145 // --------------------
146 // 2.3.0: include new data feeds file
147 // 2.3.0: renamed widget files to match new widget names
148 // 2.3.0: separate file for legacy support functions
149 // 2.5.0: moved templates and user roles to separate include files
150 // 2.5.0: moved times and schedules to separate include files
151
152 // --- Main Includes ---
153 require RADIO_STATION_DIR . '/includes/support-functions.php';
154 require RADIO_STATION_DIR . '/includes/post-types.php';
155 require RADIO_STATION_DIR . '/includes/templates.php';
156 require RADIO_STATION_DIR . '/includes/user-roles.php';
157 require RADIO_STATION_DIR . '/includes/data-feeds.php';
158 require RADIO_STATION_DIR . '/includes/legacy.php';
159
160 // --- Player ---
161 // 2.4.0.4: include player as standard
162 require RADIO_STATION_DIR . '/player/radio-player.php';
163
164 // --- Scheduler ---
165 // note: keep this load order as schedules instantiates schedule engine class
166 require RADIO_STATION_DIR . '/scheduler/schedule-engine.php';
167 require RADIO_STATION_DIR . '/includes/schedules.php';
168 require RADIO_STATION_DIR . '/includes/times.php';
169
170 // --- Shortcodes ---
171 require RADIO_STATION_DIR . '/includes/master-schedule.php';
172 require RADIO_STATION_DIR . '/includes/shortcodes.php';
173
174 // --- Widgets ---
175 // 2.3.1: added radio player widget file
176 // 2.4.0.4: move player widget here
177 // 2.5.0: move widget classes to widgets directory
178 require RADIO_STATION_DIR . '/widgets/class-current-show-widget.php';
179 require RADIO_STATION_DIR . '/widgets/class-upcoming-shows-widget.php';
180 require RADIO_STATION_DIR . '/widgets/class-current-playlist-widget.php';
181 require RADIO_STATION_DIR . '/widgets/class-radio-clock-widget.php';
182 require RADIO_STATION_DIR . '/widgets/class-radio-player-widget.php';
183
184 // --- Blocks ---
185 // 2.5.0: added for registering block types
186 if ( function_exists( 'register_block_type' ) ) {
187 require RADIO_STATION_DIR . '/includes/blocks.php';
188 }
189
190 // --- Feature Development ---
191 // 2.3.0: add feature branch development includes
192 $features = array( 'import-export' );
193 foreach ( $features as $feature ) {
194 $filepath = RADIO_STATION_DIR . '/includes/' . $feature . '.php';
195 if ( file_exists( $filepath ) ) {
196 include $filepath;
197 }
198 }
199
200 // --- Backwards Compatible Player ---
201 // 2.5.1: add player backwards compatible functions
202 add_action( 'plugins_loaded', 'radio_station_back_compat_player' );
203 function radio_station_back_compat_player() {
204 $back_compat = apply_filters( 'radio_station_back_compat_player', true );
205 if ( $back_compat ) {
206 include RADIO_STATION_DIR . '/player/compat.php';
207 }
208 }
209
210
211 // ---------------------------
212 // Plugin Options and Defaults
213 // ---------------------------
214 // 2.3.0: added plugin options
215 // 2.4.0.8: moved options array to separate file
216 // 2.5.0: move plan options check to separate function
217 // 2.5.18: get options via function
218 require RADIO_STATION_DIR . '/options.php';
219 $plan_options = radio_station_check_plan_options();
220 $options = radio_station_plugin_options();
221
222 // ----------------------
223 // Plugin Loader Settings
224 // ----------------------
225 // 2.3.0: added plugin loader settings
226 // 2.4.0.8: use RADIO_STATION_SLUG constant
227
228 // --- settings array ---
229 $settings = array(
230 // --- Plugin Info ---
231 'slug' => RADIO_STATION_SLUG,
232 'file' => RADIO_STATION_FILE,
233 'version' => '0.0.1',
234
235 // --- Menus and Links ---
236 'title' => 'Radio Station',
237 'parentmenu' => RADIO_STATION_SLUG,
238 'home' => RADIO_STATION_HOME_URL,
239 'docs' => RADIO_STATION_DOCS_URL,
240 'support' => 'https://github.com/netmix/radio-station/issues/',
241 'share' => RADIO_STATION_HOME_URL . '#share',
242 'donate' => 'https://patreon.com/radiostation',
243 'readme' => false,
244 'settingsmenu' => false,
245
246 // --- Options ---
247 'namespace' => 'radio_station',
248 'settings' => 'rs',
249 'option' => 'radio_station',
250 'options' => $options,
251
252 // --- WordPress.Org ---
253 'wporgslug' => RADIO_STATION_SLUG,
254 'wporg' => true,
255 'textdomain' => 'radio-station',
256
257 // --- Freemius ---
258 // 2.4.0.1: turn on addons switch for Pro
259 // 2.4.0.3: turn on plans switch for Pro also
260 // 2.4.0.3: set Pro details and Upgrade links
261 // 2.4.0.4: change upgrade_link to -upgrade
262 // 2.5.6: added affiliation selected key
263 'freemius_id' => '4526',
264 'freemius_key' => 'pk_aaf375c4fb42e0b5b3831e0b8476b',
265 'hasplans' => $plan_options['has_plans'],
266 'upgrade_link' => add_query_arg( 'page', RADIO_STATION_SLUG . '-pricing', admin_url( 'admin.php' ) ),
267 'pro_link' => RADIO_STATION_PRO_URL . 'pricing/',
268 'hasaddons' => $plan_options['has_addons'],
269 'addons_link' => add_query_arg( 'page', RADIO_STATION_SLUG . '-addons', admin_url( 'admin.php' ) ),
270 'plan' => $plan_options['plan_type'],
271 'affiliation' => 'selected',
272
273 );
274
275 // ---------------------
276 // Settings Text Filters
277 // ---------------------
278 // 2.5.18: added to avoid translations loading early
279 add_filter( 'radio_station_admin_args', 'radio_station_settings_texts' );
280 function radio_station_settings_texts( $args ) {
281 $texts = array(
282 'sharetext' => __( 'Share the Plugin Love', 'radio-station' ),
283 'ratetext' => __( 'Rate on WordPress.org', 'radio-station' ),
284 'donatetext' => __( 'Support this Plugin', 'radio-station' ),
285 );
286 $args = array_merge( $args, $texts );
287 return $args;
288 }
289
290 // ---------------------------
291 // Bundle Plan Settings Filter
292 // ---------------------------
293 // 2.5.0: added for bundle pricing configuration
294 add_filter( 'freemius_init_settings_radio_station', 'radio_station_freemius_bundle_config' );
295 function radio_station_freemius_bundle_config( $settings ) {
296 // 2.4.0.6: add bundles configuration
297 $settings['bundle_id'] = '9521';
298 $settings['bundle_public_key'] = 'pk_a2650f223ef877e87fe0fdfc4442b';
299 $settings['bundle_license_auto_activation'] = true;
300 return $settings;
301 }
302
303 // -------------------------
304 // Set Plugin Option Globals
305 // -------------------------
306 global $radio_station_data;
307 $radio_station_data['channel'] = '';
308 $radio_station_data['options'] = $options;
309 $radio_station_data['settings'] = $settings;
310 if ( RADIO_STATION_DEBUG ) {
311 echo '<span style="display:none;">Radio Station Settings: ' . esc_html( print_r( $settings, true ) ) . '</span>';
312 }
313
314 // ----------------------------
315 // Start Plugin Loader Instance
316 // ----------------------------
317 require RADIO_STATION_DIR . '/loader.php';
318 $rs_instance = new radio_station_loader( $settings );
319
320
321 // --------------------------
322 // Include Plugin Admin Files
323 // --------------------------
324 // 2.2.7: added conditional load of admin includes
325 // 2.2.7: moved all admin functions to radio-station-admin.php
326 if ( is_admin() ) {
327
328 // --- Admin Includes ---
329 require RADIO_STATION_DIR . '/radio-station-admin.php';
330 require RADIO_STATION_DIR . '/includes/post-types-admin.php';
331 require RADIO_STATION_DIR . '/includes/onboarding.php';
332
333 // --- Contextual Help ---
334 // 2.3.0: maybe load contextual help config
335 if ( file_exists( RADIO_STATION_DIR . '/help/contextual-help-config.php' ) ) {
336 include RADIO_STATION_DIR . '/help/contextual-help-config.php';
337 }
338 }
339
340 // -----------------------
341 // Load Plugin Text Domain
342 // -----------------------
343 // 2.5.13: change plugins_loaded hook for load_plugin_textdomain
344 add_action( 'init', 'radio_station_init' );
345 function radio_station_init() {
346 // 2.3.0: use RADIO_STATION_DIR constant
347 load_plugin_textdomain( 'radio-station', false, RADIO_STATION_DIR . '/languages' );
348 }
349
350 // ----------------------------
351 // Add Pricing Page Path Filter
352 // ----------------------------
353 // 2.5.0: added for Freemius Pricing Page v2
354 // 2.5.18: disabled as since included in Freemius by default
355 // add_action( 'radio_station_loaded', 'radio_station_add_pricing_path_filter' );
356 // function radio_station_add_pricing_path_filter() {
357 // global $radio_station_freemius;
358 // if ( method_exists( $radio_station_freemius, 'add_filter' ) ) {
359 // $radio_station_freemius->add_filter( 'freemius_pricing_js_path', 'radio_station_pricing_page_path' );
360 // }
361 // }
362
363 // ---------------------------------
364 // Freemius Pricing Page Path Filter
365 // ---------------------------------
366 // 2.5.0: added for Freemius Pricing Page v2
367 // 2.5.18: disabled as since included in Freemius by default
368 // function radio_station_pricing_page_path( $default_pricing_js_path ) {
369 // $suffix = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) || RADIO_STATION_DEBUG ? '' : '.min';
370 // return RADIO_STATION_DIR . '/freemius-pricing/freemius-pricing' . $suffix . '.js';
371 // }
372
373
374 // ------------------------
375 // === Plugin Functions ===
376 // ------------------------
377
378 // ------------------
379 // Check Plan Options
380 // ------------------
381 // 2.5.0: moved to separate function
382 function radio_station_check_plan_options() {
383
384 // 2.4.0.3: added check active/installed Pro version
385 // 2.4.0.4: add defaults for has_addons and has_plans
386 $has_addons = false;
387 $has_plans = true;
388 $plan = 'free';
389
390 // --- check for deactivated pro plugin ---
391 // 2.4.0.4: remove unnecessary second argument to wp_cache_get
392 $plugins = wp_cache_get( 'plugins' );
393 if ( !$plugins ) {
394 if ( !function_exists( 'get_plugins' ) ) {
395 $admin_plugins = ABSPATH . 'wp-admin/includes/plugin.php';
396 if ( file_exists( $admin_plugins ) ) {
397 include_once $admin_plugins;
398 }
399 }
400 $plugins = get_plugins();
401 }
402 if ( $plugins && is_array( $plugins ) && ( count( $plugins ) > 0 ) ) {
403 foreach ( $plugins as $slug => $plugin ) {
404 if ( strstr( $slug, 'radio-station-pro.php' ) ) {
405 // 2.4.0.4: only set premium for upgrade version
406 if ( isset( $plugin['Name'] ) && strstr( $plugin['Name'], '(Premium)' ) ) {
407 $plan = 'premium';
408 break;
409 } else {
410 // 2.4.0.4: detect and force enable addon version
411 $plan = 'premium';
412 $has_addons = true;
413 $has_plans = false;
414 break;
415 }
416 }
417 }
418 }
419
420 // 2.5.0: set as array for returning
421 $plan_options = array(
422 'has_plans' => $has_plans,
423 'has_addons' => $has_addons,
424 'plan_type' => $plan,
425 );
426 return $plan_options;
427 }
428
429 // --------------------
430 // Check Plugin Version
431 // --------------------
432 // 2.3.0: check plugin version for updates and announcements
433 add_action( 'init', 'radio_station_check_version', 9 );
434 function radio_station_check_version() {
435
436 // --- get current and stored versions ---
437 // 2.3.2: use plugin version function
438 $version = radio_station_plugin_version();
439 $stored_version = get_option( 'radio_station_version', false );
440
441 // --- check current against stored version ---
442 if ( !$stored_version ) {
443
444 // --- no stored plugin version, add it now ---
445 update_option( 'radio_station_version', $version );
446
447 if ( version_compare( $version, '2.3.0', '>=' ) ) {
448 // --- flush rewrite rules (for new post type and rest route rewrites) ---
449 // (handled separately as 2.3.0 is first version with version checking)
450 add_option( 'radio_station_flush_rewrite_rules', true );
451 }
452
453 } elseif ( version_compare( $version, $stored_version, '>' ) ) {
454
455 // --- updates from before to after x.x.x ---
456 // (code template if/when needed for future release updates)
457 // if ( ( version_compare( $version, 'x.x.x', '>=' ) )
458 // && ( version_compare( $stored_version, 'x.x.x', '<' ) ) ) {
459 // // eg. trigger a single thing to do
460 // add_option( 'radio_station_do_thing_once', true );
461 // }
462
463 // --- bump stored version to current version ---
464 update_option( 'radio_station_previous_version', $stored_version );
465 update_option( 'radio_station_version', $version );
466 }
467 }
468
469 // ------------------------
470 // Plugin Activation Action
471 // ------------------------
472 // (run on plugin activation, and thus also after a plugin update)
473 // 2.2.8: fix for mismatched flag function name
474 register_activation_hook( RADIO_STATION_FILE, 'radio_station_plugin_activation' );
475 function radio_station_plugin_activation() {
476
477 // --- flag to flush rewrite rules ---
478 // 2.2.3: added this for custom post types rewrite flushing
479 add_option( 'radio_station_flush_rewrite_rules', true );
480
481 // --- clear schedule transients ---
482 // 2.3.3: added clear transients on (re)activation
483 // 2.3.3.9: just use clear cached data function
484 radio_station_clear_cached_data( false );
485
486 // --- set welcome redirect transient ---
487 // TODO: check if handled by Freemius activation
488 // set_transient( 'radio_station_welcome', 1, 7 );
489
490 // 2.4.0.8: clear plugin updates transient on activation
491 delete_site_transient( 'update_plugins' );
492 }
493
494 // ---------------------------
495 // Activation Welcome Redirect
496 // ---------------------------
497 /* add_action( 'admin_init', 'radio_station_welcome_redirect' );
498 function radio_station_welcome_redirect() {
499 if ( !get_transient( 'radio_station_welcome' ) || wp_doing_ajax() || is_network_admin() || !current_user_can( 'install_plugins' ) ) {
500 return;
501 }
502 delete_transient( 'radio_station_welcome' );
503 $location = admin_url( 'admin.php?page=radio-station&welcome=1' );
504 wp_safe_redirect( $location );
505 exit;
506 } */
507
508 // --------------------------
509 // Plugin Deactivation Action
510 // --------------------------
511 // 2.4.0.8: clear plugin updates transient on deactivation
512 // 2.5.0: fix to typo in deactivation hook function and add _plugin
513 register_deactivation_hook( RADIO_STATION_FILE, 'radio_station_plugin_deactivation' );
514 function radio_station_plugin_deactivation() {
515 flush_rewrite_rules();
516 delete_site_transient( 'update_plugins' );
517 }
518
519 // -------------------------------
520 // Filter Plugin Updates Transient
521 // -------------------------------
522 // 2.4.0.8: added to ensure Pro never overwrites free on update
523 add_filter( 'pre_set_site_transient_update_plugins', 'radio_station_transient_update_plugins', 999 );
524 add_filter( 'site_transient_update_plugins', 'radio_station_transient_update_plugins', 999 );
525 function radio_station_transient_update_plugins( $transient_data ) {
526 // 2.4.0.9: fix for PHP8 cannot check property_exists of non-object
527 if ( $transient_data && is_object( $transient_data ) && property_exists( $transient_data, 'response' ) ) {
528 $response = $transient_data->response;
529 if ( isset( $response[RADIO_STATION_BASENAME] ) ) {
530 if ( strstr( $response[RADIO_STATION_BASENAME]->url, 'freemius' ) ) {
531 unset( $response[RADIO_STATION_BASENAME] );
532 }
533 }
534 $transient_data->response = $response;
535 }
536 return $transient_data;
537 }
538
539 // --------------------------------
540 // Filter Freemius Plugin Icon Path
541 // --------------------------------
542 // 2.4.0.8: filter Freemius plugin icon path
543 add_filter( 'fs_plugin_icon_radio-station', 'radio_station_freemius_plugin_url_path' );
544 function radio_station_freemius_plugin_url_path( $default_path ) {
545 $icon_path = RADIO_STATION_DIR . '/assets/icon-256x256.png';
546 if ( file_exists( $icon_path ) ) {
547 return $icon_path;
548 }
549 $icon_path = RADIO_STATION_DIR . '/images/' . RADIO_STATION_SLUG . '.png';
550 // 2.5.10: fix to mismatched variable default_path
551 if ( file_exists( $icon_path ) ) {
552 return $icon_path;
553 }
554 // 2.5.0: fix to incorrect return of undefined local_path
555 return $default_path;
556 }
557
558 // ------------------------------------
559 // Set Allowed Origins for Radio Player
560 // ------------------------------------
561 // 2.3.3.9: added for embedded radio player control
562 add_filter( 'allowed_http_origins', 'radio_station_allowed_player_origins' );
563 function radio_station_allowed_player_origins( $origins ) {
564
565 if ( !defined( 'DOING_AJAX' ) || !DOING_AJAX ) {
566 return $origins;
567 }
568 // 2.5.6: added sanitize_text_field
569 if ( !isset( $_REQUEST['action'] ) || ( 'radio_player' !== sanitize_text_field( $_REQUEST['action'] ) ) ) {
570 return $origins;
571 }
572
573 $netmix = untrailingslashit( RADIO_STATION_NETMIX_DIR );
574 $allowed = array( $netmix );
575 $allowed = apply_filters( 'radio_station_player_allowed_origins', $allowed );
576 foreach ( $allowed as $allow ) {
577 $origins[] = $allow;
578 }
579 return $origins;
580 }
581
582
583 // -------------------------
584 // === Resource Handling ===
585 // -------------------------
586
587 // ----------------------
588 // Enqueue Plugin Scripts
589 // ----------------------
590 // 2.3.0: added for enqueueing main Radio Station script
591 // 2.5.0: change to prevent conflict with radio station theme
592 add_action( 'wp_enqueue_scripts', 'radio_station_enqueue_plugin_scripts' );
593 function radio_station_enqueue_plugin_scripts() {
594
595 // --- enqueue custom stylesheet if found ---
596 // 2.3.0: added for automatic custom style loading
597 radio_station_enqueue_style( 'custom' );
598
599 // --- register moment js ---
600 // 2.5.0: move to separate function for reusability
601 // 2.5.18: move earlier to add as radio station dependency
602 radio_station_register_moment();
603 wp_enqueue_script( 'moment' );
604
605 // --- enqueue plugin script ---
606 // 2.3.0: added jquery dependency for inline script fragments
607 // 2.5.18: add moment as a dependency to prevent pageload conflicts
608 radio_station_enqueue_script( 'radio-station', array( 'jquery', 'moment' ), true );
609
610 // --- set script suffix ---
611 $suffix = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min';
612 $suffix = ( defined( 'RADIO_STATION_DEBUG' ) && RADIO_STATION_DEBUG ) ? '' : $suffix;
613
614 // -- enqueue javascript timezone detection script ---
615 // 2.3.3.9: activated for improved timezone detection
616 $jstz_url = plugins_url( 'js/jstz' . $suffix . '.js', RADIO_STATION_FILE );
617 wp_enqueue_script( 'jstz', $jstz_url, array(), '1.0.6', false );
618
619 }
620
621 // ------------------
622 // Register Moment JS
623 // ------------------
624 // 2.5.0: moved to separate function for resusability
625 function radio_station_register_moment() {
626
627 // --- set script suffix ---
628 $suffix = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min';
629 $suffix = ( defined( 'RADIO_STATION_DEBUG' ) && RADIO_STATION_DEBUG ) ? '' : $suffix;
630
631 // --- enqueue Moment.js ---
632 // ref: https://momentjs.com
633 // 2.3.3.9: added for improved time format display
634 // 2.5.0: add check for registered script in WP core
635 if ( !wp_script_is( 'moment', 'registered' ) ) {
636 $moment_url = plugins_url( 'js/moment' . $suffix . '.js', RADIO_STATION_FILE );
637 wp_register_script( 'moment', $moment_url, array( 'jquery' ), '2.29.4', false );
638 }
639 }
640
641 // ---------------------
642 // Enqueue Plugin Script
643 // ---------------------
644 function radio_station_enqueue_script( $scriptkey, $deps = array(), $infooter = false ) {
645
646 // --- set stylesheet filename and child theme path ---
647 $filename = $scriptkey . '.js';
648
649 // 2.3.0: check template hierarchy for file
650 $template = radio_station_get_template( 'both', $filename, 'js' );
651 if ( $template ) {
652
653 // 2.3.2: use plugin version for releases
654 $plugin_version = radio_station_plugin_version();
655 $version_length = strlen( $plugin_version );
656 // 2.5.0: allow for minor version release numbers
657 if ( 4 > $version_length ) {
658 $version = $plugin_version;
659 } else {
660 $version = filemtime( $template['file'] );
661 }
662
663 $url = $template['url'];
664
665 // --- enqueue script ---
666 // 2.5.0: register script before enqueueing
667 wp_register_script( $scriptkey, $url, $deps, $version, $infooter );
668 wp_enqueue_script( $scriptkey );
669 }
670 }
671
672 // -----------------
673 // Add Inline Script
674 // -----------------
675 // 2.5.0: added for missed inline scripts (via shortcodes)
676 function radio_station_add_inline_script( $handle, $js, $position = 'after' ) {
677
678 // --- add check if script is already done ---
679 if ( wp_script_is( $handle, 'registered' ) && !wp_script_is( $handle, 'done' ) ) {
680
681 // --- handle javascript normally ---
682 wp_add_inline_script( $handle, $js, $position );
683
684 } else {
685
686 // 2.5.7: enqueue dummy javascript file to output in footer
687 // 2.5.10: fix slug from rp-footer to rs-footer
688 // 2.5.10: change from register_script to enqueue_script
689 // 2.5.18: register here but enqueue later
690 if ( !wp_script_is( RADIO_STATION_SLUG . '-footer', 'registered' ) ) {
691 $version = function_exists( 'radio_station_plugin_version' ) ? radio_station_plugin_version() : '2.5.0';
692 wp_register_script( RADIO_STATION_SLUG . '-footer', null, array( 'jquery' ), $version, true );
693 // wp_enqueue_script( RADIO_STATION_SLUG . '-footer' );
694 }
695 wp_add_inline_script( RADIO_STATION_SLUG . '-footer', $js, $position );
696
697 // 2.5.18: enqueue in footer
698 // 2.5.18: allow for admin footer hook
699 $hook = is_admin() ? 'admin_footer' : 'wp_footer';
700 if ( !has_action( $hook, 'radio_station_enqueue_footer_scripts', 5 ) ) {
701 add_action( $hook, 'radio_station_enqueue_footer_scripts', 5 );
702 }
703
704 }
705 }
706
707 // ----------------------
708 // Enqueue Footer Scripts
709 // ----------------------
710 // 2.5.0: added print footer scripts for missed inline scripts
711 // 2.5.7: deprecated print script in favour of adding inline to dummy script
712 // 2.5.18: repurpose to enqueue footer scripts
713 function radio_station_enqueue_footer_scripts() {
714 wp_enqueue_script( RADIO_STATION_SLUG . '-footer' );
715 }
716
717 // --------------------------
718 // Print Admin Footer Scripts
719 // --------------------------
720 // 2.5.7: deprecated in favour of adding inline to dummy script
721
722 // -------------------------
723 // Enqueue Plugin Stylesheet
724 // -------------------------
725 // ?.?.?: widgets.css style conditional enqueueing moved to within widget classes
726 // 2.3.0: added abstracted method for enqueueing plugin stylesheets
727 // 2.3.0: moved master schedule style enqueueing to conditional in master-schedule.php
728 // 2.5.0: added optional dependencies argument to style enqueues
729 function radio_station_enqueue_style( $stylekey, $deps = array() ) {
730
731 // --- check style enqueued switch ---
732 global $radio_station_styles;
733 if ( !isset( $radio_station_styles ) ) {
734 $radio_station_styles = array();
735 }
736 if ( !isset( $radio_station_styles[$stylekey] ) ) {
737
738 // --- set stylesheet filename and child theme path ---
739 $filename = 'rs-' . $stylekey . '.css';
740
741 // 2.3.0: check template hierarchy for file
742 $template = radio_station_get_template( 'both', $filename, 'css' );
743 if ( $template ) {
744
745 // --- use found template values ---
746 // 2.3.2: use plugin version for releases
747 $plugin_version = radio_station_plugin_version();
748 $version_length = strlen( $plugin_version );
749 // 2.5.0: allow for minor version release numbers
750 if ( 4 > $version_length ) {
751 $version = $plugin_version;
752 } else {
753 $version = filemtime( $template['file'] );
754 }
755 $url = $template['url'];
756
757 // --- enqueue styles in footer ---
758 wp_enqueue_style( 'rs-' . $stylekey, $url, $deps, $version, 'all' );
759
760 // --- set style enqueued switch ---
761 $radio_station_styles[$stylekey] = true;
762 }
763 }
764 }
765
766 // -----------------
767 // Add Inline Styles
768 // -----------------
769 // 2.5.0: added for missed inline styles (via shortcodes)
770 function radio_station_add_inline_style( $handle, $css ) {
771
772 // --- add check if style is already done ---
773 if ( wp_style_is( $handle, 'registered' ) && !wp_style_is( $handle, 'done' ) ) {
774
775 // --- handle style normally ---
776 wp_add_inline_style( $handle, $css );
777
778 } else {
779 // 2.5.18: register inline style but enqueue later
780 if ( !wp_style_is( RADIO_STATION_SLUG . '-footer', 'registered' ) ) {
781 $version = function_exists( 'radio_station_plugin_version' ) ? radio_station_plugin_version() : '2.5.0';
782 wp_register_style( RADIO_STATION_SLUG . '-footer', null, array(), $version, 'all' );
783 // wp_enqueue_style( RADIO_STATION_SLUG . '-footer' );
784 }
785 wp_add_inline_style( RADIO_STATION_SLUG . '-footer', $css );
786
787 // 2.5.18: allow for admin footer position
788 $hook = is_admin() ? 'admin_footer' : 'wp_footer';
789 if ( !has_action( $hook, 'radio_station_enqueue_footer_styles', 5 ) ) {
790 add_action( $hook, 'radio_station_enqueue_footer_styles', 5 );
791 }
792 }
793 }
794
795 // ---------------------
796 // Enqueue Footer Styles
797 // ---------------------
798 // 2.5.0: added print in footer for missed inline styles
799 // 2.5.18: repurpose to enqueue footer Styles
800 function radio_station_enqueue_footer_styles() {
801 wp_enqueue_style( RADIO_STATION_SLUG . '-footer' );
802 }
803
804 // -------------------------
805 // Print Admin Footer Styles
806 // -------------------------
807 // 2.5.0: added for missed inline styles
808 // 2.5.7: deprecated in favour of adding inline to dummy script
809
810 // -----------------------------
811 // Print Missed Footer Resources
812 // -----------------------------
813 // 2.1.19: added for theme compatibility (shortcode loaded styles to footer)
814 // 2.7.1: change priority to 19 to be before _wp_footer_scripts
815 add_action( 'wp_footer', 'radio_station_print_missed_footer_resources', 19 );
816 function radio_station_print_missed_footer_resources() {
817 print_late_styles();
818 wp_print_styles();
819 /* global $wp_styles;
820 foreach ( $wp_styles->registered as $handle => $style ) {
821 if ( wp_style_is( $handle, 'queue' ) && !wp_style_is( $handle, 'done' ) ) {
822 $wp_styles->do_item( $handle, false );
823 }
824 } */
825 // 2.7.1: do NOT call wp_print_footer_scripts as clearing style queue
826 // wp_print_footer_scripts();
827 }
828
829
830 // ----------------------
831 // Debug Queued Resources
832 // ----------------------
833 // 2.7.1: added for debugging weird footer enqueue bugs
834 add_action( 'wp_footer', 'radio_station_debug_queued_resources', 9 );
835 add_action( 'wp_footer', 'radio_station_debug_queued_resources', 21 );
836 function radio_station_debug_queued_resources() {
837
838 global $wp_styles, $wp_scripts;
839
840 if ( isset( $_REQUEST['rs-debug-styles'] ) && is_a( $wp_styles, 'WP_Styles' ) ) {
841 echo '<span style="display:none;">Style Print Queue: ' . "\n";
842 foreach ( $wp_styles->registered as $handle => $style ) {
843 if ( wp_style_is( $handle, 'queue' ) && !wp_style_is( $handle, 'done' ) ) {
844 echo $handle . ': ' . print_r( $style, true ) . "\n";
845 }
846 }
847 echo '</span>' . "\n";;
848 }
849
850 if ( isset( $_REQUEST['rs-debug-scripts'] ) && is_a( $wp_scripts, 'WP_Scripts' ) ) {
851 echo '<span style="display:none;">Script Print Queue: ' . "\n";
852 foreach ( $wp_scripts->registered as $handle => $script ) {
853 if ( wp_script_is( $handle, 'queue' ) && !wp_script_is( $wp_script_is, 'done' ) ) {
854 echo $handle . ': ' . print_r( $script, true ) . "\n";
855 }
856 }
857 echo '</span>' . "\n";;
858 }
859
860 }
861
862 // ------------------
863 // Enqueue Datepicker
864 // ------------------
865 // 2.3.0: enqueued separately by override post type only
866 // 2.3.3.9: moved here from radio-station-admin.php
867 function radio_station_enqueue_datepicker() {
868
869 // --- enqueue jquery datepicker ---
870 wp_enqueue_script( 'jquery-ui-datepicker' );
871
872 // --- enqueue jquery datepicker styles ---
873 // 2.3.0: update theme styles from 1.8.2 to 1.12.1
874 // 2.3.0: use local datepicker styles instead of via Google
875 // $protocol = is_ssl() ? 'https' : 'http';
876 // $url = $protocol . '://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/smoothness/jquery-ui.css';
877 // wp_enqueue_style( 'jquery-ui-style', $url, array(), '1.12.1' );
878 $style = radio_station_get_template( 'both', 'jquery-ui.css', 'css' );
879 wp_enqueue_style( 'jquery-ui-smoothness', $style['url'], array(), '1.12.1', 'all' );
880
881 }
882
883 // ---------------------------
884 // Enqueue Widget Color Picker
885 // ---------------------------
886 // 2.5.0: added for widget color options
887 function radio_station_enqueue_color_picker() {
888
889 // --- enqueue color picker ---
890 $suffix = SCRIPT_DEBUG ? '' : '.min';
891 $url = plugins_url( '/js/wp-color-picker-alpha' . $suffix . '.js', RADIO_STATION_FILE );
892 wp_enqueue_script( 'wp-color-picker-a', $url, array( 'wp-color-picker' ), '3.0.0', true );
893
894 // --- init color picker fields ---
895 $js = "jQuery(document).ready(function() {";
896 $js .= "if (jQuery('.color-picker').length) {jQuery('.color-picker').wpColorPicker();}";
897 $js .= "});" . "\n";
898 // 2.5.0: use radio_station_add_inline_script
899 radio_station_add_inline_script( 'wp-color-picker-a', $js );
900 }
901
902 // -------------------------------
903 // Enqueue Localized Script Values
904 // -------------------------------
905 add_action( 'wp_enqueue_scripts', 'radio_station_localize_script' );
906 function radio_station_localize_script() {
907
908 // 2.5.0: check flag to run once only
909 global $radio_station;
910 if ( isset( $radio_station['script-localized'] ) ) {
911 return;
912 }
913
914 $js = radio_station_localization_script();
915 // 2.5.0: use radio_station_add_inline_script
916 radio_station_add_inline_script( 'radio-station', $js );
917 $radio_station['script-localized'] = true;
918 }
919
920 // -------------------
921 // Localization Script
922 // -------------------
923 // 2.3.3.9: separated script from enqueueing
924 function radio_station_localization_script() {
925
926 // --- create settings objects ---
927 $js = "var radio = {}; radio.timezone = {}; radio.time = {}; radio.labels = {}; radio.units = {};";
928
929 // 2.4.0.6: add filterable time display separator
930 $time_separator = apply_filters( 'radio_station_time_separator', ':', 'javascript' );
931 $js .= " radio.sep = '" . esc_js( $time_separator ) . "';";
932
933 // --- set AJAX URL ---
934 // 2.3.2: add admin AJAX URL
935 $js .= "radio.ajax_url = '" . esc_url( admin_url( 'admin-ajax.php' ) ) . "';" . "\n";
936
937 // --- clock time format ---
938 // TODO: maybe set time format ?
939 // ref: https://devhints.io/wip/intl-datetime
940 $clock_format = radio_station_get_setting( 'clock_time_format' );
941 $js .= "radio.clock_format = '" . esc_js( $clock_format ) . "';" . "\n";
942
943 // --- detect touchscreens ---
944 // ref: https://stackoverflow.com/a/52855084/5240159
945 // 2.5.0: use !any-pointer:fine instead of pointer:coarse
946 // ref: https://stackoverflow.com/a/51774045/5240159
947 $js .= "matchmedia = window.matchMedia || window.msMatchMedia;" . "\n";
948 $js .= "radio.touchscreen = !matchmedia('(any-pointer: fine)').matches;" . "\n";
949
950 // --- set debug flag ---
951 if ( RADIO_STATION_DEBUG ) {
952 $js .= "radio.debug = true;" . "\n";
953 } else {
954 $js .= "radio.debug = false;" . "\n";
955 }
956
957 // 2.5.0: set separate clock debug flag
958 if ( isset( $_REQUEST['rs-clock-debug'] ) && ( '1' === sanitize_text_field( $_REQUEST['rs-clock-debug'] ) ) ) {
959 $js .= "radio.clock_debug = true;" . "\n";
960 } else {
961 $js .= "radio.clock_debug = false;" . "\n";
962 }
963
964 // --- radio timezone ---
965 // 2.3.2: added get timezone function
966 $timezone = radio_station_get_timezone();
967
968 if ( stristr( $timezone, 'UTC' ) ) {
969
970 if ( 'UTC' == $timezone ) {
971 $offset = '0';
972 } else {
973 $offset = str_replace( 'UTC', '', $timezone );
974 }
975 $js .= "radio.timezone.offset = " . esc_js( $offset * 60 * 60 ) . "; ";
976 if ( '0' == $offset ) {
977 $offset = '';
978 } elseif ( $offset > 0 ) {
979 $offset = '+' . $offset;
980 }
981 $js .= "radio.timezone.code = 'UTC" . esc_js( $offset ) . "';" . "\n";
982 $js .= "radio.timezone.utc = '" . esc_js( $offset ) . "';" . "\n";
983 $js .= "radio.timezone.utczone = true;" . "\n";
984
985 } else {
986
987 // --- get offset and code from timezone location ---
988 $datetimezone = new DateTimeZone( $timezone );
989 $offset = $datetimezone->getOffset( new DateTime() );
990 $offset_hours = $offset / ( 60 * 60 );
991 if ( 0 == $offset ) {
992 $utc_offset = '';
993 } elseif ( $offset > 0 ) {
994 $utc_offset = '+' . $offset_hours;
995 } else {
996 $utc_offset = $offset_hours;
997 }
998 $utc_offset = 'UTC' . $utc_offset;
999 $code = radio_station_get_timezone_code( $timezone );
1000 $js .= "radio.timezone.location = '" . esc_js( $timezone ) . "';" . "\n";
1001 $js .= "radio.timezone.offset = " . esc_js( $offset ) . ";" . "\n";
1002 $js .= "radio.timezone.code = '" . esc_js( $code ) . "';" . "\n";
1003 $js .= "radio.timezone.utc = '" . esc_js( $utc_offset ) . "';" . "\n";
1004 $js .= "radio.timezone.utczone = false;" . "\n";
1005
1006 }
1007
1008 if ( defined( 'RADIO_STATION_USE_SERVER_TIMES' ) && RADIO_STATION_USE_SERVER_TIMES ) {
1009 $js .= "radio.timezone.adjusted = false;" . "\n";
1010 } else {
1011 $js .= "radio.timezone.adjusted = true;" . "\n";
1012 }
1013
1014 // --- set user timezone offset ---
1015 // (and convert offset minutes to seconds)
1016 $js .= "radio.timezone.useroffset = (new Date()).getTimezoneOffset() * 60;" . "\n";
1017
1018 // --- translated months array ---
1019 // 2.3.2: also translate short month labels
1020 $js .= "radio.labels.months = new Array(";
1021 $short = "radio.labels.smonths = new Array(";
1022 $months = array( 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' );
1023 foreach ( $months as $i => $month ) {
1024 $month = radio_station_translate_month( $month );
1025 $short_month = radio_station_translate_month( $month, true );
1026 $month = str_replace( "'", "", $month );
1027 $short_month = str_replace( "'", "", $short_month );
1028 $js .= "'" . esc_js( $month ) . "'";
1029 $short .= "'" . esc_js( $short_month ) . "'";
1030 if ( $i < ( count( $months ) - 1 ) ) {
1031 $js .= ", ";
1032 $short .= ", ";
1033 }
1034 }
1035 $js .= ");" . "\n";
1036 $js .= $short . ");" . "\n";
1037
1038 // --- translated days array ---
1039 // 2.3.2: also translate short day labels
1040 $js .= "radio.labels.days = new Array(";
1041 $short = "radio.labels.sdays = new Array(";
1042 $days = array( 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday' );
1043 foreach ( $days as $i => $day ) {
1044 $day = radio_station_translate_weekday( $day );
1045 $short_day = radio_station_translate_weekday( $day, true );
1046 $day = str_replace( "'", "", $day );
1047 $short_day = str_replace( "'", "", $short_day );
1048 $js .= "'" . esc_js( $day ) . "'";
1049 $short .= "'" . esc_js( $short_day ) . "'";
1050 if ( $i < ( count( $days ) - 1 ) ) {
1051 $js .= ", ";
1052 $short .= ", ";
1053 }
1054 }
1055 $js .= ");" . "\n";
1056 $js .= $short . ");" . "\n";
1057
1058 // --- set countdown labels ---
1059 // 2.5.0: moved here from countdown enqueue function
1060 // 2.5.18: added with label for host metadata display
1061 $js .= "radio.labels.showstarted = '" . esc_js( __( 'This Show has started.', 'radio-station' ) ) . "';" . "\n";
1062 $js .= "radio.labels.showended = '" . esc_js( __( 'This Show has ended.', 'radio-station' ) ) . "';" . "\n";
1063 $js .= "radio.labels.playlistended = '" . esc_js( __( 'This Playlist has ended.', 'radio-station' ) ) . "';" . "\n";
1064 $js .= "radio.labels.timecommencing = '" . esc_js( __( 'Commencing in', 'radio-station' ) ) . "';" . "\n";
1065 $js .= "radio.labels.timeremaining = '" . esc_js( __( 'Remaining Time', 'radio-station' ) ) . "';" . "\n";
1066 $js .= "radio.labels.showwith = '" . esc_js( __( 'with', 'radio-station' ) ) . "';" . "\n";
1067 $js .= "radio.labels.showand = '" . esc_js( __( 'and', 'radio-station' ) ) . "';" . "\n";
1068
1069 // --- translated time unit strings ---
1070 $js .= "radio.units.am = '" . esc_js( radio_station_translate_meridiem( 'am' ) ) . "'; ";
1071 $js .= "radio.units.pm = '" . esc_js( radio_station_translate_meridiem( 'pm' ) ) . "'; ";
1072 $js .= "radio.units.second = '" . esc_js( __( 'Second', 'radio-station' ) ) . "'; ";
1073 $js .= "radio.units.seconds = '" . esc_js( __( 'Seconds', 'radio-station' ) ) . "'; ";
1074 $js .= "radio.units.minute = '" . esc_js( __( 'Minute', 'radio-station' ) ) . "'; ";
1075 $js .= "radio.units.minutes = '" . esc_js( __( 'Minutes', 'radio-station' ) ) . "'; ";
1076 $js .= "radio.units.hour = '" . esc_js( __( 'Hour', 'radio-station' ) ) . "'; ";
1077 $js .= "radio.units.hours = '" . esc_js( __( 'Hours', 'radio-station' ) ) . "'; ";
1078 $js .= "radio.units.day = '" . esc_js( __( 'Day', 'radio-station' ) ) . "'; ";
1079 $js .= "radio.units.days = '" . esc_js( __( 'Days', 'radio-station' ) ) . "'; " . "\n";
1080
1081 // --- time key map ---
1082 // 2.3.3.9: added for PHP Date Format to MomentJS conversions
1083 // (object of approximate 'PHP date() key':'moment format() key' conversions)
1084 $js .= "radio.moment_map = {'d':'D', 'j':'D', 'w':'e', 'D':'e', 'l':'e', 'N':'e', 'S':'Do', ";
1085 $js .= "'F':'M', 'm':'M', 'n':'M', 'M':'M', 'Y':'YYYY', 'y':'YY',";
1086 $js .= "'a':'a', 'A':'a', 'g':'h', 'G':'H', 'g':'h', 'H':'H', 'i':'m', 's':'s'}" . "\n";
1087
1088 // --- convert show times ---
1089 // 2.3.3.9:
1090 // 2.5.0: shorten logic for convert show times
1091 $usertimes = radio_station_get_setting( 'convert_show_times' );
1092 $convert_show_times = ( 'yes' === (string) $usertimes ) ? 'true' : 'false';
1093 $js .= "radio.convert_show_times = " . esc_js( $convert_show_times ) . ";" . "\n";
1094
1095 // --- add inline script ---
1096 $js = apply_filters( 'radio_station_localization_script', $js );
1097 return $js;
1098 }
1099
1100 // ---------------------
1101 // Filter Streaming Data
1102 // ---------------------
1103 // 2.3.3.7: added streaming data filter for player integration
1104 // 2.5.6: added missing 4th argument (arg count declaration)
1105 add_filter( 'radio_player_data', 'radio_station_streaming_data', 10, 2 );
1106 function radio_station_streaming_data( $data, $station = false ) {
1107
1108 $data = array(
1109 'script' => radio_station_get_setting( 'player_script' ),
1110 'instance' => 0,
1111 'url' => radio_station_get_stream_url(),
1112 'format' => radio_station_get_setting( 'streaming_format' ),
1113 'fallback' => radio_station_get_fallback_url(),
1114 'fformat' => radio_station_get_setting( 'fallback_format' ),
1115 );
1116
1117 // commented out: this breaks player settings
1118 // if ( RADIO_STATION_DEBUG ) {
1119 // echo '<span style="display:none;">Player Stream Data: ' . esc_html( print_r( $data, true ) ) . '</span>' . "\n";
1120 // }
1121 $data = apply_filters( 'radio_station_streaming_data', $data, $station );
1122 return $data;
1123 }
1124
1125 // --------------------
1126 // Filter Player Script
1127 // --------------------
1128 // 2.5.7: disable Howler script setting (browser incompatibilities)
1129 add_filter( 'radio_station_player_script', 'radio_station_filter_player_script', 11 );
1130 function radio_station_filter_player_script( $script ) {
1131 if ( 'howler' == $script ) {
1132 $script = 'amplitude';
1133 }
1134 return $script;
1135 }
1136
1137
1138 // -------------------------
1139 // === Transient Caching ===
1140 // -------------------------
1141 // 2.5.0: moved here from includes/support-functions.php
1142
1143 // --------------------------
1144 // Delete Prefixed Transients
1145 // --------------------------
1146 // 2.3.3.4: added helper for clearing transient data
1147 function radio_station_delete_transients_with_prefix( $prefix ) {
1148 global $wpdb;
1149
1150 // 2.3.3.9: add trailing underscore to prefix
1151 $prefix = $wpdb->esc_like( '_transient_' . $prefix . '_' );
1152
1153 // 2.3.3.9: fix to LIKE match
1154 // $query = "SELECT `option_name` FROM " . $wpdb->prefix . "options WHERE `option_name` LIKE '%" . $prefix . "%'";
1155 // $results = $wpdb->get_results( $query, ARRAY_A );
1156 // 2.5.9: use wpdb_prepare on LIKE statement
1157 // ref: https://wordpress.stackexchange.com/a/8834/76440
1158 $query = "SELECT `option_name` FROM " . $wpdb->prefix . "options WHERE `option_name` LIKE '%%%s%%'";
1159 $results = $wpdb->get_results( $wpdb->prepare( $query, $prefix ), ARRAY_A );
1160
1161 // if ( RADIO_STATION_DEBUG ) {
1162 // echo $query . PHP_EOL . '<br>';
1163 // echo 'Transients: ' . esc_html( print_r( $results, true ) ) . "\n";
1164 // }
1165 if ( !$results || !is_array( $results ) || ( count( $results ) < 1 ) ) {
1166 return;
1167 }
1168
1169 foreach ( $results as $option ) {
1170 // 2.3.3.9: fix to replace malfunctioning ltrim
1171 // $key = ltrim( $option['option_name'], '_transient_' );
1172 $key = substr( $option['option_name'], 11 );
1173 delete_transient( $key );
1174 // 2.3.3.9: also delete transient cache object by key
1175 wp_cache_delete( $key, 'transient' );
1176 // if ( RADIO_STATION_DEBUG ) {
1177 // echo "Deleting transient and cache object for '" . esc_html( $key ) . "'" . "\n";
1178 // }
1179 }
1180 }
1181
1182 // -----------------
1183 // Clear Cached Data
1184 // -----------------
1185 // 2.3.3.9: made into separate function
1186 // 2.4.0.3: added second argument for post type
1187 function radio_station_clear_cached_data( $post_id = false, $post_type = false ) {
1188
1189 // --- clear main schedule transients ---
1190 // 2.3.3: remove current show transient
1191 // 2.3.4: add previous show transient
1192 delete_transient( 'radio_station_current_schedule' );
1193 delete_transient( 'radio_station_next_show' );
1194 delete_transient( 'radio_station_previous_show' );
1195
1196 // --- clear time-based schedule transients ---
1197 // 2.3.4: delete all prefixed transients (for times)
1198 radio_station_delete_transients_with_prefix( 'radio_station_current_schedule' );
1199 radio_station_delete_transients_with_prefix( 'radio_station_next_show' );
1200 radio_station_delete_transients_with_prefix( 'radio_station_previous_show' );
1201
1202 // --- maybe clear show meta data ---
1203 if ( $post_id ) {
1204 do_action( 'radio_station_clear_data', $post_type, $post_id );
1205 if ( $post_type ) {
1206 do_action( 'radio_station_clear_data', $post_type . '_meta', $post_id );
1207 }
1208 }
1209
1210 // --- maybe send directory ping ---
1211 // 2.3.1: added directory update ping option
1212 // 2.3.2: queue directory ping
1213 radio_station_queue_directory_ping();
1214
1215 // --- set last updated schedule time ---
1216 // 2.3.2: added for data API use
1217 update_option( 'radio_station_schedule_updated', time() );
1218
1219 }
1220
1221 // ---------------------------------
1222 // Clear Cache on Status Transitions
1223 // ---------------------------------
1224 // 2.4.0.4: clear show and override caches on post status changes
1225 add_action( 'transition_post_status', 'radio_station_clear_cache_on_transitions', 10, 3 );
1226 function radio_station_clear_cache_on_transitions( $new_status, $old_status, $post ) {
1227 if ( $new_status == $old_status ) {
1228 return;
1229 }
1230 $post_types = array( RADIO_STATION_SHOW_SLUG, RADIO_STATION_OVERRIDE_SLUG );
1231 if ( in_array( $post->post_type, $post_types ) ) {
1232 radio_station_clear_cached_data( $post->ID, $post->post_type );
1233 }
1234 }
1235
1236
1237 // -----------------
1238 // === Debugging ===
1239 // -----------------
1240
1241 // --------------------------
1242 // maybe Clear Transient Data
1243 // --------------------------
1244 // 2.3.0: clear show transients if debugging
1245 // 2.3.1: added action to init hook
1246 // 2.3.1: check clear show transients option
1247 add_action( 'init', 'radio_station_clear_transients' );
1248 function radio_station_clear_transients() {
1249 $clear_transients = radio_station_get_setting( 'clear_transients' );
1250 if ( RADIO_STATION_DEBUG || ( 'yes' === (string) $clear_transients ) ) {
1251 // 2.3.2: do not clear on AJAX calls
1252 if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
1253 return;
1254 }
1255 // 2.3.3.9: just use clear cached data function
1256 radio_station_clear_cached_data( false );
1257 }
1258 }
1259
1260 // ------------------------
1261 // Debug Output and Logging
1262 // ------------------------
1263 // 2.3.0: added debugging function
1264 function radio_station_debug( $data, $echo = true, $file = false ) {
1265
1266 // --- maybe output debug info ---
1267 if ( $echo ) {
1268 // 2.3.0: added span wrap for hidden display
1269 // 2.3.1.1: added class for page source searches
1270 // 2.5.0: wrap in esc_html anyway (though it might mangle debug output)
1271 echo '<span class="radio-station-debug" style="display:none;">' . esc_html( $data ) . '</span>' . PHP_EOL;
1272 }
1273
1274 // --- check for logging constant ---
1275 if ( defined( 'RADIO_STATION_DEBUG_LOG' ) ) {
1276 if ( !$file && RADIO_STATION_DEBUG_LOG ) {
1277 $file = 'radio-station.log';
1278 } elseif ( false === RADIO_STATION_DEBUG_LOG ) {
1279 $file = false;
1280 }
1281 }
1282
1283 // --- write to debug file ---
1284 if ( $file ) {
1285 if ( !is_dir( RADIO_STATION_DIR . '/debug' ) ) {
1286 wp_mkdir_p( RADIO_STATION_DIR . '/debug' );
1287 }
1288 $file = RADIO_STATION_DIR . '/debug/' . $file;
1289 error_log( $data, 3, $file );
1290 }
1291 }
1292
1293 // ---------------------
1294 // Freemius Object Debug
1295 // ---------------------
1296 // 2.4.0.4: added to debug freemius instance
1297 add_action( 'shutdown', 'radio_station_freemius_debug' );
1298 function radio_station_freemius_debug() {
1299 if ( is_admin() && RADIO_STATION_DEBUG && current_user_can( 'manage_options' ) ) {
1300 // 2.4.0.6: check if global instance is set directly
1301 if ( isset( $GLOBALS['radio_station_freemius'] ) ) {
1302 $instance = $GLOBALS['radio_station_freemius'];
1303 echo '<span style="display:none;">Freemius Object: ' . esc_html( print_r( $instance, true ) ) . '</span>';
1304 }
1305 }
1306 }
1307
1308 // ---------------------------
1309 // Debug Footer Scripts/Styles
1310 // ---------------------------
1311 // add_action( 'wp_footer', 'radio_station_script_debug', 1 );
1312 function radio_station_script_debug() {
1313 if ( !RADIO_STATION_DEBUG ) {
1314 return;
1315 }
1316 if ( isset( $_REQUEST['debug-script'] ) ) {
1317 $handle = sanitize_text_field( $_REQUEST['debug-script'] );
1318 global $wp_scripts;
1319 $debug = $wp_scripts->registered[$handle];
1320 echo '<span style="display:none;">Script object for ' . esc_html( $handle ) . ': ' . esc_html( print_r( $debug, true ) ) . '</span>' . "\n";
1321 }
1322 if ( isset( $_REQUEST['debug-style'] ) ) {
1323 $handle = sanitize_text_field( $_REQUEST['debug-style'] );
1324 global $wp_styles;
1325 $debug = $wp_styles->registered[$handle];
1326 echo '<span style="display:none;">Style object for ' . esc_html( $handle ) . ': ' . esc_html( print_r( $debug, true ) ) . '</span>' . "\n";
1327 }
1328 }
1329