PluginProbe
AudioIgniter Music Player / 1.7.2
AudioIgniter Music Player v1.7.2
2.0.4 trunk 1.0.0 1.0.1 1.1.0 1.2.0 1.3.0 1.4.0 1.4.1 1.4.2 1.5.0 1.5.1 1.6.0 1.6.1 1.6.2 1.6.3 1.7.0 1.7.1 1.7.2 1.7.3 1.8.0 1.9.0 2.0.0 2.0.1 2.0.2 All 26 releases
audioigniter / audioigniter.php

audioigniter.php in AudioIgniter Music Player 1.7.2, at audioigniter.php

1,372 lines 45.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Plugin Name: AudioIgniter
4 * Plugin URI: https://www.cssigniter.com/plugins/audioigniter/
5 * Description: AudioIgniter lets you create music playlists and embed them in your WordPress posts, pages or custom post types and serve your audio content in style!
6 * Author: The CSSIgniter Team
7 * Author URI: https://www.cssigniter.com
8 * Version: 1.7.2
9 * Text Domain: audioigniter
10 * Domain Path: languages
11 *
12 * AudioIgniter is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation, either version 2 of the License, or
15 * any later version.
16 *
17 * AudioIgniter Downloads is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with AudioIgniter. If not, see <http://www.gnu.org/licenses/>.
24 *
25 */
26
27 if ( ! defined( 'ABSPATH' ) ) {
28 exit;
29 }
30
31
32 class AudioIgniter {
33
34 /**
35 * AudioIgniter version.
36 *
37 * @var string
38 * @since 1.0.0
39 * @since 1.7.0 Changed from static to non-static.
40 */
41 public $version = null;
42
43 /**
44 * Instance of this class.
45 *
46 * @var AudioIgniter
47 * @since 1.0.0
48 */
49 protected static $instance = null;
50
51 /**
52 * Sanitizer instance.
53 *
54 * @var AudioIgniter_Sanitizer
55 * @since 1.0.0
56 */
57 public $sanitizer = null;
58
59 /**
60 * The URL directory path (with trailing slash) of the main plugin file.
61 *
62 * @var string
63 * @since 1.0.0
64 */
65 protected static $plugin_url = '';
66
67 /**
68 * The filesystem directory path (with trailing slash) of the main plugin file.
69 *
70 * @var string
71 * @since 1.0.0
72 */
73 protected static $plugin_path = '';
74
75
76 /**
77 * Playlist post type name.
78 *
79 * @var string
80 * @since 1.0.0
81 */
82 public $post_type = 'ai_playlist';
83
84
85
86 /**
87 * AudioIgniter Instance.
88 *
89 * Instantiates or reuses an instance of AudioIgniter.
90 *
91 * @since 1.0.0
92 * @static
93 * @see AudioIgniter()
94 * @return AudioIgniter - Single instance.
95 */
96 public static function instance() {
97 if ( is_null( self::$instance ) ) {
98 self::$instance = new self();
99 }
100 return self::$instance;
101 }
102
103
104 /**
105 * AudioIgniter constructor. Intentionally left empty so that instances can be created without
106 * re-loading of resources (e.g. scripts/styles), or re-registering hooks.
107 * http://wordpress.stackexchange.com/questions/70055/best-way-to-initiate-a-class-in-a-wp-plugin
108 * https://gist.github.com/toscho/3804204
109 *
110 * @since 1.0.0
111 */
112 public function __construct() {}
113
114 /**
115 * Kickstarts plugin loading.
116 *
117 * @since 1.0.0
118 */
119 public function plugin_setup() {
120 if ( is_null( $this->version ) ) {
121 if ( ! function_exists( 'get_plugin_data' ) ) {
122 include_once ABSPATH . 'wp-admin/includes/plugin.php';
123 }
124 $plugin_data = get_plugin_data( __FILE__ );
125
126 $this->version = $plugin_data['Version'];
127 }
128
129 self::$plugin_url = plugin_dir_url( __FILE__ );
130 self::$plugin_path = plugin_dir_path( __FILE__ );
131
132 load_plugin_textdomain( 'audioigniter', false, dirname( self::plugin_basename() ) . '/languages' );
133
134 include_once( 'class-audioigniter-sanitizer.php' );
135 $this->sanitizer = new AudioIgniter_Sanitizer();
136
137 // Initialization needed in every request.
138 $this->init();
139
140 // Initialization needed in admin requests.
141 $this->admin_init();
142
143 // Initialization needed in frontend requests.
144 $this->frontend_init();
145
146 do_action( 'audioigniter_loaded' );
147 }
148
149 /**
150 * Registers actions that need to be run on both admin and frontend
151 *
152 * @since 1.0.0
153 */
154 protected function init() {
155 add_action( 'init', array( $this, 'register_post_types' ) );
156 add_action( 'init', array( $this, 'register_scripts' ) );
157 add_action( 'init', array( $this, 'register_playlist_endpoint' ) );
158 add_action( 'init', array( $this, 'register_image_sizes' ) );
159 add_action( 'init', array( $this, 'register_shortcodes' ) );
160 add_action( 'widgets_init', array( $this, 'register_widgets' ) );
161
162 do_action( 'audioigniter_init' );
163 }
164
165
166 /**
167 * Registers actions that need to be run on admin only.
168 *
169 * @since 1.0.0
170 */
171 protected function admin_init() {
172 if ( ! is_admin() ) {
173 return;
174 }
175
176 add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_scripts' ) );
177 add_action( 'add_meta_boxes', array( $this, 'add_meta_boxes' ) );
178 add_action( 'save_post', array( $this, 'save_post' ) );
179
180 do_action( 'audioigniter_admin_init' );
181 }
182
183 /**
184 * Registers actions that need to be run on frontend only.
185 *
186 * @since 1.0.0
187 */
188 protected function frontend_init() {
189 if ( is_admin() ) {
190 return;
191 }
192
193 add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
194 add_action( 'template_redirect', array( $this, 'handle_playlist_endpoint' ) );
195
196 do_action( 'audioigniter_frontend_init' );
197 }
198
199 /**
200 * Register (but not enqueue) all scripts and styles to be used throughout the plugin.
201 *
202 * @since 1.0.0
203 */
204 public function register_scripts() {
205 wp_register_style( 'audioigniter', $this->plugin_url() . 'player/build/style.css', array(), $this->version );
206 wp_register_style( 'audioigniter-admin', $this->plugin_url() . 'assets/css/admin-styles.css', array(), $this->version );
207
208 wp_register_script( 'audioigniter', $this->plugin_url() . 'player/build/app.js', array(), $this->version, true );
209 wp_register_script( 'audioigniter-admin', $this->plugin_url() . 'assets/js/audioigniter.js', array(), $this->version, true );
210
211 wp_localize_script( 'audioigniter', 'aiStrings', apply_filters( 'audioigniter_aiStrings', array(
212 /* translators: %s is the track's title. */
213 'play_title' => esc_html__( 'Play %s', 'audioigniter' ),
214 /* translators: %s is the track's title. */
215 'pause_title' => esc_html__( 'Pause %s', 'audioigniter' ),
216 'previous' => esc_html__( 'Previous track', 'audioigniter' ),
217 'next' => esc_html__( 'Next track', 'audioigniter' ),
218 'toggle_list_repeat' => esc_html__( 'Toggle track listing repeat', 'audioigniter' ),
219 'toggle_track_repeat' => esc_html__( 'Toggle track repeat' ),
220 'toggle_list_visible' => esc_html__( 'Toggle track listing visibility', 'audioigniter' ),
221 'buy_track' => esc_html__( 'Buy this track', 'audioigniter' ),
222 'download_track' => esc_html__( 'Download this track', 'audioigniter' ),
223 'volume_up' => esc_html__( 'Volume Up', 'audioigniter' ),
224 'volume_down' => esc_html__( 'Volume Down', 'audioigniter' ),
225 'open_track_lyrics' => esc_html__( 'Open track lyrics', 'audioigniter' ),
226 'set_playback_rate' => esc_html__( 'Set playback rate', 'audioigniter' ),
227 'skip_forward' => esc_html__( 'Skip forward', 'audioigniter' ),
228 'skip_backward' => esc_html__( 'Skip backward', 'audioigniter' ),
229 'shuffle' => esc_html__( 'Shuffle', 'audioigniter' ),
230 ) ) );
231
232 wp_localize_script( 'audioigniter-admin', 'ai_scripts', array(
233 'messages' => array(
234 'confirm_clear_tracks' => esc_html__( 'Do you really want to remove all tracks? (This will not delete your audio files).', 'audioigniter' ),
235 'media_title_upload' => esc_html__( 'Select or upload audio media', 'audioigniter' ),
236 'media_title_upload_cover' => esc_html__( 'Select a cover image', 'audioigniter' ),
237 ),
238 ) );
239 }
240
241 /**
242 * Enqueues frontend scripts and styles.
243 *
244 * @since 1.0.0
245 */
246 public function enqueue_scripts() {
247 wp_enqueue_style( 'audioigniter' );
248 wp_enqueue_script( 'audioigniter' );
249 }
250
251 /**
252 * Enqueues admin scripts and styles.
253 *
254 * @since 1.0.0
255 */
256 public function enqueue_admin_scripts( $hook ) {
257 $screen = get_current_screen();
258
259 if ( 'post' === $screen->base && $screen->post_type === $this->post_type ) {
260 wp_enqueue_media();
261 wp_enqueue_style( 'audioigniter-admin' );
262 wp_enqueue_script( 'audioigniter-admin' );
263 }
264 }
265
266 /**
267 * Post types registration.
268 *
269 * @since 1.0.0
270 */
271 public function register_post_types() {
272 $labels = array(
273 'name' => esc_html_x( 'Playlists', 'post type general name', 'audioigniter' ),
274 'singular_name' => esc_html_x( 'Playlist', 'post type singular name', 'audioigniter' ),
275 'menu_name' => esc_html_x( 'Playlists', 'admin menu', 'audioigniter' ),
276 'name_admin_bar' => esc_html_x( 'Playlist', 'add new on admin bar', 'audioigniter' ),
277 'add_new' => esc_html__( 'Add New Playlist', 'audioigniter' ),
278 'add_new_item' => esc_html__( 'Add New Playlist', 'audioigniter' ),
279 'edit_item' => esc_html__( 'Edit Playlist', 'audioigniter' ),
280 'new_item' => esc_html__( 'New Playlist', 'audioigniter' ),
281 'view_item' => esc_html__( 'View Playlist', 'audioigniter' ),
282 'search_items' => esc_html__( 'Search Playlists', 'audioigniter' ),
283 'not_found' => esc_html__( 'No playlists found', 'audioigniter' ),
284 'not_found_in_trash' => esc_html__( 'No playlists found in the trash', 'audioigniter' ),
285 );
286
287 $args = array(
288 'labels' => $labels,
289 'singular_label' => esc_html_x( 'Playlist', 'post type singular name', 'audioigniter' ),
290 'public' => false,
291 'show_ui' => true,
292 'capability_type' => 'post',
293 'hierarchical' => false,
294 'has_archive' => false,
295 'supports' => array( 'title' ),
296 'menu_icon' => 'dashicons-controls-volumeon',
297 );
298
299 register_post_type( $this->post_type, $args );
300 }
301
302
303 /**
304 * Registers metaboxes for the ai_playlist post type.
305 *
306 * @since 1.0.0
307 */
308 public function add_meta_boxes() {
309 add_meta_box( 'ai-meta-box-tracks', esc_html__( 'Tracks', 'audioigniter' ), array( $this, 'metabox_tracks' ), $this->post_type, 'normal', 'high' );
310 add_meta_box( 'ai-meta-box-settings', esc_html__( 'Settings', 'audioigniter' ), array( $this, 'metabox_settings' ), $this->post_type, 'normal', 'high' );
311 add_meta_box( 'ai-meta-box-shortcode', esc_html__( 'Shortcode', 'audioigniter' ), array( $this, 'metabox_shortcode' ), $this->post_type, 'normal', 'high' );
312 }
313
314 /**
315 * Echoes the Tracks metabox markup.
316 *
317 * @since 1.0.0
318 *
319 * @param WP_Post $object
320 * @param array $box
321 */
322 public function metabox_tracks( $object, $box ) {
323 $tracks = $this->get_post_meta( $object->ID, '_audioigniter_tracks', array() );
324
325 wp_nonce_field( basename( __FILE__ ), $object->post_type . '_nonce' );
326 ?>
327
328 <?php $this->metabox_tracks_header(); ?>
329
330 <div class="ai-container">
331 <?php $this->metabox_tracks_field_controls(); ?>
332
333 <?php $container_classes = apply_filters( 'audioigniter_metabox_tracks_container_classes', array( 'ai-fields-container' ) ); ?>
334
335 <div class="<?php echo esc_attr( implode( ' ', $container_classes ) ); ?>">
336 <?php
337 if ( ! empty( $tracks ) ) {
338 foreach ( $tracks as $track ) {
339 $this->metabox_tracks_repeatable_track_field( $track );
340 }
341 } else {
342 $this->metabox_tracks_repeatable_track_field();
343 }
344 ?>
345 </div>
346
347 <?php $this->metabox_tracks_field_controls(); ?>
348 </div>
349
350 <?php $this->metabox_tracks_footer(); ?>
351
352 <input type="hidden" name="ai_nonce" id="ai_nonce" value="<?php echo esc_attr( wp_create_nonce( self::plugin_basename() ) ); ?>"/>
353 <?php
354 }
355
356
357 /**
358 * Echoes the Tracks metabox header.
359 *
360 * @since 1.0.0
361 */
362 protected function metabox_tracks_header() {
363 ?>
364 <div class="ai-header ai-brand-module">
365 <div class="ai-row">
366 <div class="ai-col-left">
367 <a href="https://www.cssigniter.com/plugins/audioigniter?utm_source=dashboard&utm_medium=link&utm_content=audioigniter&utm_campaign=logo" target="_blank" class="ai-logo">
368 <img
369 src="<?php echo esc_url( $this->plugin_url() . 'assets/images/logo.svg' ); ?>"
370 alt="<?php esc_attr_e( 'AudioIgniter Logo', 'audioigniter' ); ?>"
371 >
372 </a>
373 </div>
374
375 <?php if ( apply_filters( 'audioigniter_metabox_tracks_show_upgrade_button', true ) ) : ?>
376 <div class="ai-col-right">
377 <div class="ai-brand-module-actions">
378 <a href="https://www.cssigniter.com/plugins/audioigniter?utm_source=dashboard&utm_medium=link&utm_content=audioigniter&utm_campaign=upgrade-pro" class="ai-btn ai-btn-green" target="_blank">
379 <?php esc_html_e( 'Upgrade to Pro', 'audioigniter' ); ?>
380 </a>
381 </div>
382 </div>
383 <?php endif; ?>
384 </div>
385 </div>
386 <?php
387 }
388
389 /**
390 * Echoes the Tracks metabox footer.
391 *
392 * @since 1.0.0
393 */
394 protected function metabox_tracks_footer() {
395 ?>
396 <div class="ai-footer ai-brand-module">
397 <div class="ai-row">
398 <div class="ai-col-left">
399 <ul class="ai-list-inline ai-footer-links">
400 <?php
401 $links = apply_filters( 'audioigniter_metabox_tracks_footer_links', array(
402 'support' => array(
403 'title' => __( 'Support', 'audioigniter' ),
404 'url' => 'https://wordpress.org/support/plugin/audioigniter',
405 ),
406 'documentation' => array(
407 'title' => __( 'Documentation', 'audioigniter' ),
408 'url' => 'https://www.cssigniter.com/docs/audioigniter/',
409 ),
410 'rate_plugin' => array(
411 'title' => __( 'Rate this plugin', 'audioigniter' ),
412 'url' => 'https://wordpress.org/support/view/plugin-reviews/audioigniter',
413 ),
414 ) );
415
416 foreach ( $links as $link ) {
417 if ( empty( $link['url'] ) || empty( $link['title'] ) ) {
418 continue;
419 }
420
421 echo sprintf( '<li><a href="%s" target="_blank">%s</a></li>',
422 esc_url( $link['url'] ),
423 esc_html( $link['title'] )
424 );
425 }
426 ?>
427 </ul>
428 </div>
429
430 <div class="ai-col-right">
431 <?php
432 $url = 'https://www.cssigniter.com/plugins/audioigniter?utm_source=dashboard&utm_medium=link&utm_content=audioigniter&utm_campaign=footer-link';
433 /* translators: %s is a URL. */
434 $copy = sprintf( __( 'Thank you for creating with <a href="%s" target="_blank">AudioIgniter</a>', 'audioigniter' ),
435 esc_url( $url )
436 );
437 ?>
438 <div class="ai-brand-module-actions">
439 <p class="ai-note"><?php echo wp_kses( $copy, array( 'a' => array( 'href' => true, 'target' => true ) ) ); ?></p>
440 </div>
441 </div>
442 </div>
443 </div>
444 <?php
445 }
446
447 protected function metabox_tracks_repeatable_track_field( $track = array() ) {
448 $track = wp_parse_args( $track, self::get_default_track_values() );
449
450 $cover_id = $track['cover_id'];
451 $title = $track['title'];
452 $artist = $track['artist'];
453 $track_url = $track['track_url'];
454 $buy_link = $track['buy_link'];
455 $download_url = $track['download_url'];
456
457 $cover_url = wp_get_attachment_image_src( intval( $cover_id ), 'thumbnail' );
458 if ( ! empty( $cover_url[0] ) ) {
459 $cover_url = $cover_url[0];
460 $cover_data = wp_prepare_attachment_for_js( intval( $cover_id ) );
461 } else {
462 $cover_url = '';
463 $cover_data = '';
464 }
465
466 $uid = uniqid();
467
468 $field_classes = apply_filters( 'audioigniter_metabox_track_classes', array( 'ai-field-repeatable' ), $track_url );
469 ?>
470 <div class="<?php echo esc_attr( implode( ' ', $field_classes ) ); ?>" data-uid="<?php echo esc_attr( $uid ); ?>">
471 <div class="ai-field-head">
472
473 <?php do_action( 'audioigniter_metabox_tracks_repeatable_track_field_before_title' ); ?>
474
475 <span class="ai-field-title"><?php echo wp_kses( $title, array() ); ?></span>
476
477 <button type="button" class="ai-field-toggle button-link">
478 <span class="screen-reader-text">
479 <?php esc_html_e( 'Toggle track visibility', 'audioigniter' ); ?>
480 </span>
481 <span class="toggle-indicator"></span>
482 </button>
483 </div>
484
485 <div class="ai-field-container">
486 <div class="ai-field-cover">
487 <a href="#" class="ai-field-upload-cover <?php echo ! empty( $cover_url ) ? 'ai-has-cover' : ''; ?>">
488 <span class="ai-remove-cover">
489 <span class="screen-reader-text">
490 <?php esc_html_e( 'Remove Cover Image', 'audioigniter' ); ?>
491 </span>
492 <span class="dashicons dashicons-no-alt"></span>
493 </span>
494
495 <?php if ( ! empty( $cover_url ) ) : ?>
496 <img src="<?php echo esc_url( $cover_url ); ?>" alt="<?php echo esc_attr( $cover_data['alt'] ); ?>">
497 <?php else : ?>
498 <img src="#" alt="">
499 <?php endif; ?>
500
501 <div class="ai-field-cover-placeholder">
502 <span class="ai-cover-prompt">
503 <?php esc_html_e( 'Upload Cover', 'audioigniter' ); ?>
504 </span>
505 </div>
506 </a>
507
508 <input
509 type="hidden"
510 id="ai_playlist_tracks-<?php echo esc_attr( $uid ); ?>-cover_id"
511 name="ai_playlist_tracks[<?php echo esc_attr( $uid ); ?>][cover_id]"
512 value="<?php echo esc_attr( $cover_id ); ?>"
513 />
514 </div>
515
516 <div class="ai-field-split">
517 <div class="ai-form-field">
518 <label
519 for="ai_playlist_tracks-<?php echo esc_attr( $uid ); ?>-title"
520 class="screen-reader-text">
521 <?php esc_html_e( 'Title', 'audioigniter' ); ?>
522 </label>
523 <input
524 type="text"
525 id="ai_playlist_tracks-<?php echo esc_attr( $uid ); ?>-title"
526 class="ai-track-title"
527 name="ai_playlist_tracks[<?php echo esc_attr( $uid ); ?>][title]"
528 placeholder="<?php esc_attr_e( 'Title', 'audioigniter' ); ?>"
529 value="<?php echo esc_attr( $title ); ?>"
530 />
531 </div>
532 <div class="ai-form-field">
533 <label
534 for="ai_playlist_tracks-<?php echo esc_attr( $uid ); ?>-artist"
535 class="screen-reader-text">
536 <?php esc_html_e( 'Artist', 'audioigniter' ); ?>
537 </label>
538 <input
539 type="text"
540 id="ai_playlist_tracks-<?php echo esc_attr( $uid ); ?>-artist"
541 class="ai-track-artist"
542 name="ai_playlist_tracks[<?php echo esc_attr( $uid ); ?>][artist]"
543 placeholder="<?php esc_attr_e( 'Artist', 'audioigniter' ); ?>"
544 value="<?php echo esc_attr( $artist ); ?>"
545 />
546 </div>
547
548 <div class="ai-form-field">
549 <label
550 for="ai_playlist_tracks-<?php echo esc_attr( $uid ); ?>-buy_link"
551 class="screen-reader-text">
552 <?php esc_html_e( 'Buy link', 'audioigniter' ); ?>
553 </label>
554 <input
555 type="text"
556 id="ai_playlist_tracks-<?php echo esc_attr( $uid ); ?>-buy_link"
557 class="ai-track-buy-link"
558 name="ai_playlist_tracks[<?php echo esc_attr( $uid ); ?>][buy_link]"
559 placeholder="<?php esc_attr_e( 'Buy link', 'audioigniter' ); ?>"
560 value="<?php echo esc_url( $buy_link ); ?>"
561 />
562 </div>
563
564 <?php do_action( 'audioigniter_metabox_tracks_repeatable_track_fields_column_1', $track, $uid ); ?>
565 </div>
566
567 <div class="ai-field-split">
568 <div class="ai-form-field">
569 <label
570 for="ai_playlist_tracks-<?php echo esc_attr( $uid ); ?>-track_url"
571 class="screen-reader-text">
572 <?php esc_html_e( 'Audio file or radio stream', 'audioigniter' ); ?>
573 </label>
574
575 <div class="ai-form-field-addon">
576 <input
577 type="text"
578 id="ai_playlist_tracks-<?php echo esc_attr( $uid ); ?>-track_url"
579 class="ai-track-url"
580 name="ai_playlist_tracks[<?php echo esc_attr( $uid ); ?>][track_url]"
581 placeholder="<?php esc_attr_e( 'Audio file or radio stream', 'audioigniter' ); ?>"
582 value="<?php echo esc_url( $track_url ); ?>"
583 />
584 <button type="button" class="button ai-upload">
585 <?php esc_html_e( 'Upload', 'audioigniter' ); ?>
586 </button>
587
588 <?php do_action( 'audioigniter_metabox_tracks_repeatable_track_field_after_track_upload_button' ); ?>
589 </div>
590 </div>
591
592 <div class="ai-form-field">
593 <label
594 for="ai_playlist_tracks-<?php echo esc_attr( $uid ); ?>-download_url"
595 class="screen-reader-text">
596 <?php esc_html_e( 'Download URL', 'audioigniter' ); ?>
597 </label>
598 <input
599 type="text"
600 id="ai_playlist_tracks-<?php echo esc_attr( $uid ); ?>-download_url"
601 class="ai-track-download-url"
602 name="ai_playlist_tracks[<?php echo esc_attr( $uid ); ?>][download_url]"
603 placeholder="<?php esc_attr_e( 'Download URL', 'audioigniter' ); ?>"
604 value="<?php echo esc_url( $download_url ); ?>"
605 />
606 </div>
607
608 <?php do_action( 'audioigniter_metabox_tracks_repeatable_track_fields_column_2', $track, $uid ); ?>
609
610 <button type="button" class="button ai-remove-field">
611 <span class="dashicons dashicons-dismiss"></span>
612 <?php esc_html_e( 'Remove Track', 'audioigniter' ); ?>
613 </button>
614 </div>
615
616 </div>
617 </div>
618 <?php
619 }
620
621 protected function metabox_tracks_field_controls() {
622 ?>
623 <div class="ai-field-controls-wrap">
624 <div class="ai-field-controls">
625 <button type="button" class="button ai-add-field">
626 <span class="dashicons dashicons-plus-alt"></span>
627 <?php esc_html_e( 'Add Track', 'audioigniter' ); ?>
628 </button>
629
630 <?php do_action( 'audioigniter_metabox_tracks_field_controls' ); ?>
631
632 <button type="button" class="button ai-remove-all-fields">
633 <span class="dashicons dashicons-dismiss"></span>
634 <?php esc_html_e( 'Clear Playlist', 'audioigniter' ); ?>
635 </button>
636 </div>
637
638 <div class="ai-field-controls-visibility">
639 <a href="#" class="ai-fields-expand-all">
640 <?php esc_html_e( 'Expand All', 'audioigniter' ); ?>
641 </a>
642 <a href="#" class="ai-fields-collapse-all">
643 <?php esc_html_e( 'Collapse All', 'audioigniter' ); ?>
644 </a>
645 </div>
646 </div>
647 <?php
648 }
649
650 /**
651 * Echoes the Settings metabox markup.
652 *
653 * @version 1.4.0
654 * @since 1.0.0
655 *
656 * @param WP_Post $object
657 * @param array $box
658 */
659 public function metabox_settings( $object, $box ) {
660 $type = $this->get_post_meta( $object->ID, '_audioigniter_player_type', 'full' );
661 $numbers = $this->get_post_meta( $object->ID, '_audioigniter_show_numbers', 1 );
662 $numbers_reverse = $this->get_post_meta( $object->ID, '_audioigniter_show_numbers_reverse', 0 );
663 $thumb = $this->get_post_meta( $object->ID, '_audioigniter_show_covers', 1 );
664 $active_thumb = $this->get_post_meta( $object->ID, '_audioigniter_show_active_cover', 1 );
665 $artist = $this->get_post_meta( $object->ID, '_audioigniter_show_artist', 1 );
666 $buy_links = $this->get_post_meta( $object->ID, '_audioigniter_show_buy_links', 1 );
667 $buy_links_new_target = $this->get_post_meta( $object->ID, '_audioigniter_buy_links_new_target', 1 );
668 $cycle_tracks = $this->get_post_meta( $object->ID, '_audioigniter_cycle_tracks', 0 );
669 $track_listing = $this->get_post_meta( $object->ID, '_audioigniter_show_track_listing', 1 );
670 $track_listing_allow_toggle = $this->get_post_meta( $object->ID, '_audioigniter_allow_track_listing_toggle', 1 );
671 $track_listing_allow_loop = $this->get_post_meta( $object->ID, '_audioigniter_allow_track_listing_loop', 1 );
672 $credit = $this->get_post_meta( $object->ID, '_audioigniter_show_credit', 0 );
673 $limit_tracklisting_height = $this->get_post_meta( $object->ID, '_audioigniter_limit_tracklisting_height', 1 );
674 $tracklisting_height = $this->get_post_meta( $object->ID, '_audioigniter_tracklisting_height', 185 );
675 $volume = $this->get_post_meta( $object->ID, '_audioigniter_volume', 100 );
676 $max_width = $this->get_post_meta( $object->ID, '_audioigniter_max_width' );
677
678 wp_nonce_field( basename( __FILE__ ), $object->post_type . '_nonce' );
679 ?>
680 <div class="ai-module ai-module-settings">
681 <div class="ai-form-field-group">
682 <h3 class="ai-form-field-group-title"><?php esc_html_e( 'Player &amp; Track listing', 'audioigniter' ); ?></h3>
683
684 <div class="ai-form-field">
685 <div class="ai-player-type-message ai-info-box"></div>
686 <label for="_audioigniter_player_type">
687 <?php esc_html_e( 'Player Type', 'audioigniter' ); ?>
688 </label>
689
690 <select
691 class="widefat ai-form-select-player-type"
692 id="_audioigniter_player_type"
693 name="_audioigniter_player_type"
694 >
695 <?php foreach ( $this->get_player_types() as $player_key => $player_type ) : ?>
696 <option
697 value="<?php echo esc_attr( $player_key ); ?>"
698 data-no-support="<?php echo esc_attr( implode( ', ', $player_type['no-support'] ) ); ?>"
699 data-info="<?php echo esc_attr( $player_type['info'] ); ?>"
700 <?php selected( $type, $player_key ); ?>
701 >
702 <?php echo wp_kses( $player_type['label'], 'strip' ); ?>
703 </option>
704 <?php endforeach; ?>
705 </select>
706 </div>
707
708 <div class="ai-form-field">
709 <input
710 type="checkbox"
711 class="ai-checkbox"
712 id="_audioigniter_show_track_listing"
713 name="_audioigniter_show_track_listing"
714 value="1" <?php checked( $track_listing, true ); ?>
715 />
716
717 <label for="_audioigniter_show_track_listing">
718 <?php esc_html_e( 'Show track listing by default', 'audioigniter' ); ?>
719 </label>
720 </div>
721
722 <div class="ai-form-field">
723 <input
724 type="checkbox"
725 class="ai-checkbox"
726 id="_audioigniter_allow_track_listing_toggle"
727 name="_audioigniter_allow_track_listing_toggle"
728 value="1" <?php checked( $track_listing_allow_toggle, true ); ?>
729 />
730
731 <label for="_audioigniter_allow_track_listing_toggle">
732 <?php esc_html_e( 'Show track listing visibility toggle button', 'audioigniter' ); ?>
733 </label>
734 </div>
735
736 <div class="ai-form-field">
737 <input
738 type="checkbox"
739 class="ai-checkbox"
740 id="_audioigniter_show_numbers_revese"
741 name="_audioigniter_show_numbers_reverse"
742 value="1" <?php checked( $numbers_reverse, true ); ?>
743 />
744
745 <label for="_audioigniter_show_numbers_revese">
746 <?php esc_html_e( 'Reverse track order', 'audioigniter' ); ?>
747 </label>
748 </div>
749
750 <div class="ai-form-field">
751 <label for="_audioigniter_volume">
752 <?php esc_html_e( 'Starting volume', 'audioigniter' ); ?>
753 </label>
754
755 <input
756 type="number"
757 min="0"
758 max="100"
759 step="10"
760 id="_audioigniter_volume"
761 class="ai-track-title"
762 name="_audioigniter_volume"
763 placeholder="<?php esc_attr_e( '0-100', 'audioigniter' ); ?>"
764 value="<?php echo esc_attr( $volume ); ?>"
765 />
766
767 <p class="ai-field-help">
768 <?php esc_html_e( 'Enter a value between 0 and 100 in increments of 10', 'audioigniter' ); ?>
769 </p>
770 </div>
771
772 <div class="ai-form-field">
773 <input
774 type="checkbox"
775 class="ai-checkbox"
776 id="_audioigniter_limit_tracklisting_height"
777 name="_audioigniter_limit_tracklisting_height"
778 value="1" <?php checked( $limit_tracklisting_height, true ); ?>
779 />
780
781 <label for="_audioigniter_limit_tracklisting_height">
782 <?php esc_html_e( 'Limit track listing height', 'audioigniter' ); ?>
783 </label>
784 </div>
785
786 <div class="ai-form-field">
787 <label for="_audioigniter_tracklisting_height">
788 <?php esc_html_e( 'Track listing height', 'audioigniter' ); ?>
789 </label>
790
791 <input
792 type="number"
793 min="10"
794 step="5"
795 id="_audioigniter_tracklisting_height"
796 class="ai-track-title"
797 name="_audioigniter_tracklisting_height"
798 placeholder="<?php esc_attr_e( 'Track listing height', 'audioigniter' ); ?>"
799 value="<?php echo esc_attr( $tracklisting_height ); ?>"
800 />
801
802 <p class="ai-field-help">
803 <?php esc_html_e( 'Set a number of pixels', 'audioigniter' ); ?>
804 </p>
805 </div>
806
807 <div class="ai-form-field">
808 <label for="_audioigniter_max_width">
809 <?php esc_html_e( 'Maximum player width', 'audioigniter' ); ?>
810 </label>
811
812 <input
813 type="number"
814 id="_audioigniter_max_width"
815 class="ai-track-title"
816 name="_audioigniter_max_width"
817 placeholder="<?php esc_attr_e( 'Automatic width', 'audioigniter' ); ?>"
818 value="<?php echo esc_attr( $max_width ); ?>"
819 />
820
821 <p class="ai-field-help">
822 <?php esc_html_e( 'Set a number of pixels, or leave empty to automatically cover 100% of the available area (recommended).', 'audioigniter' ); ?>
823 </p>
824 </div>
825
826 <?php do_action( 'audioigniter_metabox_settings_group_player_track_listing_fields', $object, $box ); ?>
827 </div>
828
829 <div class="ai-form-field-group">
830 <h3 class="ai-form-field-group-title"><?php esc_html_e( 'Tracks', 'audioigniter' ); ?></h3>
831
832 <div class="ai-form-field">
833 <input
834 type="checkbox"
835 class="ai-checkbox"
836 id="_audioigniter_show_numbers"
837 name="_audioigniter_show_numbers"
838 value="1" <?php checked( $numbers, true ); ?>
839 />
840
841 <label for="_audioigniter_show_numbers">
842 <?php esc_html_e( 'Show track numbers in tracklist', 'audioigniter' ); ?>
843 </label>
844 </div>
845
846 <div class="ai-form-field">
847 <input
848 type="checkbox"
849 class="ai-checkbox"
850 id="_audioigniter_show_covers"
851 name="_audioigniter_show_covers"
852 value="1" <?php checked( $thumb, true ); ?>
853 />
854
855 <label for="_audioigniter_show_covers">
856 <?php esc_html_e( 'Show track covers in tracklist', 'audioigniter' ); ?>
857 </label>
858 </div>
859
860 <div class="ai-form-field">
861 <input
862 type="checkbox"
863 class="ai-checkbox"
864 id="_audioigniter_show_active_cover"
865 name="_audioigniter_show_active_cover"
866 value="1" <?php checked( $active_thumb, true ); ?>
867 />
868
869 <label for="_audioigniter_show_active_cover">
870 <?php esc_html_e( "Show active track's cover", 'audioigniter' ); ?>
871 </label>
872 </div>
873
874 <div class="ai-form-field">
875 <input
876 type="checkbox"
877 class="ai-checkbox"
878 id="_audioigniter_show_artist"
879 name="_audioigniter_show_artist"
880 value="1" <?php checked( $artist, true ); ?>
881 />
882
883 <label for="_audioigniter_show_artist">
884 <?php esc_html_e( 'Show artist names', 'audioigniter' ); ?>
885 </label>
886 </div>
887
888 <div class="ai-form-field">
889 <input
890 type="checkbox"
891 class="ai-checkbox"
892 id="_audioigniter_show_buy_links"
893 name="_audioigniter_show_buy_links"
894 value="1" <?php checked( $buy_links, true ); ?>
895 />
896
897 <label for="_audioigniter_show_buy_links">
898 <?php esc_html_e( 'Show track extra buttons (buy link, download button etc)', 'audioigniter' ); ?>
899 </label>
900 </div>
901
902 <div class="ai-form-field">
903 <input
904 type="checkbox"
905 class="ai-checkbox"
906 id="_audioigniter_buy_links_new_target"
907 name="_audioigniter_buy_links_new_target"
908 value="1" <?php checked( $buy_links_new_target, true ); ?>
909 />
910
911 <label for="_audioigniter_buy_links_new_target">
912 <?php esc_html_e( 'Open buy links in new window', 'audioigniter' ); ?>
913 </label>
914 </div>
915
916 <?php do_action( 'audioigniter_metabox_settings_group_tracks_fields', $object, $box ); ?>
917 </div>
918
919 <div class="ai-form-field-group">
920 <h3 class="ai-form-field-group-title"><?php esc_html_e( 'Track &amp; Track listing repeat', 'audioigniter' ); ?></h3>
921
922 <div class="ai-form-field">
923 <input
924 type="checkbox"
925 class="ai-checkbox"
926 id="_audioigniter_cycle_tracks"
927 name="_audioigniter_cycle_tracks"
928 value="1" <?php checked( $cycle_tracks, true ); ?>
929 />
930
931 <label for="_audioigniter_cycle_tracks">
932 <?php esc_html_e( 'Repeat track listing enabled by default', 'audioigniter' ); ?>
933 </label>
934 </div>
935
936 <div class="ai-form-field">
937 <input
938 type="checkbox"
939 class="ai-checkbox"
940 id="_audioigniter_allow_track_listing_loop"
941 name="_audioigniter_allow_track_listing_loop"
942 value="1" <?php checked( $track_listing_allow_loop, true ); ?>
943 />
944
945 <label for="_audioigniter_allow_track_listing_loop">
946 <?php esc_html_e( 'Show track listing repeat toggle button', 'audioigniter' ); ?>
947 </label>
948 </div>
949
950 <?php do_action( 'audioigniter_metabox_settings_group_player_track_track_listing_repeat_fields', $object, $box ); ?>
951 </div>
952
953 <div class="ai-form-field">
954 <input
955 type="checkbox"
956 class="ai-checkbox"
957 id="_audioigniter_show_credit"
958 name="_audioigniter_show_credit"
959 value="1" <?php checked( $credit, true ); ?>
960 />
961
962 <label for="_audioigniter_show_credit">
963 <?php esc_html_e( 'Show "Powered by AudioIgniter" link', 'audioigniter' ); ?>
964 </label>
965
966 <p class="ai-field-help">
967 <?php esc_html_e( "We've put a great deal of effort into building this plugin. If you feel like it, let others know about it by enabling this option.", 'audioigniter' ); ?>
968 </p>
969 </div>
970 </div>
971 <?php
972 }
973
974 /**
975 * Echoes the Shortcode metabox markup.
976 *
977 * @since 1.0.0
978 *
979 * @param WP_Post $object
980 * @param array $box
981 */
982 public function metabox_shortcode( $object, $box ) {
983 ?>
984 <div class="ai-module ai-module-shortcode">
985 <div class="ai-form-field">
986 <label for="ai_shortcode">
987 <?php esc_html_e( 'Grab the shortcode', 'audioigniter' ); ?>
988 </label>
989
990 <input
991 type="text"
992 class="code"
993 id="ai_shortcode"
994 name="ai_shortcode"
995 value="<?php echo esc_attr( sprintf( '[ai_playlist id="%s"]', $object->ID ) ); ?>"
996 />
997
998 </div>
999 </div>
1000 <?php
1001 }
1002
1003 /**
1004 * Returns the available player types and their data.
1005 *
1006 * @version 1.4.0
1007 * @since 1.4.0
1008 *
1009 * @return array
1010 */
1011 public function get_player_types() {
1012 // Each player type has a number of settings that it might not support
1013 // E.g. "Simple Player" does not support track listing visibility, covers
1014 // and others. Provide every setting that's not supported based on the `name`
1015 // attribute of each setting input (input, select, textarea), *without
1016 // the _audioigniter_ prefix* in the `no-support` array.
1017 // To allow support for every setting simply set `no-support` to an empty array.
1018
1019 $player_types = array(
1020 'full' => array(
1021 'label' => __( 'Full Player', 'audioigniter' ),
1022 'no-support' => array(),
1023 'info' => '',
1024 ),
1025 'simple' => array(
1026 'label' => __( 'Simple Player', 'audioigniter' ),
1027 'no-support' => array(
1028 'show_track_listing',
1029 'show_covers',
1030 'show_active_cover',
1031 'limit_tracklisting_height',
1032 'tracklisting_height',
1033 'allow_track_listing_loop',
1034 'allow_track_listing_toggle',
1035 'skip_amount',
1036 'initial_track',
1037 ),
1038 'info' => '',
1039 ),
1040 );
1041
1042 return apply_filters( 'audioigniter_player_types', $player_types );
1043 }
1044
1045 public function save_post( $post_id ) {
1046 if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) { return false; }
1047 if ( isset( $_POST['post_view'] ) && 'list' === $_POST['post_view'] ) { return false; }
1048 if ( ! isset( $_POST['post_type'] ) || $_POST['post_type'] !== $this->post_type ) { return false; }
1049 if ( ! isset( $_POST[ $this->post_type . '_nonce' ] ) || ! wp_verify_nonce( $_POST[ $this->post_type . '_nonce' ], basename( __FILE__ ) ) ) { return false; }
1050 $post_type_obj = get_post_type_object( $this->post_type );
1051 if ( ! current_user_can( $post_type_obj->cap->edit_post, $post_id ) ) { return false; }
1052
1053 update_post_meta( $post_id, '_audioigniter_tracks', $this->sanitizer->metabox_playlist( $_POST['ai_playlist_tracks'], $post_id ) );
1054
1055 update_post_meta( $post_id, '_audioigniter_show_numbers', $this->sanitizer->checkbox_ref( $_POST['_audioigniter_show_numbers'] ) );
1056 update_post_meta( $post_id, '_audioigniter_show_numbers_reverse', $this->sanitizer->checkbox_ref( $_POST['_audioigniter_show_numbers_reverse'] ) );
1057 update_post_meta( $post_id, '_audioigniter_show_covers', $this->sanitizer->checkbox_ref( $_POST['_audioigniter_show_covers'] ) );
1058 update_post_meta( $post_id, '_audioigniter_show_active_cover', $this->sanitizer->checkbox_ref( $_POST['_audioigniter_show_active_cover'] ) );
1059 update_post_meta( $post_id, '_audioigniter_show_artist', $this->sanitizer->checkbox_ref( $_POST['_audioigniter_show_artist'] ) );
1060 update_post_meta( $post_id, '_audioigniter_show_buy_links', $this->sanitizer->checkbox_ref( $_POST['_audioigniter_show_buy_links'] ) );
1061 update_post_meta( $post_id, '_audioigniter_buy_links_new_target', $this->sanitizer->checkbox_ref( $_POST['_audioigniter_buy_links_new_target'] ) );
1062 update_post_meta( $post_id, '_audioigniter_cycle_tracks', $this->sanitizer->checkbox_ref( $_POST['_audioigniter_cycle_tracks'] ) );
1063 update_post_meta( $post_id, '_audioigniter_show_track_listing', $this->sanitizer->checkbox_ref( $_POST['_audioigniter_show_track_listing'] ) );
1064 update_post_meta( $post_id, '_audioigniter_allow_track_listing_toggle', $this->sanitizer->checkbox_ref( $_POST['_audioigniter_allow_track_listing_toggle'] ) );
1065 update_post_meta( $post_id, '_audioigniter_allow_track_listing_loop', $this->sanitizer->checkbox_ref( $_POST['_audioigniter_allow_track_listing_loop'] ) );
1066 update_post_meta( $post_id, '_audioigniter_player_type', $this->sanitizer->player_type( $_POST['_audioigniter_player_type'] ) );
1067 update_post_meta( $post_id, '_audioigniter_show_credit', $this->sanitizer->checkbox_ref( $_POST['_audioigniter_show_credit'] ) );
1068 update_post_meta( $post_id, '_audioigniter_limit_tracklisting_height', $this->sanitizer->checkbox_ref( $_POST['_audioigniter_limit_tracklisting_height'] ) );
1069 update_post_meta( $post_id, '_audioigniter_tracklisting_height', intval( $_POST['_audioigniter_tracklisting_height'] ) );
1070 update_post_meta( $post_id, '_audioigniter_volume', intval( $_POST['_audioigniter_volume'] ) );
1071 update_post_meta( $post_id, '_audioigniter_max_width', $this->sanitizer->intval_or_empty( $_POST['_audioigniter_max_width'] ) );
1072
1073 /**
1074 * @since 1.4.0
1075 */
1076 do_action( 'audioigniter_save_post', $post_id );
1077 }
1078
1079 public static function get_default_track_values() {
1080 return apply_filters( 'audioigniter_default_track_values', array(
1081 'cover_id' => '',
1082 'title' => '',
1083 'artist' => '',
1084 'track_url' => '',
1085 'buy_link' => '',
1086 'download_url' => '',
1087 ) );
1088 }
1089
1090 public function register_image_sizes() {
1091 add_image_size( 'audioigniter_cover', 560, 560, true );
1092 }
1093
1094 public function register_widgets() {
1095 $widgets = apply_filters( 'audioigniter_register_widgets', array() );
1096
1097 foreach ( $widgets as $class => $file ) {
1098 require_once( $file );
1099 register_widget( $class );
1100 }
1101 }
1102
1103 public function register_shortcodes() {
1104 add_shortcode( 'ai_playlist', array( $this, 'shortcode_ai_playlist' ) );
1105 }
1106
1107 /**
1108 * Checks whether passed post object or ID is an AudioIgniter playlist.
1109 *
1110 * @version 1.4.0
1111 * @since 1.4.0
1112 *
1113 * @param int|WP_Post $post Post ID or post object.
1114 *
1115 * @return bool
1116 */
1117 public function is_playlist( $post ) {
1118 $post = get_post( $post );
1119
1120 if ( is_wp_error( $post ) || empty( $post ) || is_null( $post ) || $post->post_type !== $this->post_type ) {
1121 return false;
1122 }
1123
1124 return true;
1125 }
1126
1127 /**
1128 * Returns a data attributes array for the given playlist.
1129 *
1130 * @version 1.4.0
1131 * @since 1.4.0
1132 *
1133 * @param int $post_id Post ID.
1134 *
1135 * @return array
1136 */
1137 public function get_playlist_data_attributes_array( $post_id ) {
1138 $post_id = intval( $post_id );
1139
1140 if ( ! $this->is_playlist( $post_id ) ) {
1141 return array();
1142 }
1143
1144 $attrs = array(
1145 'data-player-type' => $this->get_post_meta( $post_id, '_audioigniter_player_type', 'full' ),
1146 'data-tracks-url' => add_query_arg( array( 'audioigniter_playlist_id' => $post_id ), home_url( '/' ) ),
1147 'data-display-track-no' => $this->convert_bool_string( $this->get_post_meta( $post_id, '_audioigniter_show_numbers', 1 ) ),
1148 'data-reverse-track-order' => $this->convert_bool_string( $this->get_post_meta( $post_id, '_audioigniter_show_numbers_reverse', 0 ) ),
1149 'data-display-tracklist-covers' => $this->convert_bool_string( $this->get_post_meta( $post_id, '_audioigniter_show_covers', 1 ) ),
1150 'data-display-active-cover' => $this->convert_bool_string( $this->get_post_meta( $post_id, '_audioigniter_show_active_cover', 1 ) ),
1151 'data-display-artist-names' => $this->convert_bool_string( $this->get_post_meta( $post_id, '_audioigniter_show_artist', 1 ) ),
1152 'data-display-buy-buttons' => $this->convert_bool_string( $this->get_post_meta( $post_id, '_audioigniter_show_buy_links', 1 ) ),
1153 'data-buy-buttons-target' => $this->convert_bool_string( $this->get_post_meta( $post_id, '_audioigniter_buy_links_new_target', 1 ) ),
1154 'data-cycle-tracks' => $this->convert_bool_string( $this->get_post_meta( $post_id, '_audioigniter_cycle_tracks', 0 ) ),
1155 'data-display-credits' => $this->convert_bool_string( $this->get_post_meta( $post_id, '_audioigniter_show_credit', 1 ) ),
1156 'data-display-tracklist' => $this->convert_bool_string( $this->get_post_meta( $post_id, '_audioigniter_show_track_listing', 1 ) ),
1157 'data-allow-tracklist-toggle' => $this->convert_bool_string( $this->get_post_meta( $post_id, '_audioigniter_allow_track_listing_toggle', 1 ) ),
1158 'data-allow-tracklist-loop' => $this->convert_bool_string( $this->get_post_meta( $post_id, '_audioigniter_allow_track_listing_loop', 1 ) ),
1159 'data-limit-tracklist-height' => $this->convert_bool_string( $this->get_post_meta( $post_id, '_audioigniter_limit_tracklisting_height', 1 ) ),
1160 'data-volume' => intval( $this->get_post_meta( $post_id, '_audioigniter_volume', 100 ) ),
1161 'data-tracklist-height' => intval( $this->get_post_meta( $post_id, '_audioigniter_tracklisting_height', 185 ) ),
1162 'data-max-width' => $this->get_post_meta( $post_id, '_audioigniter_max_width' ),
1163 );
1164
1165 return apply_filters( 'audioigniter_get_playlist_data_attributes_array', $attrs, $post_id );
1166 }
1167
1168 /**
1169 * Returns the output of the [ai_playlist] shortcode.
1170 *
1171 * @version 1.4.0
1172 * @since 1.0.0
1173 *
1174 * @param array $atts The shortcode attributes.
1175 * @param string $content Content, when used with a shortcode closing tag.
1176 * @param string $tag The shortcode name used to reach this function.
1177 *
1178 * @return string
1179 */
1180 public function shortcode_ai_playlist( $atts, $content, $tag ) {
1181 $atts = shortcode_atts( array(
1182 'id' => '',
1183 'class' => '',
1184 ), $atts, $tag );
1185
1186 $id = intval( $atts['id'] );
1187 $class_name = $atts['class'];
1188
1189 if ( ! $this->is_playlist( $id ) ) {
1190 return '';
1191 }
1192
1193 $post = get_post( $id );
1194
1195 $params = apply_filters( 'audioigniter_shortcode_data_attributes_array', $this->get_playlist_data_attributes_array( $id ), $id, $post );
1196 $params = array_filter( $params, array( $this->sanitizer, 'array_filter_empty_null' ) );
1197 $params = $this->sanitizer->html_data_attributes_array( $params );
1198
1199 // Returning a truthy value from the filter, will short-circuit execution of the shortcode.
1200 if ( false !== apply_filters( 'audioigniter_shortcode_shortcircuit', false, $id, $post, $params ) ) {
1201 return '';
1202 }
1203
1204 $data = '';
1205 foreach ( $params as $attribute => $value ) {
1206 $data .= sprintf( '%s="%s" ', sanitize_key( $attribute ), esc_attr( $value ) );
1207 }
1208
1209 $player_classes = array_merge( array(
1210 'audioigniter-root',
1211 ), explode( ' ', $class_name ) );
1212
1213 $output = sprintf( '<div id="audioigniter-%s" class="%s" %s></div>',
1214 esc_attr( $id ),
1215 esc_attr( implode( ' ', $player_classes ) ),
1216 $data
1217 );
1218
1219 return $output;
1220 }
1221
1222 public function convert_bool_string( $value ) {
1223 if ( $value ) {
1224 return 'true';
1225 }
1226
1227 return 'false';
1228 }
1229
1230 public function register_playlist_endpoint() {
1231 add_rewrite_tag( '%audioigniter_playlist_id%', '([0-9]+)' );
1232 add_rewrite_rule( '^audioigniter/playlist/([0-9]+)/?', 'index.php?audioigniter_playlist_id=$matches[1]', 'bottom' );
1233 }
1234
1235 public function handle_playlist_endpoint() {
1236 global $wp_query;
1237
1238 $playlist_id = $wp_query->get( 'audioigniter_playlist_id' );
1239
1240 if ( empty( $playlist_id ) ) {
1241 return;
1242 }
1243
1244 $playlist_id = intval( $playlist_id );
1245 $post = get_post( $playlist_id );
1246
1247 if ( empty( $post ) || $post->post_type !== $this->post_type ) {
1248 wp_send_json_error( __( "ID doesn't match a playlist", 'audioigniter' ) );
1249 }
1250
1251 $response = array();
1252 $tracks = $this->get_post_meta( $playlist_id, '_audioigniter_tracks', array() );
1253
1254 foreach ( $tracks as $track ) {
1255 $track = wp_parse_args( $track, self::get_default_track_values() );
1256 $track_response = array();
1257
1258 $track_response['title'] = $track['title'];
1259 $track_response['subtitle'] = $track['artist'];
1260 $track_response['audio'] = $track['track_url'];
1261 $track_response['buyUrl'] = $track['buy_link'];
1262 $track_response['downloadUrl'] = $track['download_url'];
1263 $track_response['downloadFilename'] = $this->get_filename_from_url( $track['download_url'] );
1264
1265 if ( ! $track_response['downloadFilename'] ) {
1266 $track_response['downloadFilename'] = $track_response['downloadUrl'];
1267 }
1268
1269 $cover_url = wp_get_attachment_image_src( intval( $track['cover_id'] ), 'audioigniter_cover' );
1270 if ( ! empty( $cover_url[0] ) ) {
1271 $cover_url = $cover_url[0];
1272 } else {
1273 $cover_url = '';
1274 }
1275
1276 $track_response['cover'] = $cover_url;
1277
1278 $track_response = apply_filters( 'audioigniter_playlist_endpoint_track', $track_response, $track, $playlist_id, $post );
1279
1280 $response[] = $track_response;
1281 }
1282
1283 wp_send_json( $response );
1284 }
1285
1286 function get_filename_from_url( $url ) {
1287 $struct = wp_parse_url( $url );
1288
1289 if ( ! empty( $struct['path'] ) ) {
1290 return basename( $struct['path'] );
1291 }
1292
1293 return '';
1294 }
1295
1296 public function get_all_playlists( $orderby = 'date', $order = 'DESC' ) {
1297 $q = new WP_Query( array(
1298 'post_type' => $this->post_type,
1299 'posts_per_page' => - 1,
1300 'orderby' => $orderby,
1301 'order' => $order,
1302 ) );
1303
1304 return $q->posts;
1305 }
1306
1307 public function get_post_meta( $post_id, $key, $default = '' ) {
1308 $keys = get_post_custom_keys( $post_id );
1309
1310 $value = $default;
1311
1312 if ( is_array( $keys ) && in_array( $key, $keys, true ) ) {
1313 $value = get_post_meta( $post_id, $key, true );
1314 }
1315
1316 return $value;
1317 }
1318
1319 public function plugin_activated() {
1320 if ( ! current_user_can( 'activate_plugins' ) ) {
1321 return;
1322 }
1323
1324 $this->register_post_types();
1325
1326 do_action( 'audioigniter_activated' );
1327
1328 flush_rewrite_rules();
1329 }
1330
1331 public function plugin_deactivated() {
1332 if ( ! current_user_can( 'activate_plugins' ) ) {
1333 return;
1334 }
1335
1336 unregister_post_type( $this->post_type );
1337
1338 do_action( 'audioigniter_deactivated' );
1339
1340 flush_rewrite_rules();
1341 }
1342
1343 public static function plugin_basename() {
1344 return plugin_basename( __FILE__ );
1345 }
1346
1347 public function plugin_url() {
1348 return self::$plugin_url;
1349 }
1350
1351 public function plugin_path() {
1352 return self::$plugin_path;
1353 }
1354 }
1355
1356
1357 /**
1358 * Main instance of AudioIgniter.
1359 *
1360 * Returns the working instance of AudioIgniter. No need for globals.
1361 *
1362 * @since 1.0.0
1363 * @return AudioIgniter
1364 */
1365 function AudioIgniter() {
1366 return AudioIgniter::instance();
1367 }
1368
1369 add_action( 'plugins_loaded', array( AudioIgniter(), 'plugin_setup' ) );
1370 register_activation_hook( __FILE__, array( AudioIgniter(), 'plugin_activated' ) );
1371 register_deactivation_hook( __FILE__, array( AudioIgniter(), 'plugin_deactivated' ) );
1372