PluginProbe
AudioIgniter Music Player / 2.0.1
AudioIgniter Music Player v2.0.1
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 2.0.1, at audioigniter.php

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