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

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

1,056 lines 33.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Plugin Name: AudioIgniter
4 * Plugin URI: https://www.cssigniter.com/ignite/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.0.1
9 * Text Domain: audioigniter
10 * Domain Path: languages
11 *
12 * AudioIgniter is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation, either version 2 of the License, or
15 * any later version.
16 *
17 * AudioIgniter Downloads is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with AudioIgniter. If not, see <http://www.gnu.org/licenses/>.
24 *
25 */
26
27 if ( ! defined( 'ABSPATH' ) ) {
28 exit;
29 }
30
31
32 class AudioIgniter {
33
34 /**
35 * AudioIgniter version.
36 *
37 * @var string
38 * @since 1.0.0
39 */
40 public static $version = '1.0.1';
41
42 /**
43 * Instance of this class.
44 *
45 * @var AudioIgniter
46 * @since 1.0.0
47 */
48 protected static $instance = null;
49
50 /**
51 * Sanitizer instance.
52 *
53 * @var AudioIgniter_Sanitizer
54 * @since 1.0.0
55 */
56 public $sanitizer = null;
57
58 /**
59 * The URL directory path (with trailing slash) of the main plugin file.
60 *
61 * @var string
62 * @since 1.0.0
63 */
64 protected static $plugin_url = '';
65
66 /**
67 * The filesystem directory path (with trailing slash) of the main plugin file.
68 *
69 * @var string
70 * @since 1.0.0
71 */
72 protected static $plugin_path = '';
73
74
75 /**
76 * Playlist post type name.
77 *
78 * @var string
79 * @since 1.0.0
80 */
81 public $post_type = 'ai_playlist';
82
83
84
85 /**
86 * AudioIgniter Instance.
87 *
88 * Instantiates or reuses an instance of AudioIgniter.
89 *
90 * @since 1.0.0
91 * @static
92 * @see AudioIgniter()
93 * @return AudioIgniter - Single instance.
94 */
95 public static function instance() {
96 if ( is_null( self::$instance ) ) {
97 self::$instance = new self();
98 }
99 return self::$instance;
100 }
101
102
103 /**
104 * AudioIgniter constructor. Intentionally left empty so that instances can be created without
105 * re-loading of resources (e.g. scripts/styles), or re-registering hooks.
106 * http://wordpress.stackexchange.com/questions/70055/best-way-to-initiate-a-class-in-a-wp-plugin
107 * https://gist.github.com/toscho/3804204
108 *
109 * @since 1.0.0
110 */
111 public function __construct() {}
112
113 /**
114 * Kickstarts plugin loading.
115 *
116 * @since 1.0.0
117 */
118 public function plugin_setup() {
119 self::$plugin_url = plugin_dir_url( __FILE__ );
120 self::$plugin_path = plugin_dir_path( __FILE__ );
121
122 load_plugin_textdomain( 'audioigniter', false, dirname( self::plugin_basename() ) . '/languages' );
123
124 include_once( 'class-audioigniter-sanitizer.php' );
125 $this->sanitizer = new AudioIgniter_Sanitizer();
126
127 // Initialization needed in every request.
128 $this->init();
129
130 // Initialization needed in admin requests.
131 $this->admin_init();
132
133 // Initialization needed in frontend requests.
134 $this->frontend_init();
135
136 do_action( 'audioigniter_loaded' );
137 }
138
139 /**
140 * Registers actions that need to be run on both admin and frontend
141 *
142 * @since 1.0.0
143 */
144 protected function init() {
145 add_action( 'init', array( $this, 'register_post_types' ) );
146 add_action( 'init', array( $this, 'register_scripts' ) );
147 add_action( 'init', array( $this, 'register_playlist_endpoint' ) );
148 add_action( 'init', array( $this, 'register_image_sizes' ) );
149 add_action( 'init', array( $this, 'register_shortcodes' ) );
150 add_action( 'widgets_init', array( $this, 'register_widgets' ) );
151
152 do_action( 'audioigniter_init' );
153 }
154
155
156 /**
157 * Registers actions that need to be run on admin only.
158 *
159 * @since 1.0.0
160 */
161 protected function admin_init() {
162 if ( ! is_admin() ) {
163 return;
164 }
165
166 add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_scripts' ) );
167 add_action( 'add_meta_boxes', array( $this, 'add_meta_boxes' ) );
168 add_action( 'save_post', array( $this, 'save_post' ) );
169
170 do_action( 'audioigniter_admin_init' );
171 }
172
173 /**
174 * Registers actions that need to be run on frontend only.
175 *
176 * @since 1.0.0
177 */
178 protected function frontend_init() {
179 if ( is_admin() ) {
180 return;
181 }
182
183 add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
184 add_action( 'template_redirect', array( $this, 'handle_playlist_endpoint' ) );
185
186 do_action( 'audioigniter_frontend_init' );
187 }
188
189 /**
190 * Register (but not enqueue) all scripts and styles to be used throughout the plugin.
191 *
192 * @since 1.0.0
193 */
194 public function register_scripts() {
195 wp_register_style( 'audioigniter', $this->plugin_url() . 'player/build/style.css', array(), self::$version );
196 wp_register_style( 'audioigniter-admin', $this->plugin_url() . 'assets/css/admin-styles.css', array(), self::$version );
197
198 wp_register_script( 'audioigniter', $this->plugin_url() . 'player/build/app.js', array(), self::$version, true );
199 wp_register_script( 'audioigniter-admin', $this->plugin_url() . 'assets/js/audioigniter.js', array(), self::$version, true );
200
201 wp_localize_script( 'audioigniter-admin', 'ai_scripts', array(
202 'messages' => array(
203 'confirm_clear_tracks' => esc_html__( 'Do you really want to remove all tracks? (This will not delete your audio files).', 'audioigniter' ),
204 'media_title_upload' => esc_html__( 'Select or upload audio media', 'audioigniter' ),
205 'media_title_upload_cover' => esc_html__( 'Select a cover image', 'audioigniter' ),
206 ),
207 ) );
208 }
209
210 /**
211 * Enqueues frontend scripts and styles.
212 *
213 * @since 1.0.0
214 */
215 public function enqueue_scripts() {
216 wp_enqueue_style( 'audioigniter' );
217 wp_enqueue_script( 'audioigniter' );
218 }
219
220 /**
221 * Enqueues admin scripts and styles.
222 *
223 * @since 1.0.0
224 */
225 public function enqueue_admin_scripts( $hook ) {
226 $screen = get_current_screen();
227
228 if ( 'post' === $screen->base && $screen->post_type === $this->post_type ) {
229 wp_enqueue_media();
230 wp_enqueue_style( 'audioigniter-admin' );
231 wp_enqueue_script( 'audioigniter-admin' );
232 }
233 }
234
235 /**
236 * Post types registration.
237 *
238 * @since 1.0.0
239 */
240 public function register_post_types() {
241 $labels = array(
242 'name' => esc_html_x( 'Playlists', 'post type general name', 'audioigniter' ),
243 'singular_name' => esc_html_x( 'Playlist', 'post type singular name', 'audioigniter' ),
244 'menu_name' => esc_html_x( 'Playlists', 'admin menu', 'audioigniter' ),
245 'name_admin_bar' => esc_html_x( 'Playlist', 'add new on admin bar', 'audioigniter' ),
246 'add_new' => esc_html__( 'Add New Playlist', 'audioigniter' ),
247 'add_new_item' => esc_html__( 'Add New Playlist', 'audioigniter' ),
248 'edit_item' => esc_html__( 'Edit Playlist', 'audioigniter' ),
249 'new_item' => esc_html__( 'New Playlist', 'audioigniter' ),
250 'view_item' => esc_html__( 'View Playlist', 'audioigniter' ),
251 'search_items' => esc_html__( 'Search Playlists', 'audioigniter' ),
252 'not_found' => esc_html__( 'No playlists found', 'audioigniter' ),
253 'not_found_in_trash' => esc_html__( 'No playlists found in the trash', 'audioigniter' ),
254 );
255
256 $args = array(
257 'labels' => $labels,
258 'singular_label' => esc_html_x( 'Playlist', 'post type singular name', 'audioigniter' ),
259 'public' => false,
260 'show_ui' => true,
261 'capability_type' => 'post',
262 'hierarchical' => false,
263 'has_archive' => false,
264 'supports' => array( 'title' ),
265 'menu_icon' => 'dashicons-controls-volumeon',
266 );
267
268 register_post_type( $this->post_type, $args );
269 }
270
271
272 /**
273 * Registers metaboxes for the ai_playlist post type.
274 *
275 * @since 1.0.0
276 */
277 public function add_meta_boxes() {
278 add_meta_box( 'ai-meta-box-tracks', esc_html__( 'Tracks', 'audioigniter' ), array( $this, 'metabox_tracks' ), $this->post_type, 'normal', 'high' );
279 add_meta_box( 'ai-meta-box-settings', esc_html__( 'Settings', 'audioigniter' ), array( $this, 'metabox_settings' ), $this->post_type, 'normal', 'high' );
280 add_meta_box( 'ai-meta-box-shortcode', esc_html__( 'Shortcode', 'audioigniter' ), array( $this, 'metabox_shortcode' ), $this->post_type, 'normal', 'high' );
281 }
282
283 /**
284 * Echoes the Tracks metabox markup.
285 *
286 * @since 1.0.0
287 *
288 * @param WP_Post $object
289 * @param array $box
290 */
291 public function metabox_tracks( $object, $box ) {
292 $tracks = $this->get_post_meta( $object->ID, '_audioigniter_tracks', array() );
293
294 wp_nonce_field( basename( __FILE__ ), $object->post_type . '_nonce' );
295 ?>
296
297 <?php $this->metabox_tracks_header(); ?>
298
299 <div class="ai-container">
300 <?php $this->metabox_tracks_field_controls(); ?>
301
302 <?php $container_classes = apply_filters( 'audioigniter_metabox_tracks_container_classes', array( 'ai-fields-container' ) ); ?>
303
304 <div class="<?php echo esc_attr( implode( ' ', $container_classes ) ); ?>">
305 <?php
306 if ( ! empty( $tracks ) ) {
307 foreach ( $tracks as $track ) {
308 $this->metabox_tracks_repeatable_track_field( $track );
309 }
310 } else {
311 $this->metabox_tracks_repeatable_track_field();
312 }
313 ?>
314 </div>
315
316 <?php $this->metabox_tracks_field_controls(); ?>
317 </div>
318
319 <?php $this->metabox_tracks_footer(); ?>
320
321 <input type="hidden" name="ai_nonce" id="ai_nonce" value="<?php echo esc_attr( wp_create_nonce( self::plugin_basename() ) ); ?>"/>
322 <?php
323 }
324
325
326 /**
327 * Echoes the Tracks metabox header.
328 *
329 * @since 1.0.0
330 */
331 protected function metabox_tracks_header() {
332 ?>
333 <div class="ai-header ai-brand-module">
334 <div class="ai-row">
335 <div class="ai-col-left">
336 <a href="https://www.cssigniter.com/ignite/plugins/audioigniter?utm_source=dashboard&utm_medium=link&utm_content=audioigniter&utm_campaign=logo" target="_blank" class="ai-logo">
337 <img
338 src="<?php echo esc_url( $this->plugin_url() . 'assets/images/logo.svg' ); ?>"
339 alt="<?php esc_attr_e( 'AudioIgniter Logo', 'audioigniter' ); ?>"
340 >
341 </a>
342 </div>
343
344 <?php if ( apply_filters( 'audioigniter_metabox_tracks_show_upgrade_button', true ) ) : ?>
345 <div class="ai-col-right">
346 <div class="ai-brand-module-actions">
347 <a href="https://www.cssigniter.com/ignite/plugins/audioigniter?utm_source=dashboard&utm_medium=link&utm_content=audioigniter&utm_campaign=upgrade-pro" class="ai-btn ai-btn-green" target="_blank">
348 <?php esc_html_e( 'Upgrade to Pro', 'audioigniter' ); ?>
349 </a>
350 </div>
351 </div>
352 <?php endif; ?>
353 </div>
354 </div>
355 <?php
356 }
357
358 /**
359 * Echoes the Tracks metabox footer.
360 *
361 * @since 1.0.0
362 */
363 protected function metabox_tracks_footer() {
364 ?>
365 <div class="ai-footer ai-brand-module">
366 <div class="ai-row">
367 <div class="ai-col-left">
368 <ul class="ai-list-inline">
369 <?php
370 $links = apply_filters( 'audioigniter_metabox_tracks_footer_links', array(
371 'support' => array(
372 'title' => __( 'Support', 'audioigniter' ),
373 'url' => 'https://wordpress.org/support/plugin/audioigniter',
374 ),
375 'documentation' => array(
376 'title' => __( 'Documentation', 'audioigniter' ),
377 'url' => 'https://www.cssigniter.com/docs/audioigniter/',
378 ),
379 'rate_plugin' => array(
380 'title' => __( 'Rate this plugin', 'audioigniter' ),
381 'url' => 'https://wordpress.org/support/view/plugin-reviews/audioigniter',
382 ),
383 ) );
384
385 foreach ( $links as $link ) {
386 if ( empty( $link['url'] ) || empty( $link['title'] ) ) {
387 continue;
388 }
389
390 echo sprintf( '<li><a href="%s" target="_blank">%s</a></li>',
391 esc_url( $link['url'] ),
392 esc_html( $link['title'] )
393 );
394 }
395 ?>
396 </ul>
397 </div>
398
399 <div class="ai-col-right">
400 <?php
401 $url = 'https://www.cssigniter.com/ignite/plugins/audioigniter?utm_source=dashboard&utm_medium=link&utm_content=audioigniter&utm_campaign=footer-link';
402 $copy = sprintf( __( 'Thank you for creating with <a href="%s" target="_blank">AudioIgniter</a>', 'audioigniter' ),
403 esc_url( $url )
404 );
405 ?>
406 <div class="ai-brand-module-actions">
407 <p class="ai-note"><?php echo wp_kses( $copy, array( 'a' => array( 'href' => true, 'target' => true ) ) ); ?></p>
408 </div>
409 </div>
410 </div>
411 </div>
412 <?php
413 }
414
415 protected function metabox_tracks_repeatable_track_field( $track = array() ) {
416 $track = wp_parse_args( $track, self::get_default_track_values() );
417
418 $cover_id = $track['cover_id'];
419 $title = $track['title'];
420 $artist = $track['artist'];
421 $track_url = $track['track_url'];
422 $buy_link = $track['buy_link'];
423
424 $cover_url = wp_get_attachment_image_src( intval( $cover_id ), 'thumbnail' );
425 if ( ! empty( $cover_url[0] ) ) {
426 $cover_url = $cover_url[0];
427 $cover_data = wp_prepare_attachment_for_js( intval( $cover_id ) );
428 } else {
429 $cover_url = '';
430 $cover_data = '';
431 }
432
433 $uid = uniqid();
434
435 $field_classes = apply_filters( 'audioigniter_metabox_track_classes', array( 'ai-field-repeatable' ), $track_url );
436 ?>
437 <div class="<?php echo esc_attr( implode( ' ', $field_classes ) ); ?>" data-uid="<?php echo esc_attr( $uid ); ?>">
438 <div class="ai-field-head">
439
440 <?php do_action( 'audioigniter_metabox_tracks_repeatable_track_field_before_title' ); ?>
441
442 <span class="ai-field-title"><?php echo wp_kses( $title, array() ); ?></span>
443
444 <button type="button" class="ai-field-toggle button-link">
445 <span class="screen-reader-text">
446 <?php esc_html_e( 'Toggle track visibility', 'audioigniter' ); ?>
447 </span>
448 <span class="toggle-indicator"></span>
449 </button>
450 </div>
451
452 <div class="ai-field-container">
453 <div class="ai-field-cover">
454 <a href="#" class="ai-field-upload-cover <?php echo ! empty( $cover_url ) ? 'ai-has-cover' : ''; ?>">
455 <span class="ai-remove-cover">
456 <span class="screen-reader-text">
457 <?php esc_html_e( 'Remove Cover Image', 'audioigniter' ); ?>
458 </span>
459 <span class="dashicons dashicons-no-alt"></span>
460 </span>
461
462 <?php if ( ! empty( $cover_url ) ) : ?>
463 <img src="<?php echo esc_url( $cover_url ); ?>" alt="<?php echo esc_attr( $cover_data['alt'] ); ?>">
464 <?php else : ?>
465 <img src="#" alt="">
466 <?php endif; ?>
467
468 <div class="ai-field-cover-placeholder">
469 <span class="ai-cover-prompt">
470 <?php esc_html_e( 'Upload Cover', 'audioigniter' ); ?>
471 </span>
472 </div>
473 </a>
474
475 <input
476 type="hidden"
477 id="ai_playlist_tracks-<?php echo esc_attr( $uid ); ?>-cover_id"
478 name="ai_playlist_tracks[<?php echo esc_attr( $uid ); ?>][cover_id]"
479 value="<?php echo esc_attr( $cover_id ); ?>"
480 />
481 </div>
482
483 <div class="ai-field-split">
484 <div class="ai-form-field">
485 <label
486 for="ai_playlist_tracks-<?php echo esc_attr( $uid ); ?>-title"
487 class="screen-reader-text">
488 <?php esc_html_e( 'Title', 'audioigniter' ); ?>
489 </label>
490 <input
491 type="text"
492 id="ai_playlist_tracks-<?php echo esc_attr( $uid ); ?>-title"
493 class="ai-track-title"
494 name="ai_playlist_tracks[<?php echo esc_attr( $uid ); ?>][title]"
495 placeholder="<?php esc_attr_e( 'Title', 'audioigniter' ); ?>"
496 value="<?php echo esc_attr( $title ); ?>"
497 />
498 </div>
499 <div class="ai-form-field">
500 <label
501 for="ai_playlist_tracks-<?php echo esc_attr( $uid ); ?>-artist"
502 class="screen-reader-text">
503 <?php esc_html_e( 'Artist', 'audioigniter' ); ?>
504 </label>
505 <input
506 type="text"
507 id="ai_playlist_tracks-<?php echo esc_attr( $uid ); ?>-artist"
508 class="ai-track-artist"
509 name="ai_playlist_tracks[<?php echo esc_attr( $uid ); ?>][artist]"
510 placeholder="<?php esc_attr_e( 'Artist', 'audioigniter' ); ?>"
511 value="<?php echo esc_attr( $artist ); ?>"
512 />
513 </div>
514 </div>
515
516 <div class="ai-field-split">
517 <div class="ai-form-field">
518 <label
519 for="ai_playlist_tracks-<?php echo esc_attr( $uid ); ?>-track_url"
520 class="screen-reader-text">
521 <?php esc_html_e( 'Audio file or radio stream', 'audioigniter' ); ?>
522 </label>
523
524 <div class="ai-form-field-addon">
525 <input
526 type="text"
527 id="ai_playlist_tracks-<?php echo esc_attr( $uid ); ?>-track_url"
528 class="ai-track-url"
529 name="ai_playlist_tracks[<?php echo esc_attr( $uid ); ?>][track_url]"
530 placeholder="<?php esc_attr_e( 'Audio file or radio stream', 'audioigniter' ); ?>"
531 value="<?php echo esc_url( $track_url ); ?>"
532 />
533 <button type="button" class="button ai-upload">
534 <?php esc_html_e( 'Upload', 'audioigniter' ); ?>
535 </button>
536
537 <?php do_action( 'audioigniter_metabox_tracks_repeatable_track_field_after_track_upload_button' ); ?>
538 </div>
539 </div>
540 <div class="ai-form-field">
541 <label
542 for="ai_playlist_tracks-<?php echo esc_attr( $uid ); ?>-buy_link"
543 class="screen-reader-text">
544 <?php esc_html_e( 'Buy link', 'audioigniter' ); ?>
545 </label>
546 <input
547 type="text"
548 id="ai_playlist_tracks-<?php echo esc_attr( $uid ); ?>-buy_link"
549 class="ai-track-buy-link"
550 name="ai_playlist_tracks[<?php echo esc_attr( $uid ); ?>][buy_link]"
551 placeholder="<?php esc_attr_e( 'Buy link', 'audioigniter' ); ?>"
552 value="<?php echo esc_url( $buy_link ); ?>"
553 />
554 </div>
555
556 <button type="button" class="button ai-remove-field">
557 <span class="dashicons dashicons-dismiss"></span>
558 <?php esc_html_e( 'Remove Track', 'audioigniter' ); ?>
559 </button>
560 </div>
561 </div>
562 </div>
563 <?php
564 }
565
566 protected function metabox_tracks_field_controls() {
567 ?>
568 <div class="ai-field-controls-wrap">
569 <div class="ai-field-controls">
570 <button type="button" class="button ai-add-field">
571 <span class="dashicons dashicons-plus-alt"></span>
572 <?php esc_html_e( 'Add Track', 'audioigniter' ); ?>
573 </button>
574
575 <?php do_action( 'audioigniter_metabox_tracks_field_controls' ); ?>
576
577 <button type="button" class="button ai-remove-all-fields">
578 <span class="dashicons dashicons-dismiss"></span>
579 <?php esc_html_e( 'Clear Playlist', 'audioigniter' ); ?>
580 </button>
581 </div>
582
583 <div class="ai-field-controls-visibility">
584 <a href="#" class="ai-fields-expand-all">
585 <?php esc_html_e( 'Expand All', 'audioigniter' ); ?>
586 </a>
587 <a href="#" class="ai-fields-collapse-all">
588 <?php esc_html_e( 'Collapse All', 'audioigniter' ); ?>
589 </a>
590 </div>
591 </div>
592 <?php
593 }
594
595 /**
596 * Echoes the Settings metabox markup.
597 *
598 * @since 1.0.0
599 *
600 * @param WP_Post $object
601 * @param array $box
602 */
603 function metabox_settings( $object, $box ) {
604 $numbers = $this->get_post_meta( $object->ID, '_audioigniter_show_numbers', 1 );
605 $numbers_reverse = $this->get_post_meta( $object->ID, '_audioigniter_show_numbers_reverse', 0 );
606 $thumb = $this->get_post_meta( $object->ID, '_audioigniter_show_covers', 1 );
607 $active_thumb = $this->get_post_meta( $object->ID, '_audioigniter_show_active_cover', 1 );
608 $artist = $this->get_post_meta( $object->ID, '_audioigniter_show_artist', 1 );
609 $buy_links = $this->get_post_meta( $object->ID, '_audioigniter_show_buy_links', 1 );
610 $track_listing = $this->get_post_meta( $object->ID, '_audioigniter_show_track_listing', 1 );
611 $credit = $this->get_post_meta( $object->ID, '_audioigniter_show_credit', 0 );
612 $limit_tracklisting_height = $this->get_post_meta( $object->ID, '_audioigniter_limit_tracklisting_height', 1 );
613 $tracklisting_height = $this->get_post_meta( $object->ID, '_audioigniter_tracklisting_height', 185 );
614 $max_width = $this->get_post_meta( $object->ID, '_audioigniter_max_width' );
615
616 wp_nonce_field( basename( __FILE__ ), $object->post_type . '_nonce' );
617 ?>
618 <div class="ai-module ai-module-settings">
619 <div class="ai-form-field">
620 <input
621 type="checkbox"
622 class="ai-checkbox"
623 id="_audioigniter_show_track_listing"
624 name="_audioigniter_show_track_listing"
625 value="1" <?php checked( $track_listing, true ); ?>
626 />
627
628 <label for="_audioigniter_show_track_listing">
629 <?php esc_html_e( 'Show track listing', 'audioigniter' ); ?>
630 </label>
631 </div>
632
633 <div class="ai-form-field">
634 <input
635 type="checkbox"
636 class="ai-checkbox"
637 id="_audioigniter_show_numbers"
638 name="_audioigniter_show_numbers"
639 value="1" <?php checked( $numbers, true ); ?>
640 />
641
642 <label for="_audioigniter_show_numbers">
643 <?php esc_html_e( 'Show track numbers in tracklist', 'audioigniter' ); ?>
644 </label>
645 </div>
646
647 <div class="ai-form-field">
648 <input
649 type="checkbox"
650 class="ai-checkbox"
651 id="_audioigniter_show_numbers_revese"
652 name="_audioigniter_show_numbers_reverse"
653 value="1" <?php checked( $numbers_reverse, true ); ?>
654 />
655
656 <label for="_audioigniter_show_numbers_revese">
657 <?php esc_html_e( 'Show numbers in reverse order', 'audioigniter' ); ?>
658 </label>
659
660 <p class="ai-field-help">
661 <?php esc_html_e( 'For this to work, the "Show track numbers in tracklist" option above must be enabled.', 'audioigniter' ); ?>
662 </p>
663 </div>
664
665 <div class="ai-form-field">
666 <input
667 type="checkbox"
668 class="ai-checkbox"
669 id="_audioigniter_show_covers"
670 name="_audioigniter_show_covers"
671 value="1" <?php checked( $thumb, true ); ?>
672 />
673
674 <label for="_audioigniter_show_covers">
675 <?php esc_html_e( 'Show track covers in tracklist', 'audioigniter' ); ?>
676 </label>
677 </div>
678
679 <div class="ai-form-field">
680 <input
681 type="checkbox"
682 class="ai-checkbox"
683 id="_audioigniter_show_active_cover"
684 name="_audioigniter_show_active_cover"
685 value="1" <?php checked( $active_thumb, true ); ?>
686 />
687
688 <label for="_audioigniter_show_active_cover">
689 <?php esc_html_e( "Show active track's cover", 'audioigniter' ); ?>
690 </label>
691 </div>
692
693 <div class="ai-form-field">
694 <input
695 type="checkbox"
696 class="ai-checkbox"
697 id="_audioigniter_show_artist"
698 name="_audioigniter_show_artist"
699 value="1" <?php checked( $artist, true ); ?>
700 />
701
702 <label for="_audioigniter_show_artist">
703 <?php esc_html_e( 'Show artist names', 'audioigniter' ); ?>
704 </label>
705 </div>
706
707 <div class="ai-form-field">
708 <input
709 type="checkbox"
710 class="ai-checkbox"
711 id="_audioigniter_show_buy_links"
712 name="_audioigniter_show_buy_links"
713 value="1" <?php checked( $buy_links, true ); ?>
714 />
715
716 <label for="_audioigniter_show_buy_links">
717 <?php esc_html_e( 'Show buy link', 'audioigniter' ); ?>
718 </label>
719 </div>
720
721 <div class="ai-form-field">
722 <input
723 type="checkbox"
724 class="ai-checkbox"
725 id="_audioigniter_show_credit"
726 name="_audioigniter_show_credit"
727 value="1" <?php checked( $credit, true ); ?>
728 />
729
730 <label for="_audioigniter_show_credit">
731 <?php esc_html_e( 'Show "Powered by AudioIgniter" link', 'audioigniter' ); ?>
732 </label>
733
734 <p class="ai-field-help">
735 <?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' ); ?>
736 </p>
737 </div>
738
739 <div class="ai-form-field">
740 <input
741 type="checkbox"
742 class="ai-checkbox"
743 id="_audioigniter_limit_tracklisting_height"
744 name="_audioigniter_limit_tracklisting_height"
745 value="1" <?php checked( $limit_tracklisting_height, true ); ?>
746 />
747
748 <label for="_audioigniter_limit_tracklisting_height">
749 <?php esc_html_e( 'Limit track listing height', 'audioigniter' ); ?>
750 </label>
751 </div>
752
753 <div class="ai-form-field">
754 <label for="_audioigniter_tracklisting_height">
755 <?php esc_html_e( 'Track listing height', 'audioigniter' ); ?>
756 </label>
757
758 <input
759 type="number"
760 min="10"
761 step="5"
762 id="_audioigniter_tracklisting_height"
763 class="ai-track-title"
764 name="_audioigniter_tracklisting_height"
765 placeholder="<?php esc_attr_e( 'Track listing height', 'audioigniter' ); ?>"
766 value="<?php echo esc_attr( $tracklisting_height ); ?>"
767 />
768
769 <p class="ai-field-help">
770 <?php esc_html_e( 'Set a number of pixels', 'audioigniter' ); ?>
771 </p>
772 </div>
773
774 <div class="ai-form-field">
775 <label for="_audioigniter_max_width">
776 <?php esc_html_e( 'Maximum player width', 'audioigniter' ); ?>
777 </label>
778
779 <input
780 type="number"
781 id="_audioigniter_max_width"
782 class="ai-track-title"
783 name="_audioigniter_max_width"
784 placeholder="<?php esc_attr_e( 'Automatic width', 'audioigniter' ); ?>"
785 value="<?php echo esc_attr( $max_width ); ?>"
786 />
787
788 <p class="ai-field-help">
789 <?php esc_html_e( 'Set a number of pixels, or leave empty to automatically cover 100% of the available area (recommended).', 'audioigniter' ); ?>
790 </p>
791 </div>
792 </div>
793 <?php
794 }
795
796 /**
797 * Echoes the Shortcode metabox markup.
798 *
799 * @since 1.0.0
800 *
801 * @param WP_Post $object
802 * @param array $box
803 */
804 public function metabox_shortcode( $object, $box ) {
805 ?>
806 <div class="ai-module ai-module-shortcode">
807 <div class="ai-form-field">
808 <label for="ai_shortcode">
809 <?php esc_html_e( 'Grab the shortcode', 'audioigniter' ); ?>
810 </label>
811
812 <input
813 type="text"
814 class="code"
815 id="ai_shortcode"
816 name="ai_shortcode"
817 value="<?php echo esc_attr( sprintf( '[ai_playlist id="%s"]', $object->ID ) ); ?>"
818 />
819
820 </div>
821 </div>
822 <?php
823 }
824
825 public function save_post( $post_id ) {
826 if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) { return false; }
827 if ( isset( $_POST['post_view'] ) && $_POST['post_view'] === 'list' ) { return false; }
828 if ( ! isset( $_POST['post_type'] ) || $_POST['post_type'] !== $this->post_type ) { return false; }
829 if ( ! isset( $_POST[ $this->post_type . '_nonce' ] ) || ! wp_verify_nonce( $_POST[ $this->post_type . '_nonce' ], basename( __FILE__ ) ) ) { return false; }
830 $post_type_obj = get_post_type_object( $this->post_type );
831 if ( ! current_user_can( $post_type_obj->cap->edit_post, $post_id ) ) { return false; }
832
833 update_post_meta( $post_id, '_audioigniter_tracks', $this->sanitizer->metabox_playlist( $_POST['ai_playlist_tracks'], $post_id ) );
834
835 update_post_meta( $post_id, '_audioigniter_show_numbers', $this->sanitizer->checkbox_ref( $_POST['_audioigniter_show_numbers'] ) );
836 update_post_meta( $post_id, '_audioigniter_show_numbers_reverse', $this->sanitizer->checkbox_ref( $_POST['_audioigniter_show_numbers_reverse'] ) );
837 update_post_meta( $post_id, '_audioigniter_show_covers', $this->sanitizer->checkbox_ref( $_POST['_audioigniter_show_covers'] ) );
838 update_post_meta( $post_id, '_audioigniter_show_active_cover', $this->sanitizer->checkbox_ref( $_POST['_audioigniter_show_active_cover'] ) );
839 update_post_meta( $post_id, '_audioigniter_show_artist', $this->sanitizer->checkbox_ref( $_POST['_audioigniter_show_artist'] ) );
840 update_post_meta( $post_id, '_audioigniter_show_buy_links', $this->sanitizer->checkbox_ref( $_POST['_audioigniter_show_buy_links'] ) );
841 update_post_meta( $post_id, '_audioigniter_show_track_listing', $this->sanitizer->checkbox_ref( $_POST['_audioigniter_show_track_listing'] ) );
842 update_post_meta( $post_id, '_audioigniter_show_credit', $this->sanitizer->checkbox_ref( $_POST['_audioigniter_show_credit'] ) );
843 update_post_meta( $post_id, '_audioigniter_limit_tracklisting_height', $this->sanitizer->checkbox_ref( $_POST['_audioigniter_limit_tracklisting_height'] ) );
844 update_post_meta( $post_id, '_audioigniter_tracklisting_height', intval( $_POST['_audioigniter_tracklisting_height'] ) );
845 update_post_meta( $post_id, '_audioigniter_max_width', $this->sanitizer->intval_or_empty( $_POST['_audioigniter_max_width'] ) );
846 }
847
848 public static function get_default_track_values() {
849 return apply_filters( 'audioigniter_default_track_values', array(
850 'cover_id' => '',
851 'title' => '',
852 'artist' => '',
853 'track_url' => '',
854 'buy_link' => '',
855 ) );
856 }
857
858 public function register_image_sizes() {
859 add_image_size( 'audioigniter_cover', 560, 560, true );
860 }
861
862 public function register_widgets() {
863 $widgets = apply_filters( 'audioigniter_register_widgets', array() );
864
865 foreach ( $widgets as $class => $file ) {
866 require_once( $file );
867 register_widget( $class );
868 }
869 }
870
871 public function register_shortcodes() {
872 add_shortcode( 'ai_playlist', array( $this, 'shortcode_ai_playlist' ) );
873 }
874
875 public function shortcode_ai_playlist( $atts, $content = null, $tag ) {
876 $atts = shortcode_atts( array(
877 'id' => '',
878 ), $atts, $tag );
879
880 $id = $atts['id'];
881
882 if ( empty( $id ) ) {
883 return '';
884 }
885
886 $id = intval( $id );
887 $post = get_post( $id );
888
889 if ( empty( $post ) || $post->post_type !== $this->post_type ) {
890 return '';
891 }
892
893 $params = apply_filters( 'audioigniter_shortcode_data_attributes_array', array(
894 'data-tracks-url' => add_query_arg( array( 'audioigniter_playlist_id' => $id ), home_url( '/' ) ),
895 'data-display-track-no' => $this->convert_bool_string( $this->get_post_meta( $id, '_audioigniter_show_numbers', 1 ) ),
896 'data-reverse-track-order' => $this->convert_bool_string( $this->get_post_meta( $id, '_audioigniter_show_numbers_reverse', 0 ) ),
897 'data-display-tracklist-covers' => $this->convert_bool_string( $this->get_post_meta( $id, '_audioigniter_show_covers', 1 ) ),
898 'data-display-active-cover' => $this->convert_bool_string( $this->get_post_meta( $id, '_audioigniter_show_active_cover', 1 ) ),
899 'data-display-artist-names' => $this->convert_bool_string( $this->get_post_meta( $id, '_audioigniter_show_artist', 1 ) ),
900 'data-display-buy-buttons' => $this->convert_bool_string( $this->get_post_meta( $id, '_audioigniter_show_buy_links', 1 ) ),
901 'data-display-credits' => $this->convert_bool_string( $this->get_post_meta( $id, '_audioigniter_show_credit', 1 ) ),
902 'data-display-tracklist' => $this->convert_bool_string( $this->get_post_meta( $id, '_audioigniter_show_track_listing', 1 ) ),
903 'data-limit-tracklist-height' => $this->convert_bool_string( $this->get_post_meta( $id, '_audioigniter_limit_tracklisting_height', 1 ) ),
904 'data-tracklist-height' => intval( $this->get_post_meta( $id, '_audioigniter_tracklisting_height', 185 ) ),
905 'data-max-width' => $this->get_post_meta( $id, '_audioigniter_max_width' ),
906 ), $id, $post );
907
908 $params = array_filter( $params );
909 $params = $this->sanitizer->html_data_attributes_array( $params );
910
911 $data = '';
912 foreach ( $params as $attribute => $value ) {
913 $data .= sprintf( '%s="%s" ', sanitize_key( $attribute ), esc_attr( $value ) );
914 }
915
916 $output = sprintf( '<div id="audioigniter-%s" class="audioigniter-root" %s></div>',
917 esc_attr( $id ),
918 $data
919 );
920
921 return $output;
922 }
923
924 public function convert_bool_string( $value ) {
925 if ( $value ) {
926 return 'true';
927 }
928
929 return 'false';
930 }
931
932 public function register_playlist_endpoint() {
933 add_rewrite_tag( '%audioigniter_playlist_id%', '([0-9]+)' );
934 add_rewrite_rule( '^audioigniter/playlist/([0-9]+)/?', 'index.php?audioigniter_playlist_id=$matches[1]', 'bottom' );
935 }
936
937 public function handle_playlist_endpoint() {
938 global $wp_query;
939
940 $playlist_id = $wp_query->get( 'audioigniter_playlist_id' );
941
942 if ( empty( $playlist_id ) ) {
943 return;
944 }
945
946 $playlist_id = intval( $playlist_id );
947 $post = get_post( $playlist_id );
948
949 if ( empty( $post ) || $post->post_type !== $this->post_type ) {
950 wp_send_json_error( __( "ID doesn't match a playlist", 'audioigniter' ) );
951 }
952
953 $response = array();
954 $tracks = $this->get_post_meta( $playlist_id, '_audioigniter_tracks', array() );
955
956 foreach ( $tracks as $track ) {
957 $tmp = array();
958
959 $tmp['title'] = $track['title'];
960 $tmp['subtitle'] = $track['artist'];
961 $tmp['audio'] = $track['track_url'];
962 $tmp['buyUrl'] = $track['buy_link'];
963
964 $cover_url = wp_get_attachment_image_src( intval( $track['cover_id'] ), 'audioigniter_cover' );
965 if ( ! empty( $cover_url[0] ) ) {
966 $cover_url = $cover_url[0];
967 } else {
968 $cover_url = '';
969 }
970
971 $tmp['cover'] = $cover_url;
972
973 $response[] = $tmp;
974 }
975
976 wp_send_json( $response );
977 }
978
979
980 public function get_all_playlists( $orderby = 'date', $order = 'DESC' ) {
981 $q = new WP_Query( array(
982 'post_type' => $this->post_type,
983 'posts_per_page' => - 1,
984 'orderby' => $orderby,
985 'order' => $order,
986 ) );
987
988 return $q->posts;
989 }
990
991 public function get_post_meta( $post_id, $key, $default = '' ) {
992 $keys = get_post_custom_keys( $post_id );
993
994 $value = $default;
995
996 if ( is_array( $keys ) && in_array( $key, $keys, true ) ) {
997 $value = get_post_meta( $post_id, $key, true );
998 }
999
1000 return $value;
1001 }
1002
1003 public function plugin_activated() {
1004 if ( ! current_user_can( 'activate_plugins' ) ) {
1005 return;
1006 }
1007
1008 $this->register_post_types();
1009
1010 do_action( 'audioigniter_activated' );
1011
1012 flush_rewrite_rules();
1013 }
1014
1015 public function plugin_deactivated() {
1016 if ( ! current_user_can( 'activate_plugins' ) ) {
1017 return;
1018 }
1019
1020 unregister_post_type( $this->post_type );
1021
1022 do_action( 'audioigniter_deactivated' );
1023
1024 flush_rewrite_rules();
1025 }
1026
1027 public static function plugin_basename() {
1028 return plugin_basename( __FILE__ );
1029 }
1030
1031 public function plugin_url() {
1032 return self::$plugin_url;
1033 }
1034
1035 public function plugin_path() {
1036 return self::$plugin_path;
1037 }
1038 }
1039
1040
1041 /**
1042 * Main instance of AudioIgniter.
1043 *
1044 * Returns the working instance of AudioIgniter. No need for globals.
1045 *
1046 * @since 1.0.0
1047 * @return AudioIgniter
1048 */
1049 function AudioIgniter() {
1050 return AudioIgniter::instance();
1051 }
1052
1053 add_action( 'plugins_loaded', array( AudioIgniter(), 'plugin_setup' ) );
1054 register_activation_hook( __FILE__, array( AudioIgniter(), 'plugin_activated' ) );
1055 register_deactivation_hook( __FILE__, array( AudioIgniter(), 'plugin_deactivated' ) );
1056