PluginProbe
AudioIgniter Music Player / 2.0.0
AudioIgniter Music Player v2.0.0
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.0, at audioigniter.php

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