PluginProbe
AudioIgniter Music Player / 1.9.0
AudioIgniter Music Player v1.9.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 1.9.0, at audioigniter.php

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