PluginProbe
AudioIgniter Music Player / trunk
AudioIgniter Music Player vtrunk
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 trunk, at audioigniter.php

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