music-player-for-woocommerce
Last commit date
addons
3 years ago
css
3 years ago
feedback
3 years ago
js
3 years ago
languages
3 years ago
pagebuilders
3 years ago
vendors
3 years ago
views
3 years ago
widgets
3 years ago
banner.php
3 years ago
readme.txt
3 years ago
wcmp.php
3 years ago
wcmp.php
1701 lines
| 1 | <?php |
| 2 | /* |
| 3 | Plugin Name: Music Player for WooCommerce |
| 4 | Plugin URI: https://wcmp.dwbooster.com |
| 5 | Version: 1.0.187 |
| 6 | Text Domain: music-player-for-woocommerce |
| 7 | Author: CodePeople |
| 8 | Author URI: https://wcmp.dwbooster.com |
| 9 | Description: Music Player for WooCommerce includes the MediaElement.js music player in the pages of the products with audio files associated, and in the store's pages, furthermore, the plugin allows selecting between multiple skins. |
| 10 | License: GPLv2 or later |
| 11 | License URI: http://www.gnu.org/licenses/gpl-2.0.html |
| 12 | */ |
| 13 | |
| 14 | require_once 'banner.php'; |
| 15 | $codepeople_promote_banner_plugins['codepeople-music-player-for-woocommerce'] = array( |
| 16 | 'plugin_name' => 'Music Player for WooCommerce', |
| 17 | 'plugin_url' => 'https://wordpress.org/support/plugin/music-player-for-woocommerce/reviews/#new-post', |
| 18 | ); |
| 19 | |
| 20 | // Feedback system |
| 21 | require_once 'feedback/cp-feedback.php'; |
| 22 | new WCMP_FEEDBACK( 'music-player-for-woocommerce', __FILE__, 'https://wcmp.dwbooster.com/contact-us' ); |
| 23 | |
| 24 | // CONSTANTS |
| 25 | |
| 26 | define( 'WCMP_WEBSITE_URL', get_home_url( get_current_blog_id(), '', is_ssl() ? 'https' : 'http' ) ); |
| 27 | define( 'WCMP_PLUGIN_URL', plugins_url( '', __FILE__ ) ); |
| 28 | define( 'WCMP_DEFAULT_PLAYER_LAYOUT', 'mejs-classic' ); |
| 29 | define( 'WCMP_DEFAULT_PLAYER_VOLUME', 1 ); |
| 30 | define( 'WCMP_DEFAULT_PLAYER_CONTROLS', 'default' ); |
| 31 | define( 'WCMP_DEFAULT_PlAYER_TITLE', 1 ); |
| 32 | define( 'WCMP_REMOTE_TIMEOUT', 120 ); |
| 33 | define( 'WCMP_VERSION', '1.0.187' ); |
| 34 | |
| 35 | // Load widgets |
| 36 | require_once 'widgets/playlist_widget.php'; |
| 37 | |
| 38 | add_filter( 'option_sbp_settings', array( 'WooCommerceMusicPlayer', 'troubleshoot' ) ); |
| 39 | if ( ! class_exists( 'WooCommerceMusicPlayer' ) ) { |
| 40 | class WooCommerceMusicPlayer { |
| 41 | |
| 42 | // ******************** ATTRIBUTES ************************ |
| 43 | |
| 44 | private $_products_attrs = array(); |
| 45 | private $_global_attrs = array(); |
| 46 | private $_player_layouts = array( 'mejs-classic', 'mejs-ted', 'mejs-wmp' ); |
| 47 | private $_player_controls = array( 'button', 'all', 'default' ); |
| 48 | private $_files_directory_path; |
| 49 | private $_files_directory_url; |
| 50 | private $_enqueued_resources = false; |
| 51 | private $_insert_player = true; |
| 52 | |
| 53 | private $_force_hook_title = 0; |
| 54 | |
| 55 | private $_preload_times = 0; // Multiple preloads with demo generators can affect the server performance |
| 56 | |
| 57 | /** |
| 58 | * WCMP constructor |
| 59 | * |
| 60 | * @access public |
| 61 | * @return void |
| 62 | */ |
| 63 | public function __construct() { |
| 64 | $this->_createDir(); |
| 65 | register_activation_hook( __FILE__, array( &$this, 'activation' ) ); |
| 66 | register_deactivation_hook( __FILE__, array( &$this, 'deactivation' ) ); |
| 67 | |
| 68 | add_action( 'plugins_loaded', array( &$this, 'plugins_loaded' ) ); |
| 69 | add_action( 'init', array( &$this, 'init' ) ); |
| 70 | add_action( 'admin_init', array( &$this, 'admin_init' ), 99 ); |
| 71 | } // End __constructor |
| 72 | |
| 73 | public function activation() { |
| 74 | $this->_deleteDir( $this->_files_directory_path ); |
| 75 | $this->_createDir(); |
| 76 | } |
| 77 | |
| 78 | public function deactivation() { |
| 79 | $this->_deleteDir( $this->_files_directory_path ); |
| 80 | } |
| 81 | |
| 82 | public function plugins_loaded() { |
| 83 | if ( ! class_exists( 'woocommerce' ) ) { |
| 84 | return; |
| 85 | } |
| 86 | load_plugin_textdomain( 'music-player-for-woocommerce', false, basename( dirname( __FILE__ ) ) . '/languages/' ); |
| 87 | |
| 88 | add_filter( 'the_title', array( &$this, 'include_main_player_filter' ), 11, 2 ); |
| 89 | $this->_init_force_in_title(); |
| 90 | $this->_load_addons(); |
| 91 | |
| 92 | // Integration with the content editors |
| 93 | require_once dirname( __FILE__ ) . '/pagebuilders/builders.php'; |
| 94 | WCMP_BUILDERS::run(); |
| 95 | } |
| 96 | |
| 97 | public function get_product_attr( $product_id, $attr, $default = false ) { |
| 98 | if ( ! isset( $this->_products_attrs[ $product_id ] ) ) { |
| 99 | $this->_products_attrs[ $product_id ] = array(); |
| 100 | } |
| 101 | if ( ! isset( $this->_products_attrs[ $product_id ][ $attr ] ) ) { |
| 102 | if ( metadata_exists( 'post', $product_id, $attr ) ) { |
| 103 | $this->_products_attrs[ $product_id ][ $attr ] = get_post_meta( $product_id, $attr, true ); |
| 104 | } else { |
| 105 | $this->_products_attrs[ $product_id ][ $attr ] = $this->get_global_attr( $attr, $default ); |
| 106 | } |
| 107 | } |
| 108 | return apply_filters( 'wcmp_product_attr', $this->_products_attrs[ $product_id ][ $attr ], $product_id, $attr ); |
| 109 | |
| 110 | } // End get_product_attr |
| 111 | |
| 112 | public function get_global_attr( $attr, $default = false ) { |
| 113 | if ( empty( $this->_global_attrs ) ) { |
| 114 | $this->_global_attrs = get_option( 'wcmp_global_settings', array() ); |
| 115 | } |
| 116 | if ( ! isset( $this->_global_attrs[ $attr ] ) ) { |
| 117 | $this->_global_attrs[ $attr ] = $default; |
| 118 | } |
| 119 | return apply_filters( 'wcmp_global_attr', $this->_global_attrs[ $attr ], $attr ); |
| 120 | |
| 121 | } // End get_global_attr |
| 122 | |
| 123 | // ******************** WordPress ACTIONS ************************** |
| 124 | |
| 125 | public function init() { |
| 126 | // Check if WooCommerce is installed or not |
| 127 | if ( ! class_exists( 'woocommerce' ) ) { |
| 128 | add_shortcode( |
| 129 | 'wcmp-playlist', |
| 130 | function( $atts ) { |
| 131 | return ''; |
| 132 | } |
| 133 | ); |
| 134 | return; } |
| 135 | $_current_user_id = get_current_user_id(); |
| 136 | if ( |
| 137 | $this->get_global_attr( '_wcmp_registered_only', 0 ) && |
| 138 | 0 == $_current_user_id |
| 139 | ) { |
| 140 | $this->_insert_player = false; |
| 141 | } |
| 142 | |
| 143 | if ( ! is_admin() ) { |
| 144 | add_filter( 'wcmp_preload', array( $this, 'preload' ), 10, 2 ); |
| 145 | |
| 146 | // Define the shortcode for the playlist_widget |
| 147 | add_shortcode( 'wcmp-playlist', array( &$this, 'replace_playlist_shortcode' ) ); |
| 148 | $this->_preview(); |
| 149 | if ( isset( $_REQUEST['wcmp-action'] ) && 'play' == $_REQUEST['wcmp-action'] ) { |
| 150 | if ( isset( $_REQUEST['wcmp-product'] ) ) { |
| 151 | $product_id = @intval( $_REQUEST['wcmp-product'] ); |
| 152 | if ( ! empty( $product_id ) ) { |
| 153 | $product = wc_get_product( $product_id ); |
| 154 | if ( false !== $product && isset( $_REQUEST['wcmp-file'] ) ) { |
| 155 | $files = $this->_get_product_files( |
| 156 | array( |
| 157 | 'product' => $product, |
| 158 | 'file_id' => sanitize_key( $_REQUEST['wcmp-file'] ), |
| 159 | ) |
| 160 | ); |
| 161 | |
| 162 | if ( ! empty( $files ) ) { |
| 163 | $file_url = $files[ sanitize_key( $_REQUEST['wcmp-file'] ) ]['file']; |
| 164 | $this->_tracking_play_event( $product_id, $file_url ); |
| 165 | $this->_output_file( array( 'url' => $file_url ) ); |
| 166 | } |
| 167 | } |
| 168 | } |
| 169 | } |
| 170 | exit; |
| 171 | } else { |
| 172 | // To allow customize the hooks |
| 173 | $include_main_player_hook = trim( $this->get_global_attr( '_wcmp_main_player_hook', '' ) ); |
| 174 | $include_all_players_hook = trim( $this->get_global_attr( '_wcmp_all_players_hook', '' ) ); |
| 175 | |
| 176 | if ( empty( $include_main_player_hook ) ) { |
| 177 | $include_main_player_hook = 'woocommerce_shop_loop_item_title'; |
| 178 | } |
| 179 | if ( empty( $include_all_players_hook ) ) { |
| 180 | $include_all_players_hook = 'woocommerce_single_product_summary'; |
| 181 | } |
| 182 | |
| 183 | if ( 0 == $this->_force_hook_title ) { |
| 184 | add_action( $include_main_player_hook, array( &$this, 'include_main_player' ), 11 ); |
| 185 | } |
| 186 | |
| 187 | add_action( $include_all_players_hook, array( &$this, 'include_all_players' ), 11 ); |
| 188 | |
| 189 | // Allows to call the players directly by themes |
| 190 | add_action( 'wcmp_main_player', array( &$this, 'include_main_player' ), 11 ); |
| 191 | add_action( 'wcmp_all_players', array( &$this, 'include_all_players' ), 11 ); |
| 192 | |
| 193 | // Integration with woocommerce-product-table by barn2media |
| 194 | add_filter( 'wc_product_table_data_name', array( &$this, 'product_table_data_name' ), 11, 2 ); |
| 195 | |
| 196 | $players_in_cart = $this->get_global_attr( '_wcmp_players_in_cart', false ); |
| 197 | if ( $players_in_cart ) { |
| 198 | add_action( 'woocommerce_after_cart_item_name', array( &$this, 'player_in_cart' ), 11, 2 ); |
| 199 | } |
| 200 | |
| 201 | // Add product id to audio tag |
| 202 | add_filter( 'wcmp_audio_tag', array( &$this, 'add_data_product' ), 99, 4 ); |
| 203 | |
| 204 | // Add class name to the feature image of product |
| 205 | add_filter( 'woocommerce_product_get_image', array( &$this, 'add_class_attachment' ), 99, 6 ); |
| 206 | add_filter( 'woocommerce_single_product_image_thumbnail_html', array( &$this, 'add_class_single_product_image' ), 99, 2 ); |
| 207 | |
| 208 | // Include players with the titles |
| 209 | if ( |
| 210 | $this->get_global_attr( '_wcmp_force_main_player_in_title', 1 ) && |
| 211 | ! empty( $_SERVER['REQUEST_URI'] ) |
| 212 | /* |
| 213 | ! empty( $_SERVER['REQUEST_URI'] ) && |
| 214 | stripos( esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ), 'wc/store' ) !== false */ |
| 215 | ) { |
| 216 | add_filter( 'woocommerce_product_title', array( &$this, 'woocommerce_product_title' ), 10, 2 ); |
| 217 | |
| 218 | add_filter( 'esc_html', array( &$this, 'esc_html' ), 10, 2 ); |
| 219 | } |
| 220 | |
| 221 | // For accepting the <source> tags |
| 222 | add_filter( 'wp_kses_allowed_html', array( &$this, 'allowed_html_tags' ), 10, 2 ); |
| 223 | } |
| 224 | } else { |
| 225 | add_action( 'admin_menu', array( &$this, 'menu_links' ), 10 ); |
| 226 | } |
| 227 | |
| 228 | } // End init |
| 229 | |
| 230 | public function admin_init() { |
| 231 | // Check if WooCommerce is installed or not |
| 232 | if ( ! class_exists( 'woocommerce' ) ) { |
| 233 | return; |
| 234 | } |
| 235 | |
| 236 | add_meta_box( 'wcmp_woocommerce_metabox', __( 'Music Player for WooCommerce', 'music-player-for-woocommerce' ), array( &$this, 'woocommerce_player_settings' ), $this->_get_post_types(), 'normal' ); |
| 237 | add_action( 'save_post', array( &$this, 'save_post' ), 10, 3 ); |
| 238 | add_action( 'delete_post', array( &$this, 'delete_post' ) ); |
| 239 | add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), array( &$this, 'help_link' ) ); |
| 240 | } // End admin_init |
| 241 | |
| 242 | public function help_link( $links ) { |
| 243 | array_unshift( |
| 244 | $links, |
| 245 | '<a href="https://wordpress.org/support/plugin/music-player-for-woocommerce/#new-post" target="_blank">' . __( 'Help' ) . '</a>' |
| 246 | ); |
| 247 | return $links; |
| 248 | } // End help_link |
| 249 | |
| 250 | public function menu_links() { |
| 251 | add_options_page( 'Music Player for WooCommerce', 'Music Player for WooCommerce', 'manage_options', 'music-player-for-woocommerce-settings', array( &$this, 'settings_page' ) ); |
| 252 | } // End menu_links |
| 253 | |
| 254 | public function settings_page() { |
| 255 | if ( |
| 256 | isset( $_POST['wcmp_nonce'] ) && |
| 257 | wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['wcmp_nonce'] ) ), 'wcmp_updating_plugin_settings' ) |
| 258 | ) { |
| 259 | $_REQUEST = stripslashes_deep( $_REQUEST ); |
| 260 | // Save the player settings |
| 261 | $registered_only = ( isset( $_REQUEST['_wcmp_registered_only'] ) ) ? 1 : 0; |
| 262 | $fade_out = ( isset( $_REQUEST['_wcmp_fade_out'] ) ) ? 1 : 0; |
| 263 | $purchased_times_text = sanitize_text_field( isset( $_REQUEST['_wcmp_purchased_times_text'] ) ? wp_unslash( $_REQUEST['_wcmp_purchased_times_text'] ) : '' ); |
| 264 | $troubleshoot_default_extension = ( isset( $_REQUEST['_wcmp_default_extension'] ) ) ? true : false; |
| 265 | $force_main_player_in_title = ( isset( $_REQUEST['_wcmp_force_main_player_in_title'] ) ) ? 1 : 0; |
| 266 | $ios_controls = ( isset( $_REQUEST['_wcmp_ios_controls'] ) ) ? true : false; |
| 267 | $troubleshoot_onload = ( isset( $_REQUEST['_wcmp_onload'] ) ) ? true : false; |
| 268 | $include_main_player_hook = ( isset( $_REQUEST['_wcmp_main_player_hook'] ) ) ? sanitize_text_field( wp_unslash( $_REQUEST['_wcmp_main_player_hook'] ) ) : ''; |
| 269 | $main_player_hook_title = ( isset( $_REQUEST['_wcmp_main_player_hook_title'] ) ) ? 1 : 0; |
| 270 | $include_all_players_hook = ( isset( $_REQUEST['_wcmp_all_players_hook'] ) ) ? sanitize_text_field( wp_unslash( $_REQUEST['_wcmp_all_players_hook'] ) ) : ''; |
| 271 | |
| 272 | $enable_player = ( isset( $_REQUEST['_wcmp_enable_player'] ) ) ? 1 : 0; |
| 273 | $show_in = ( isset( $_REQUEST['_wcmp_show_in'] ) && in_array( $_REQUEST['_wcmp_show_in'], array( 'single', 'multiple' ) ) ) ? sanitize_text_field( wp_unslash( $_REQUEST['_wcmp_show_in'] ) ) : 'all'; |
| 274 | $players_in_cart = ( isset( $_REQUEST['_wcmp_players_in_cart'] ) ) ? true : false; |
| 275 | $player_style = ( |
| 276 | isset( $_REQUEST['_wcmp_player_layout'] ) && |
| 277 | in_array( $_REQUEST['_wcmp_player_layout'], $this->_player_layouts ) |
| 278 | ) ? sanitize_text_field( wp_unslash( $_REQUEST['_wcmp_player_layout'] ) ) : WCMP_DEFAULT_PLAYER_LAYOUT; |
| 279 | $player_controls = ( |
| 280 | isset( $_REQUEST['_wcmp_player_controls'] ) && |
| 281 | in_array( $_REQUEST['_wcmp_player_controls'], $this->_player_controls ) |
| 282 | ) ? sanitize_text_field( wp_unslash( $_REQUEST['_wcmp_player_controls'] ) ) : WCMP_DEFAULT_PLAYER_CONTROLS; |
| 283 | |
| 284 | $on_cover = ( ( 'button' == $player_controls || 'default' == $player_controls ) && isset( $_REQUEST['_wcmp_player_on_cover'] ) ) ? 1 : 0; |
| 285 | |
| 286 | $player_title = ( isset( $_REQUEST['_wcmp_player_title'] ) ) ? 1 : 0; |
| 287 | $merge_grouped = ( isset( $_REQUEST['_wcmp_merge_in_grouped'] ) ) ? 1 : 0; |
| 288 | $play_all = ( isset( $_REQUEST['_wcmp_play_all'] ) ) ? 1 : 0; |
| 289 | $play_simultaneously = ( isset( $_REQUEST['_wcmp_play_simultaneously'] ) ) ? 1 : 0; |
| 290 | $volume = ( isset( $_REQUEST['_wcmp_player_volume'] ) && is_numeric( $_REQUEST['_wcmp_player_volume'] ) ) ? floatval( $_REQUEST['_wcmp_player_volume'] ) : 1; |
| 291 | $preload = ( |
| 292 | isset( $_REQUEST['_wcmp_preload'] ) && |
| 293 | in_array( $_REQUEST['_wcmp_preload'], array( 'none', 'metadata', 'auto' ) ) |
| 294 | ) ? sanitize_text_field( wp_unslash( $_REQUEST['_wcmp_preload'] ) ) : 'none'; |
| 295 | |
| 296 | $apply_to_all_players = ( isset( $_REQUEST['_wcmp_apply_to_all_players'] ) ) ? 1 : 0; |
| 297 | |
| 298 | $global_settings = array( |
| 299 | '_wcmp_registered_only' => $registered_only, |
| 300 | '_wcmp_fade_out' => $fade_out, |
| 301 | '_wcmp_purchased_times_text' => $purchased_times_text, |
| 302 | '_wcmp_enable_player' => $enable_player, |
| 303 | '_wcmp_show_in' => $show_in, |
| 304 | '_wcmp_players_in_cart' => $players_in_cart, |
| 305 | '_wcmp_player_layout' => $player_style, |
| 306 | '_wcmp_player_volume' => $volume, |
| 307 | '_wcmp_player_controls' => $player_controls, |
| 308 | '_wcmp_player_title' => $player_title, |
| 309 | '_wcmp_merge_in_grouped' => $merge_grouped, |
| 310 | '_wcmp_play_all' => $play_all, |
| 311 | '_wcmp_play_simultaneously' => $play_simultaneously, |
| 312 | '_wcmp_preload' => $preload, |
| 313 | '_wcmp_on_cover' => $on_cover, |
| 314 | '_wcmp_default_extension' => $troubleshoot_default_extension, |
| 315 | '_wcmp_force_main_player_in_title' => $force_main_player_in_title, |
| 316 | '_wcmp_ios_controls' => $ios_controls, |
| 317 | '_wcmp_onload' => $troubleshoot_onload, |
| 318 | '_wcmp_main_player_hook' => $include_main_player_hook, |
| 319 | '_wcmp_main_player_hook_title' => $main_player_hook_title, |
| 320 | '_wcmp_all_players_hook' => $include_all_players_hook, |
| 321 | '_wcmp_analytics_integration' => ( isset( $_REQUEST['_wcmp_analytics_integration'] ) ) ? sanitize_text_field( wp_unslash( $_REQUEST['_wcmp_analytics_integration'] ) ) : 'ua', |
| 322 | '_wcmp_analytics_property' => ( isset( $_REQUEST['_wcmp_analytics_property'] ) ) ? sanitize_text_field( wp_unslash( $_REQUEST['_wcmp_analytics_property'] ) ) : '', |
| 323 | '_wcmp_analytics_api_secret' => ( isset( $_REQUEST['_wcmp_analytics_api_secret'] ) ) ? sanitize_text_field( wp_unslash( $_REQUEST['_wcmp_analytics_api_secret'] ) ) : '', |
| 324 | '_wcmp_apply_to_all_players' => $apply_to_all_players, |
| 325 | ); |
| 326 | |
| 327 | if ( $apply_to_all_players ) { |
| 328 | $this->_deleteDir( $this->_files_directory_path ); |
| 329 | |
| 330 | $products_ids = array( |
| 331 | 'post_type' => $this->_get_post_types(), |
| 332 | 'numberposts' => -1, |
| 333 | 'post_status' => array( 'publish', 'pending', 'draft', 'future' ), |
| 334 | 'fields' => 'ids', |
| 335 | 'cache_results' => false, |
| 336 | ); |
| 337 | |
| 338 | $products = get_posts( $products_ids ); |
| 339 | foreach ( $products as $product_id ) { |
| 340 | update_post_meta( $product_id, '_wcmp_enable_player', $enable_player ); |
| 341 | update_post_meta( $product_id, '_wcmp_show_in', $show_in ); |
| 342 | update_post_meta( $product_id, '_wcmp_player_layout', $player_style ); |
| 343 | update_post_meta( $product_id, '_wcmp_player_controls', $player_controls ); |
| 344 | update_post_meta( $product_id, '_wcmp_player_volume', $volume ); |
| 345 | update_post_meta( $product_id, '_wcmp_player_title', $player_title ); |
| 346 | update_post_meta( $product_id, '_wcmp_merge_in_grouped', $merge_grouped ); |
| 347 | update_post_meta( $product_id, '_wcmp_play_all', $play_all ); |
| 348 | update_post_meta( $product_id, '_wcmp_preload', $preload ); |
| 349 | update_post_meta( $product_id, '_wcmp_on_cover', $on_cover ); |
| 350 | } |
| 351 | } |
| 352 | |
| 353 | update_option( 'wcmp_global_settings', $global_settings ); |
| 354 | $this->_global_attrs = $global_settings; |
| 355 | do_action( 'wcmp_save_setting' ); |
| 356 | } // Save settings |
| 357 | |
| 358 | print '<div class="wrap">'; // Open Wrap |
| 359 | include_once dirname( __FILE__ ) . '/views/global_options.php'; |
| 360 | print '</div>'; // Close Wrap |
| 361 | } // End settings_page |
| 362 | |
| 363 | public function save_post( $post_id, $post, $update ) { |
| 364 | if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) { |
| 365 | return; |
| 366 | } |
| 367 | if ( empty( $_POST['wcmp_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['wcmp_nonce'] ) ), 'wcmp_updating_product' ) ) { |
| 368 | return; |
| 369 | } |
| 370 | $post_types = $this->_get_post_types(); |
| 371 | if ( ! isset( $post ) || ! in_array( $post->post_type, $post_types ) || ! current_user_can( 'edit_post', $post_id ) ) { |
| 372 | return; |
| 373 | } |
| 374 | |
| 375 | $this->delete_post( $post_id ); |
| 376 | |
| 377 | // Save the player options |
| 378 | $enable_player = ( isset( $_REQUEST['_wcmp_enable_player'] ) ) ? 1 : 0; |
| 379 | $show_in = ( isset( $_REQUEST['_wcmp_show_in'] ) && in_array( $_REQUEST['_wcmp_show_in'], array( 'single', 'multiple' ) ) ) ? sanitize_text_field( wp_unslash( $_REQUEST['_wcmp_show_in'] ) ) : 'all'; |
| 380 | $player_style = ( |
| 381 | isset( $_REQUEST['_wcmp_player_layout'] ) && |
| 382 | in_array( $_REQUEST['_wcmp_player_layout'], $this->_player_layouts ) |
| 383 | ) ? sanitize_text_field( wp_unslash( $_REQUEST['_wcmp_player_layout'] ) ) : WCMP_DEFAULT_PLAYER_LAYOUT; |
| 384 | |
| 385 | $player_controls = ( |
| 386 | isset( $_REQUEST['_wcmp_player_controls'] ) && |
| 387 | in_array( $_REQUEST['_wcmp_player_controls'], $this->_player_controls ) |
| 388 | ) ? sanitize_text_field( wp_unslash( $_REQUEST['_wcmp_player_controls'] ) ) : WCMP_DEFAULT_PLAYER_CONTROLS; |
| 389 | |
| 390 | $player_title = ( isset( $_REQUEST['_wcmp_player_title'] ) ) ? 1 : 0; |
| 391 | $merge_grouped = ( isset( $_REQUEST['_wcmp_merge_in_grouped'] ) ) ? 1 : 0; |
| 392 | $play_all = ( isset( $_REQUEST['_wcmp_play_all'] ) ) ? 1 : 0; |
| 393 | $volume = ( isset( $_REQUEST['_wcmp_player_volume'] ) && is_numeric( $_REQUEST['_wcmp_player_volume'] ) ) ? floatval( $_REQUEST['_wcmp_player_volume'] ) : 1; |
| 394 | $preload = ( |
| 395 | isset( $_REQUEST['_wcmp_preload'] ) && |
| 396 | in_array( $_REQUEST['_wcmp_preload'], array( 'none', 'metadata', 'auto' ) ) |
| 397 | ) ? sanitize_text_field( wp_unslash( $_REQUEST['_wcmp_preload'] ) ) : 'none'; |
| 398 | |
| 399 | $on_cover = ( ( 'button' == $player_controls || 'default' == $player_controls ) && isset( $_REQUEST['_wcmp_player_on_cover'] ) ) ? 1 : 0; |
| 400 | |
| 401 | add_post_meta( $post_id, '_wcmp_enable_player', $enable_player, true ); |
| 402 | add_post_meta( $post_id, '_wcmp_show_in', $show_in, true ); |
| 403 | add_post_meta( $post_id, '_wcmp_player_layout', $player_style, true ); |
| 404 | add_post_meta( $post_id, '_wcmp_player_volume', $volume, true ); |
| 405 | add_post_meta( $post_id, '_wcmp_player_controls', $player_controls, true ); |
| 406 | add_post_meta( $post_id, '_wcmp_player_title', $player_title, true ); |
| 407 | add_post_meta( $post_id, '_wcmp_merge_in_grouped', $merge_grouped, true ); |
| 408 | add_post_meta( $post_id, '_wcmp_preload', $preload, true ); |
| 409 | add_post_meta( $post_id, '_wcmp_play_all', $play_all, true ); |
| 410 | add_post_meta( $post_id, '_wcmp_on_cover', $on_cover, true ); |
| 411 | } // End save_post |
| 412 | |
| 413 | public function delete_post( $post_id ) { |
| 414 | $post = get_post( $post_id ); |
| 415 | $post_types = $this->_get_post_types(); |
| 416 | if ( ! isset( $post ) || ! in_array( $post->post_type, $post_types ) || ! current_user_can( 'edit_post', $post_id ) ) { |
| 417 | return; |
| 418 | } |
| 419 | |
| 420 | // Delete truncated version of the audio file |
| 421 | $this->_delete_truncated_files( $post_id ); |
| 422 | |
| 423 | delete_post_meta( $post_id, '_wcmp_enable_player' ); |
| 424 | delete_post_meta( $post_id, '_wcmp_show_in' ); |
| 425 | delete_post_meta( $post_id, '_wcmp_merge_in_grouped' ); |
| 426 | delete_post_meta( $post_id, '_wcmp_player_layout' ); |
| 427 | delete_post_meta( $post_id, '_wcmp_player_volume' ); |
| 428 | delete_post_meta( $post_id, '_wcmp_player_controls' ); |
| 429 | delete_post_meta( $post_id, '_wcmp_player_title' ); |
| 430 | delete_post_meta( $post_id, '_wcmp_preload' ); |
| 431 | delete_post_meta( $post_id, '_wcmp_play_all' ); |
| 432 | delete_post_meta( $post_id, '_wcmp_on_cover' ); |
| 433 | } // End delete_post |
| 434 | |
| 435 | public function esc_html( $safe_text, $text ) { |
| 436 | if ( strpos( $safe_text, 'wcmp-player-container' ) !== false ) { |
| 437 | return $text; |
| 438 | } |
| 439 | return $safe_text; |
| 440 | } // End esc_html |
| 441 | |
| 442 | public function enqueue_resources() { |
| 443 | if ( $this->_enqueued_resources ) { |
| 444 | return; |
| 445 | } |
| 446 | $this->_enqueued_resources = true; |
| 447 | |
| 448 | if ( function_exists( 'wp_add_inline_script' ) ) { |
| 449 | wp_add_inline_script( 'wp-mediaelement', 'try{if(mejs && mejs.i18n && "undefined" == typeof mejs.i18n.locale) mejs.i18n.locale={};}catch(mejs_err){if(console) console.log(mejs_err);};' ); |
| 450 | } |
| 451 | |
| 452 | // Registering resources |
| 453 | wp_enqueue_style( 'wp-mediaelement' ); |
| 454 | wp_enqueue_style( 'wp-mediaelement-skins', plugin_dir_url( __FILE__ ) . 'vendors/mejs-skins/mejs-skins.min.css', array(), WCMP_VERSION ); |
| 455 | wp_enqueue_style( 'wcmp-style', plugin_dir_url( __FILE__ ) . 'css/style.css', array(), WCMP_VERSION ); |
| 456 | wp_enqueue_script( 'jquery' ); |
| 457 | wp_enqueue_script( 'wp-mediaelement' ); |
| 458 | wp_enqueue_script( 'wcmp-script', plugin_dir_url( __FILE__ ) . 'js/public.js', array( 'jquery', 'wp-mediaelement' ), WCMP_VERSION ); |
| 459 | |
| 460 | $play_all = $GLOBALS['WooCommerceMusicPlayer']->get_global_attr( |
| 461 | '_wcmp_play_all', |
| 462 | // This option is only for compatibility with versions previous to 1.0.28 |
| 463 | $GLOBALS['WooCommerceMusicPlayer']->get_global_attr( 'play_all', 0 ) |
| 464 | ); |
| 465 | |
| 466 | $play_simultaneously = $GLOBALS['WooCommerceMusicPlayer']->get_global_attr( '_wcmp_play_simultaneously', 0 ); |
| 467 | |
| 468 | if ( function_exists( 'is_product' ) && is_product() ) { |
| 469 | global $post; |
| 470 | $post_types = $this->_get_post_types(); |
| 471 | if ( ! empty( $post ) && in_array( $post->post_type, $post_types ) ) { |
| 472 | $play_all = $GLOBALS['WooCommerceMusicPlayer']->get_product_attr( |
| 473 | $post->ID, |
| 474 | '_wcmp_play_all', |
| 475 | // This option is only for compatibility with versions previous to 1.0.28 |
| 476 | $GLOBALS['WooCommerceMusicPlayer']->get_product_attr( |
| 477 | $post->ID, |
| 478 | 'play_all', |
| 479 | $play_all |
| 480 | ) |
| 481 | ); |
| 482 | } |
| 483 | } |
| 484 | |
| 485 | wp_localize_script( |
| 486 | 'wcmp-script', |
| 487 | 'wcmp_global_settings', |
| 488 | array( |
| 489 | 'fade_out' => $GLOBALS['WooCommerceMusicPlayer']->get_global_attr( '_wcmp_fade_out', 1 ), |
| 490 | 'play_all' => intval( $play_all ), |
| 491 | 'play_simultaneously' => intval( $play_simultaneously ), |
| 492 | 'ios_controls' => $GLOBALS['WooCommerceMusicPlayer']->get_global_attr( '_wcmp_ios_controls', false ), |
| 493 | 'onload' => $GLOBALS['WooCommerceMusicPlayer']->get_global_attr( '_wcmp_onload', false ), |
| 494 | ) |
| 495 | ); |
| 496 | } // End enqueue_resources |
| 497 | |
| 498 | /** |
| 499 | * Replace the shortcode to display a playlist with all songs. |
| 500 | */ |
| 501 | public function replace_playlist_shortcode( $atts ) { |
| 502 | if ( ! class_exists( 'woocommerce' ) ) { |
| 503 | return ''; |
| 504 | } |
| 505 | |
| 506 | $get_times = function( $product_id, $products_list ) { |
| 507 | if ( ! empty( $products_list ) ) { |
| 508 | foreach ( $products_list as $product ) { |
| 509 | if ( $product->product_id == $product_id ) { |
| 510 | return $product->times; |
| 511 | } |
| 512 | } |
| 513 | } |
| 514 | return 0; |
| 515 | }; |
| 516 | |
| 517 | global $post; |
| 518 | |
| 519 | $output = ''; |
| 520 | if ( ! $this->_insert_player ) { |
| 521 | return $output; |
| 522 | } |
| 523 | |
| 524 | if ( ! is_array( $atts ) ) { |
| 525 | $atts = array(); |
| 526 | } |
| 527 | $post_types = $this->_get_post_types(); |
| 528 | if ( |
| 529 | empty( $atts['products_ids'] ) && |
| 530 | empty( $atts['purchased_products'] ) && |
| 531 | ! empty( $post ) && |
| 532 | in_array( $post->post_type, $post_types ) |
| 533 | ) { |
| 534 | try { |
| 535 | ob_start(); |
| 536 | $this->include_all_players( $post->ID ); |
| 537 | $output = ob_get_contents(); |
| 538 | ob_end_clean(); |
| 539 | |
| 540 | $class = esc_attr( isset( $atts['class'] ) ? $atts['class'] : '' ); |
| 541 | |
| 542 | return strpos( $output, 'wcmp-player-list' ) !== false ? |
| 543 | str_replace( 'wcmp-player-list', $class . ' wcmp-player-list', $output ) : |
| 544 | str_replace( 'wcmp-player-container', $class . ' wcmp-player-container', $output ); |
| 545 | } catch ( Exception $err ) { |
| 546 | $atts['products_ids'] = $post->ID; |
| 547 | } |
| 548 | } |
| 549 | |
| 550 | $atts = shortcode_atts( |
| 551 | array( |
| 552 | 'products_ids' => '*', |
| 553 | 'purchased_products' => 0, |
| 554 | 'highlight_current_product' => 0, |
| 555 | 'continue_playing' => 0, |
| 556 | 'player_style' => WCMP_DEFAULT_PLAYER_LAYOUT, |
| 557 | 'controls' => 'track', |
| 558 | 'layout' => 'new', |
| 559 | 'cover' => 0, |
| 560 | 'volume' => 1, |
| 561 | 'hide_purchase_buttons' => 0, |
| 562 | 'class' => '', |
| 563 | 'loop' => 0, |
| 564 | 'purchased_times' => 0, |
| 565 | ), |
| 566 | $atts |
| 567 | ); |
| 568 | |
| 569 | $products_ids = $atts['products_ids']; |
| 570 | $purchased_products = $atts['purchased_products']; |
| 571 | $highlight_current_product = $atts['highlight_current_product']; |
| 572 | $continue_playing = $atts['continue_playing']; |
| 573 | $player_style = $atts['player_style']; |
| 574 | $controls = $atts['controls']; |
| 575 | $layout = $atts['layout']; |
| 576 | $cover = $atts['cover']; |
| 577 | $volume = $atts['volume']; |
| 578 | $hide_purchase_buttons = $atts['hide_purchase_buttons']; |
| 579 | $class = $atts['class']; |
| 580 | $loop = $atts['loop']; |
| 581 | $purchased_times = $atts['purchased_times']; |
| 582 | |
| 583 | // Typecasting variables. |
| 584 | $cover = is_numeric( $cover ) ? intval( $cover ) : 0; |
| 585 | $volume = is_numeric( $volume ) ? floatval( $volume ) : 0; |
| 586 | $purchased_products = is_numeric( $purchased_products ) ? intval( $purchased_products ) : 0; |
| 587 | $highlight_current_product = is_numeric( $highlight_current_product ) ? intval( $highlight_current_product ) : 0; |
| 588 | $continue_playing = is_numeric( $continue_playing ) ? intval( $continue_playing ) : 0; |
| 589 | $hide_purchase_buttons = is_numeric( $hide_purchase_buttons ) ? intval( $hide_purchase_buttons ) : 0; |
| 590 | $loop = is_numeric( $loop ) ? intval( $loop ) : 0; |
| 591 | $purchased_times = is_numeric( $purchased_times ) ? intval( $purchased_times ) : 0; |
| 592 | |
| 593 | // get the produts ids |
| 594 | $products_ids = preg_replace( '/[^\d\,\*]/', '', $products_ids ); |
| 595 | $products_ids = preg_replace( '/(\,\,)+/', '', $products_ids ); |
| 596 | $products_ids = trim( $products_ids, ',' ); |
| 597 | |
| 598 | if ( strlen( $products_ids ) == 0 ) { |
| 599 | return $output; |
| 600 | } |
| 601 | |
| 602 | // MAIN CODE GOES HERE |
| 603 | global $wpdb, $post; |
| 604 | |
| 605 | $current_post_id = ! empty( $post ) ? ( is_int( $post ) ? $post : $post->ID ) : -1; |
| 606 | |
| 607 | $query = 'SELECT posts.ID FROM ' . $wpdb->posts . ' AS posts, ' . $wpdb->postmeta . ' as postmeta WHERE posts.post_status="publish" AND posts.post_type IN (' . $this->_get_post_types( true ) . ') AND posts.ID = postmeta.post_id AND postmeta.meta_key="_wcmp_enable_player" AND (postmeta.meta_value="yes" OR postmeta.meta_value="1")'; |
| 608 | |
| 609 | if ( ! empty( $purchased_products ) ) { |
| 610 | // Hide the purchase buttons |
| 611 | $hide_purchase_buttons = 1; |
| 612 | |
| 613 | // Getting the list of purchased products |
| 614 | $_current_user_id = get_current_user_id(); |
| 615 | if ( 0 == $_current_user_id ) { |
| 616 | return $output; |
| 617 | } |
| 618 | |
| 619 | // GET USER ORDERS (COMPLETED + PROCESSING) |
| 620 | $customer_orders = get_posts( |
| 621 | array( |
| 622 | 'numberposts' => -1, |
| 623 | 'meta_key' => '_customer_user', |
| 624 | 'meta_value' => $_current_user_id, |
| 625 | 'post_type' => wc_get_order_types(), |
| 626 | 'post_status' => array_keys( wc_get_is_paid_statuses() ), |
| 627 | ) |
| 628 | ); |
| 629 | |
| 630 | if ( empty( $customer_orders ) ) { |
| 631 | return $output; |
| 632 | } |
| 633 | |
| 634 | // LOOP THROUGH ORDERS AND GET PRODUCT IDS |
| 635 | $products_ids = array(); |
| 636 | |
| 637 | foreach ( $customer_orders as $customer_order ) { |
| 638 | $order = wc_get_order( $customer_order->ID ); |
| 639 | $items = $order->get_items(); |
| 640 | foreach ( $items as $item ) { |
| 641 | $product_id = $item->get_product_id(); |
| 642 | $products_ids[] = $product_id; |
| 643 | } |
| 644 | } |
| 645 | $products_ids = array_unique( $products_ids ); |
| 646 | $products_ids_str = implode( ',', $products_ids ); |
| 647 | |
| 648 | $query .= ' AND posts.ID IN (' . $products_ids_str . ')'; |
| 649 | $query .= ' ORDER BY FIELD(posts.ID,' . $products_ids_str . ')'; |
| 650 | } else { |
| 651 | if ( strpos( '*', $products_ids ) === false ) { |
| 652 | $query .= ' AND posts.ID IN (' . $products_ids . ')'; |
| 653 | $query .= ' ORDER BY FIELD(posts.ID,' . $products_ids . ')'; |
| 654 | } else { |
| 655 | $query .= ' ORDER BY posts.post_title ASC'; |
| 656 | } |
| 657 | } |
| 658 | |
| 659 | $products = $wpdb->get_results( $query ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared |
| 660 | |
| 661 | if ( ! empty( $products ) ) { |
| 662 | $product_purchased_times = array(); |
| 663 | if ( $purchased_times ) { |
| 664 | $products_ids_str = ( is_array( $products_ids ) ) ? implode( ',', $products_ids ) : $products_ids; |
| 665 | |
| 666 | $product_purchased_times = $wpdb->get_results( 'SELECT order_itemmeta.meta_value product_id, COUNT(order_itemmeta.meta_value) as times FROM ' . $wpdb->prefix . 'posts as orders INNER JOIN ' . $wpdb->prefix . 'woocommerce_order_items as order_items ON (orders.ID=order_items.order_id) INNER JOIN ' . $wpdb->prefix . 'woocommerce_order_itemmeta as order_itemmeta ON (order_items.order_item_id=order_itemmeta.order_item_id) WHERE orders.post_type="shop_order" AND orders.post_status="wc-completed" AND order_itemmeta.meta_key="_product_id" ' . ( strlen( $products_ids_str ) && false === strpos( '*', $products_ids_str ) ? ' AND order_itemmeta.meta_value IN (' . $products_ids_str . ')' : '' ) . ' GROUP BY order_itemmeta.meta_value' ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared |
| 667 | } |
| 668 | |
| 669 | // Enqueue resources |
| 670 | |
| 671 | $this->enqueue_resources(); |
| 672 | wp_enqueue_style( 'wcmp-playlist-widget-style', plugin_dir_url( __FILE__ ) . 'widgets/playlist_widget/css/style.css', array(), WCMP_VERSION ); |
| 673 | wp_enqueue_script( 'wcmp-playlist-widget-script', plugin_dir_url( __FILE__ ) . 'widgets/playlist_widget/js/public.js', array(), WCMP_VERSION ); |
| 674 | wp_localize_script( |
| 675 | 'wcmp-playlist-widget-script', |
| 676 | 'wcmp_widget_settings', |
| 677 | array( 'continue_playing' => $continue_playing ) |
| 678 | ); |
| 679 | $counter = 0; |
| 680 | $output .= '<div data-loop="' . ( $loop ? 1 : 0 ) . '">'; |
| 681 | foreach ( $products as $product ) { |
| 682 | $product_obj = wc_get_product( $product->ID ); |
| 683 | $counter++; |
| 684 | $preload = $this->get_product_attr( $product->ID, '_wcmp_preload', '' ); |
| 685 | $row_class = 'wcmp-even-product'; |
| 686 | if ( 1 == $counter % 2 ) { |
| 687 | $row_class = 'wcmp-odd-product'; |
| 688 | } |
| 689 | |
| 690 | $audio_files = $this->get_product_files( $product->ID ); |
| 691 | if ( ! is_array( $audio_files ) ) { |
| 692 | continue; |
| 693 | } |
| 694 | |
| 695 | if ( $cover ) { |
| 696 | $featured_image = get_the_post_thumbnail_url( $product->ID ); |
| 697 | } |
| 698 | |
| 699 | if ( 'new' == $layout ) { |
| 700 | $price = $product_obj->get_price(); |
| 701 | $output .= ' |
| 702 | <div class="wcmp-widget-product controls-' . esc_attr( $controls ) . ' ' . esc_attr( $class ) . ' ' . esc_attr( $row_class ) . ' ' . esc_attr( ( $product->ID == $current_post_id && $highlight_current_product ) ? 'wcmp-current-product' : '' ) . '"> |
| 703 | <div class="wcmp-widget-product-header"> |
| 704 | <div class="wcmp-widget-product-title"> |
| 705 | <a href="' . esc_url( get_permalink( $product->ID ) ) . '">' . $product_obj->get_name() . '</a>' . |
| 706 | ( |
| 707 | $purchased_times ? |
| 708 | '<span class="wcmp-purchased-times">' . |
| 709 | sprintf( |
| 710 | /* translators: %d: purchased times */ |
| 711 | __( $this->get_global_attr( '_wcmp_purchased_times_text', '- purchased %d time(s)' ), 'music-player-for-woocommerce' ), // phpcs:ignore WordPress.WP.I18n.NonSingularStringLiteralText |
| 712 | $get_times( $product->ID, $product_purchased_times ) |
| 713 | ) . '</span>' : '' |
| 714 | ) . |
| 715 | '</div><!-- product title --> |
| 716 | '; |
| 717 | if ( 0 != @floatval( $price ) && 0 == $hide_purchase_buttons ) { |
| 718 | $output .= '<div class="wcmp-widget-product-purchase"> |
| 719 | ' . wc_price( $product_obj->get_price(), '' ) . ' <a href="?add-to-cart=' . $product->ID . '"></a> |
| 720 | </div><!-- product purchase --> |
| 721 | '; |
| 722 | } |
| 723 | $output .= '</div> |
| 724 | <div class="wcmp-widget-product-files"> |
| 725 | '; |
| 726 | |
| 727 | if ( ! empty( $featured_image ) ) { |
| 728 | $output .= '<img src="' . esc_attr( $featured_image ) . '" class="wcmp-widget-feature-image" /><div class="wcmp-widget-product-files-list">'; |
| 729 | } |
| 730 | |
| 731 | foreach ( $audio_files as $index => $file ) { |
| 732 | $audio_url = $this->generate_audio_url( $product->ID, $index, $file ); |
| 733 | $duration = $this->_get_duration_by_url( $file['file'] ); |
| 734 | $audio_tag = apply_filters( |
| 735 | 'wcmp_widget_audio_tag', |
| 736 | $this->get_player( |
| 737 | $audio_url, |
| 738 | array( |
| 739 | 'player_controls' => $controls, |
| 740 | 'player_style' => $player_style, |
| 741 | 'media_type' => $file['media_type'], |
| 742 | 'id' => $index, |
| 743 | 'duration' => $duration, |
| 744 | 'preload' => $preload, |
| 745 | 'volume' => $volume, |
| 746 | ) |
| 747 | ), |
| 748 | $product->ID, |
| 749 | $index, |
| 750 | $audio_url |
| 751 | ); |
| 752 | $file_title = esc_html( apply_filters( 'wcmp_widget_file_name', $file['name'], $product->ID, $index ) ); |
| 753 | $output .= ' |
| 754 | <div class="wcmp-widget-product-file"> |
| 755 | ' . $audio_tag . '' . $file_title . '<div style="clear:both;"></div> |
| 756 | </div><!--product file --> |
| 757 | '; |
| 758 | } |
| 759 | |
| 760 | if ( ! empty( $featured_image ) ) { |
| 761 | $output .= '</div>'; |
| 762 | } |
| 763 | |
| 764 | $output .= ' |
| 765 | </div><!-- product-files --> |
| 766 | </div><!-- product --> |
| 767 | '; |
| 768 | } else // Load the previous playlist layout |
| 769 | { |
| 770 | $output .= '<ul class="wcmp-widget-playlist controls-' . esc_attr( $controls ) . ' ' . esc_attr( $class ) . ' ' . esc_attr( $row_class ) . ' ' . esc_attr( ( $product->ID == $current_post_id && $highlight_current_product ) ? 'wcmp-current-product' : '' ) . '">'; |
| 771 | |
| 772 | if ( ! empty( $featured_image ) ) { |
| 773 | $output .= '<li style="display:table-row;"><img src="' . esc_attr( $featured_image ) . '" class="wcmp-widget-feature-image" /><div class="wcmp-widget-product-files-list"><ul>'; |
| 774 | } |
| 775 | |
| 776 | foreach ( $audio_files as $index => $file ) { |
| 777 | $audio_url = $this->generate_audio_url( $product->ID, $index, $file ); |
| 778 | $duration = $this->_get_duration_by_url( $file['file'] ); |
| 779 | $audio_tag = apply_filters( |
| 780 | 'wcmp_widget_audio_tag', |
| 781 | $this->get_player( |
| 782 | $audio_url, |
| 783 | array( |
| 784 | 'player_controls' => $controls, |
| 785 | 'player_style' => $player_style, |
| 786 | 'media_type' => $file['media_type'], |
| 787 | 'id' => $index, |
| 788 | 'duration' => $duration, |
| 789 | 'preload' => $preload, |
| 790 | 'volume' => $volume, |
| 791 | ) |
| 792 | ), |
| 793 | $product->ID, |
| 794 | $index, |
| 795 | $audio_url |
| 796 | ); |
| 797 | $file_title = esc_html( apply_filters( 'wcmp_widget_file_name', ( ( ! empty( $file['name'] ) ) ? $file['name'] : $product->post_title ), $product->ID, $index ) ); |
| 798 | |
| 799 | $output .= '<li class="wcmp-widget-playlist-item">' . $audio_tag . '<a href="' . esc_url( get_permalink( $product->ID ) ) . '">' . $file_title . '</a>' . |
| 800 | ( |
| 801 | $purchased_times ? |
| 802 | '<span class="wcmp-purchased-times">' . |
| 803 | sprintf( |
| 804 | /* translators: %d: purchased times */ |
| 805 | __( $this->get_global_attr( '_wcmp_purchased_times_text', '- purchased %d time(s)' ), 'music-player-for-woocommerce' ), // phpcs:ignore WordPress.WP.I18n.NonSingularStringLiteralText |
| 806 | $get_times( $product->ID, $product_purchased_times ) |
| 807 | ) . '</span>' : '' |
| 808 | ) |
| 809 | . '<div style="clear:both;"/></li>'; |
| 810 | } |
| 811 | if ( ! empty( $featured_image ) ) { |
| 812 | $output .= '</ul></div></li>'; |
| 813 | } |
| 814 | $output .= '</ul>'; |
| 815 | } |
| 816 | } |
| 817 | $output .= '</div>'; |
| 818 | } |
| 819 | return $output; |
| 820 | } // End replace_playlist_shortcode |
| 821 | |
| 822 | /** |
| 823 | * Used for accepting the <source> tags |
| 824 | */ |
| 825 | public function allowed_html_tags( $allowedposttags, $context ) { |
| 826 | if ( ! in_array( 'source', $allowedposttags ) ) { |
| 827 | $allowedposttags['source'] = array( |
| 828 | 'src' => true, |
| 829 | 'type' => true, |
| 830 | ); |
| 831 | } |
| 832 | return $allowedposttags; |
| 833 | } // End allowed_html_tags |
| 834 | |
| 835 | public function preload( $preload, $audio_url ) { |
| 836 | $result = $preload; |
| 837 | if ( strpos( $audio_url, 'wcmp-action=play' ) !== false ) { |
| 838 | if ( $this->_preload_times ) { |
| 839 | $result = 'none'; |
| 840 | } |
| 841 | $this->_preload_times++; |
| 842 | } |
| 843 | return $result; |
| 844 | } // End preload |
| 845 | |
| 846 | // ******************** WOOCOMMERCE ACTIONS ************************ |
| 847 | |
| 848 | public function woocommerce_product_title( $title, $product ) { |
| 849 | global $wp; |
| 850 | if ( ! empty( $wp->query_vars['wcfm-products-manage'] )) { |
| 851 | return $title; |
| 852 | } |
| 853 | $player = ''; |
| 854 | ob_start(); |
| 855 | $this->include_main_player( $product ); |
| 856 | $player .= ob_get_contents(); |
| 857 | ob_end_clean(); |
| 858 | return $player . $title; |
| 859 | } // End woocommerce_product_title |
| 860 | |
| 861 | /** |
| 862 | * Load the additional attributes to select the player layout |
| 863 | */ |
| 864 | public function woocommerce_player_settings() { |
| 865 | include_once 'views/player_options.php'; |
| 866 | } // End woocommerce_player_settings |
| 867 | |
| 868 | public function get_player( |
| 869 | $audio_url, |
| 870 | $args = array() |
| 871 | ) { |
| 872 | $default_args = array( |
| 873 | 'media_type' => 'mp3', |
| 874 | 'player_style' => WCMP_DEFAULT_PLAYER_LAYOUT, |
| 875 | 'player_controls' => WCMP_DEFAULT_PLAYER_CONTROLS, |
| 876 | 'duration' => false, |
| 877 | 'volume' => 1, |
| 878 | ); |
| 879 | |
| 880 | $args = array_merge( $default_args, $args ); |
| 881 | $id = ( ! empty( $args['id'] ) ) ? 'id="' . esc_attr( $args['id'] ) . '"' : ''; |
| 882 | |
| 883 | $preload = ( ! empty( $args['preload'] ) ) ? $args['preload'] : $GLOBALS['WooCommerceMusicPlayer']->get_global_attr( |
| 884 | '_wcmp_preload', |
| 885 | // This option is only for compatibility with versions previous to 1.0.28 |
| 886 | $GLOBALS['WooCommerceMusicPlayer']->get_global_attr( 'preload', 'none' ) |
| 887 | ); |
| 888 | $preload = apply_filters( 'wcmp_preload', $preload, $audio_url ); |
| 889 | |
| 890 | return '<audio ' . ( |
| 891 | ( |
| 892 | isset( $args['volume'] ) && |
| 893 | is_numeric( $args['volume'] ) && |
| 894 | 0 <= $args['volume'] * 1 && |
| 895 | $args['volume'] * 1 <= 1 |
| 896 | ) ? 'volume="' . esc_attr( $args['volume'] ) . '"' : '' |
| 897 | ) . ' ' . $id . ' preload="none" data-lazyloading="' . esc_attr( $preload ) . '" class="wcmp-player ' . esc_attr( $args['player_controls'] ) . ' ' . esc_attr( $args['player_style'] ) . '" ' . ( ( ! empty( $args['duration'] ) ) ? 'data-duration="' . esc_attr( $args['duration'] ) . '"' : '' ) . '><source src="' . esc_url( $audio_url ) . '" type="audio/' . esc_attr( $args['media_type'] ) . '" /></audio>'; |
| 898 | |
| 899 | } // End get_player |
| 900 | |
| 901 | public function get_product_files( $id ) { |
| 902 | $product = wc_get_product( $id ); |
| 903 | if ( ! empty( $product ) ) { |
| 904 | return $this->_get_product_files( |
| 905 | array( |
| 906 | 'product' => $product, |
| 907 | 'all' => 1, |
| 908 | ) |
| 909 | ); |
| 910 | } |
| 911 | return array(); |
| 912 | } |
| 913 | |
| 914 | public function generate_audio_url( $product_id, $file_id, $file_data = array() ) { |
| 915 | return $this->_generate_audio_url( $product_id, $file_id, $file_data ); |
| 916 | } |
| 917 | |
| 918 | public function include_main_player_filter( $value, $id ) { |
| 919 | global $wp; |
| 920 | if ( $this->_force_hook_title ) { |
| 921 | try { |
| 922 | if ( |
| 923 | ( wp_doing_ajax() || ! is_admin() ) && |
| 924 | ( |
| 925 | ! function_exists( 'is_product' ) || |
| 926 | ! is_product() || |
| 927 | ( is_product() && get_queried_object_id() != $id ) |
| 928 | ) && |
| 929 | ! is_cart() && |
| 930 | ! is_page( 'cart' ) && |
| 931 | ! is_checkout() && |
| 932 | is_int( $id ) && |
| 933 | empty( $_REQUEST['wcmp_nonce'] ) && |
| 934 | empty( $wp->query_vars['wcfm-products-manage'] ) |
| 935 | ) { |
| 936 | $p = wc_get_product( $id ); |
| 937 | if ( ! empty( $p ) ) { |
| 938 | add_filter( 'esc_html', array( &$this, 'esc_html' ), 10, 2 ); |
| 939 | |
| 940 | $player = ''; |
| 941 | ob_start(); |
| 942 | $this->include_main_player( $p ); |
| 943 | $player = ob_get_contents(); |
| 944 | ob_end_clean(); |
| 945 | $value = $player . $value; |
| 946 | } |
| 947 | } |
| 948 | } catch ( Exception $err ) { |
| 949 | error_log( $err->getMessage() ); |
| 950 | } |
| 951 | } |
| 952 | return $value; |
| 953 | } |
| 954 | |
| 955 | public function include_main_player( $product = '', $_echo = true ) { |
| 956 | $output = ''; |
| 957 | if ( ! $this->_insert_player ) { |
| 958 | return $output; |
| 959 | } |
| 960 | if ( is_numeric( $product ) ) { |
| 961 | $product = wc_get_product( $product ); |
| 962 | } |
| 963 | if ( ! is_object( $product ) ) { |
| 964 | $product = wc_get_product(); |
| 965 | } |
| 966 | $files = $this->_get_product_files( |
| 967 | array( |
| 968 | 'product' => $product, |
| 969 | 'first' => true, |
| 970 | ) |
| 971 | ); |
| 972 | if ( ! empty( $files ) ) { |
| 973 | $id = $product->get_id(); |
| 974 | |
| 975 | $show_in = $this->get_product_attr( $id, '_wcmp_show_in', 'all' ); |
| 976 | if ( |
| 977 | ( 'single' == $show_in && ( ! function_exists( 'is_product' ) || ! is_product() ) ) || |
| 978 | ( 'multiple' == $show_in && ( function_exists( 'is_product' ) && is_product() ) && get_queried_object_id() == $id ) |
| 979 | ) { |
| 980 | return $output; |
| 981 | } |
| 982 | $preload = $this->get_product_attr( $id, '_wcmp_preload', '' ); |
| 983 | $this->enqueue_resources(); |
| 984 | |
| 985 | $player_style = $this->get_product_attr( $id, '_wcmp_player_layout', WCMP_DEFAULT_PLAYER_LAYOUT ); |
| 986 | $player_controls = ( $this->get_product_attr( $id, '_wcmp_player_controls', WCMP_DEFAULT_PLAYER_CONTROLS ) != 'all' ) ? 'track' : ''; |
| 987 | $volume = @floatval( $this->get_product_attr( $id, '_wcmp_player_volume', WCMP_DEFAULT_PLAYER_VOLUME ) ); |
| 988 | |
| 989 | $file = reset( $files ); |
| 990 | $index = key( $files ); |
| 991 | $audio_url = $this->_generate_audio_url( $id, $index, $file ); |
| 992 | $duration = $this->_get_duration_by_url( $file['file'] ); |
| 993 | $audio_tag = apply_filters( |
| 994 | 'wcmp_audio_tag', |
| 995 | $this->get_player( |
| 996 | $audio_url, |
| 997 | array( |
| 998 | 'player_controls' => $player_controls, |
| 999 | 'player_style' => $player_style, |
| 1000 | 'media_type' => $file['media_type'], |
| 1001 | 'duration' => $duration, |
| 1002 | 'preload' => $preload, |
| 1003 | 'volume' => $volume, |
| 1004 | ) |
| 1005 | ), |
| 1006 | $id, |
| 1007 | $index, |
| 1008 | $audio_url |
| 1009 | ); |
| 1010 | |
| 1011 | do_action( 'wcmp_before_player_shop_page', $id ); |
| 1012 | |
| 1013 | $output = '<div class="wcmp-player-container product-' . esc_attr( $file['product'] ) . '">' . $audio_tag . '</div>'; |
| 1014 | if ( $_echo ) { |
| 1015 | print $output; // phpcs:ignore WordPress.Security.EscapeOutput |
| 1016 | } |
| 1017 | |
| 1018 | do_action( 'wcmp_after_player_shop_page', $id ); |
| 1019 | |
| 1020 | return $output; // phpcs:ignore WordPress.Security.EscapeOutput |
| 1021 | } |
| 1022 | } // End include_main_player |
| 1023 | |
| 1024 | public function include_all_players( $product = '' ) { |
| 1025 | if ( ! $this->_insert_player ) { |
| 1026 | return; |
| 1027 | } |
| 1028 | if ( ! is_object( $product ) ) { |
| 1029 | $product = wc_get_product(); |
| 1030 | } |
| 1031 | $files = $this->_get_product_files( |
| 1032 | array( |
| 1033 | 'product' => $product, |
| 1034 | 'all' => true, |
| 1035 | ) |
| 1036 | ); |
| 1037 | if ( ! empty( $files ) ) { |
| 1038 | $id = $product->get_id(); |
| 1039 | |
| 1040 | $show_in = $this->get_product_attr( $id, '_wcmp_show_in', 'all' ); |
| 1041 | if ( |
| 1042 | ( 'single' == $show_in && ! is_singular() ) || |
| 1043 | ( 'multiple' == $show_in && is_singular() ) |
| 1044 | ) { |
| 1045 | return; |
| 1046 | } |
| 1047 | $preload = $this->get_product_attr( $id, '_wcmp_preload', '' ); |
| 1048 | $this->enqueue_resources(); |
| 1049 | $player_style = $this->get_product_attr( $id, '_wcmp_player_layout', WCMP_DEFAULT_PLAYER_LAYOUT ); |
| 1050 | $volume = @floatval( $this->get_product_attr( $id, '_wcmp_player_volume', WCMP_DEFAULT_PLAYER_VOLUME ) ); |
| 1051 | $player_controls = $this->get_product_attr( $id, '_wcmp_player_controls', WCMP_DEFAULT_PLAYER_CONTROLS ); |
| 1052 | $player_title = intval( $this->get_product_attr( $id, '_wcmp_player_title', WCMP_DEFAULT_PlAYER_TITLE ) ); |
| 1053 | $merge_grouped = intval( $this->get_product_attr( $id, '_wcmp_merge_in_grouped', 0 ) ); |
| 1054 | $merge_grouped_clss = ( $merge_grouped ) ? 'merge_in_grouped_products' : ''; |
| 1055 | |
| 1056 | $counter = count( $files ); |
| 1057 | |
| 1058 | do_action( 'wcmp_before_players_product_page', $id ); |
| 1059 | if ( 1 == $counter ) { |
| 1060 | $player_controls = ( 'button' == $player_controls ) ? 'track' : ''; |
| 1061 | $file = reset( $files ); |
| 1062 | $index = key( $files ); |
| 1063 | $audio_url = $this->_generate_audio_url( $id, $index, $file ); |
| 1064 | $duration = $this->_get_duration_by_url( $file['file'] ); |
| 1065 | $audio_tag = apply_filters( |
| 1066 | 'wcmp_audio_tag', |
| 1067 | $this->get_player( |
| 1068 | $audio_url, |
| 1069 | array( |
| 1070 | 'player_controls' => $player_controls, |
| 1071 | 'player_style' => $player_style, |
| 1072 | 'media_type' => $file['media_type'], |
| 1073 | 'duration' => $duration, |
| 1074 | 'preload' => $preload, |
| 1075 | 'volume' => $volume, |
| 1076 | ) |
| 1077 | ), |
| 1078 | $id, |
| 1079 | $index, |
| 1080 | $audio_url |
| 1081 | ); |
| 1082 | $title = esc_html( ( $player_title ) ? apply_filters( 'wcmp_file_name', $file['name'], $id, $index ) : '' ); |
| 1083 | print '<div class="wcmp-player-container ' . esc_attr( $merge_grouped_clss ) . ' product-' . esc_attr( $file['product'] ) . '">' . $audio_tag . '</div><div class="wcmp-player-title">' . wp_kses_post( $title ) . '</div><div style="clear:both;"></div>'; // phpcs:ignore WordPress.Security.EscapeOutput |
| 1084 | } elseif ( $counter > 1 ) { |
| 1085 | $before = '<table class="wcmp-player-list ' . $merge_grouped_clss . '">'; |
| 1086 | $after = ''; |
| 1087 | foreach ( $files as $index => $file ) { |
| 1088 | $evenOdd = ( 1 == $counter % 2 ) ? 'wcmp-odd-row' : 'wcmp-even-row'; |
| 1089 | $counter--; |
| 1090 | $audio_url = $this->_generate_audio_url( $id, $index, $file ); |
| 1091 | $duration = $this->_get_duration_by_url( $file['file'] ); |
| 1092 | $audio_tag = apply_filters( |
| 1093 | 'wcmp_audio_tag', |
| 1094 | $this->get_player( |
| 1095 | $audio_url, |
| 1096 | array( |
| 1097 | 'player_style' => $player_style, |
| 1098 | 'player_controls' => ( 'all' != $player_controls ) ? 'track' : '', |
| 1099 | 'media_type' => $file['media_type'], |
| 1100 | 'duration' => $duration, |
| 1101 | 'preload' => $preload, |
| 1102 | 'volume' => $volume, |
| 1103 | ) |
| 1104 | ), |
| 1105 | $id, |
| 1106 | $index, |
| 1107 | $audio_url |
| 1108 | ); |
| 1109 | $title = esc_html( ( $player_title ) ? apply_filters( 'wcmp_file_name', $file['name'], $id, $index ) : '' ); |
| 1110 | |
| 1111 | print $before; // phpcs:ignore WordPress.Security.EscapeOutput |
| 1112 | $before = ''; |
| 1113 | $after = '</table>'; |
| 1114 | if ( 'all' != $player_controls ) { |
| 1115 | print '<tr class="' . esc_attr( $evenOdd ) . ' product-' . esc_attr( $file['product'] ) . '"><td class="wcmp-player-container wcmp-column-player-' . esc_attr( $player_style ) . '">' . $audio_tag . '</td><td class="wcmp-player-title wcmp-column-player-title">' . wp_kses_post( $title ) . '</td></tr>'; // phpcs:ignore WordPress.Security.EscapeOutput |
| 1116 | } else { |
| 1117 | print '<tr class="' . esc_attr( $evenOdd ) . ' product-' . esc_attr( $file['product'] ) . '"><td><div class="wcmp-player-container">' . $audio_tag . '</div><div class="wcmp-player-title wcmp-column-player-title">' . wp_kses_post( $title ) . '</div></td></tr>'; // phpcs:ignore WordPress.Security.EscapeOutput |
| 1118 | } |
| 1119 | } |
| 1120 | print $after; // phpcs:ignore WordPress.Security.EscapeOutput |
| 1121 | } |
| 1122 | do_action( 'wcmp_after_players_product_page', $id ); |
| 1123 | } |
| 1124 | } // End include_all_players |
| 1125 | |
| 1126 | public function player_in_cart( $cart_item, $cart_item_key ) { |
| 1127 | $product = wc_get_product( $cart_item['product_id'] ); |
| 1128 | $this->include_all_players( $product ); |
| 1129 | } // player_in_cart |
| 1130 | |
| 1131 | // Integration with woocommerce-product-table by barn2media |
| 1132 | public function product_table_data_name( $name, $product ) { |
| 1133 | ob_start(); |
| 1134 | $this->include_main_player( $product ); |
| 1135 | $player = ob_get_contents(); |
| 1136 | ob_end_clean(); |
| 1137 | $player = str_replace( '<div ', '<div style="display:inline-block" ', $player ); |
| 1138 | return $player . $name; |
| 1139 | } // product_table_data_name |
| 1140 | |
| 1141 | public function add_data_product( $player, $product_id, $index, $url ) { |
| 1142 | $player = preg_replace( '/<audio\b/i', '<audio controlslist="nodownload" data-product="' . esc_attr( $product_id ) . '" ', $player ); |
| 1143 | return $player; |
| 1144 | } // End add_data_product |
| 1145 | |
| 1146 | public function add_class_attachment( $html, $product, $size, $attr, $placeholder, $image ) { |
| 1147 | $id = $product->get_id(); |
| 1148 | $html = $this->_add_class( $html, $product ); |
| 1149 | return $html; |
| 1150 | } // End add_class_attachment |
| 1151 | |
| 1152 | public function add_class_single_product_image( $html, $post_thumbnail_id ) { |
| 1153 | global $product; |
| 1154 | |
| 1155 | if ( ! empty( $product ) ) { |
| 1156 | $html = $this->_add_class( $html, $product ); |
| 1157 | } |
| 1158 | return $html; |
| 1159 | } // add_class_single_product_image |
| 1160 | |
| 1161 | // ******************** PRIVATE METHODS ************************ |
| 1162 | |
| 1163 | private function _init_force_in_title() { |
| 1164 | $this->_force_hook_title = $this->get_global_attr( '_wcmp_main_player_hook_title', 1 ); |
| 1165 | |
| 1166 | // Integration with "WOOF – Products Filter for WooCommerce" by realmag777 |
| 1167 | if ( isset( $_REQUEST['action'] ) && 'woof_draw_products' == $_REQUEST['action'] ) { |
| 1168 | $this->_force_hook_title = 1; |
| 1169 | } |
| 1170 | |
| 1171 | } // End _init_force_in_title |
| 1172 | |
| 1173 | private function _get_post_types( $mysql_in = false ) { |
| 1174 | $post_types = array( 'product' ); |
| 1175 | if ( ! empty( $GLOBALS['wcmp_post_types'] ) && is_array( $GLOBALS['wcmp_post_types'] ) ) { |
| 1176 | $post_types = $GLOBALS['wcmp_post_types']; |
| 1177 | } |
| 1178 | if ( $mysql_in ) { |
| 1179 | return '"' . implode( '","', $post_types ) . '"'; |
| 1180 | } |
| 1181 | return $post_types; |
| 1182 | } // End _get_post_types |
| 1183 | |
| 1184 | private function _load_addons() { |
| 1185 | $path = __DIR__ . '/addons'; |
| 1186 | $wcmp = $this; |
| 1187 | |
| 1188 | if ( file_exists( $path ) ) { |
| 1189 | $addons = dir( $path ); |
| 1190 | while ( false !== ( $entry = $addons->read() ) ) { |
| 1191 | if ( strlen( $entry ) > 3 && strtolower( pathinfo( $entry, PATHINFO_EXTENSION ) ) == 'php' ) { |
| 1192 | include_once $addons->path . '/' . $entry; |
| 1193 | } |
| 1194 | } |
| 1195 | } |
| 1196 | } // End _load_addons |
| 1197 | |
| 1198 | private function _preview() { |
| 1199 | $user = wp_get_current_user(); |
| 1200 | $allowed_roles = array( 'editor', 'administrator', 'author' ); |
| 1201 | |
| 1202 | if ( array_intersect( $allowed_roles, $user->roles ) ) { |
| 1203 | if ( ! empty( $_REQUEST['wcmp-preview'] ) ) { |
| 1204 | // Sanitizing variable |
| 1205 | $preview = sanitize_text_field( wp_unslash( $_REQUEST['wcmp-preview'] ) ); |
| 1206 | |
| 1207 | // Remove every shortcode that is not in the plugin |
| 1208 | remove_all_shortcodes(); |
| 1209 | add_shortcode( 'wcmp-playlist', array( &$this, 'replace_playlist_shortcode' ) ); |
| 1210 | |
| 1211 | if ( has_shortcode( $preview, 'wcmp-playlist' ) ) { |
| 1212 | print '<!DOCTYPE html>'; |
| 1213 | $if_empty = __( 'There are no products that satisfy the block\'s settings', 'music-player-for-woocommerce' ); |
| 1214 | wp_enqueue_script( 'jquery' ); |
| 1215 | $output = do_shortcode( $preview ); |
| 1216 | if ( preg_match( '/^\s*$/', $output ) ) { |
| 1217 | $output = '<div>' . $if_empty . '</div>'; |
| 1218 | } |
| 1219 | |
| 1220 | // Deregister all scripts and styles for loading only the plugin styles. |
| 1221 | global $wp_styles, $wp_scripts; |
| 1222 | if ( ! empty( $wp_scripts ) ) { |
| 1223 | $wp_scripts->reset(); |
| 1224 | } |
| 1225 | $this->enqueue_resources(); |
| 1226 | if ( ! empty( $wp_styles ) ) { |
| 1227 | $wp_styles->do_items(); |
| 1228 | } |
| 1229 | if ( ! empty( $wp_scripts ) ) { |
| 1230 | $wp_scripts->do_items(); |
| 1231 | } |
| 1232 | |
| 1233 | print '<div class="wcmp-preview-container">' . $output . '</div>'; // phpcs:ignore WordPress.Security.EscapeOutput |
| 1234 | print '<script type="text/javascript">jQuery(window).on("load", function(){ var frameEl = window.frameElement; if(frameEl) frameEl.height = jQuery(".wcmp-preview-container").outerHeight(true)+25; });</script>'; |
| 1235 | exit; |
| 1236 | } |
| 1237 | } |
| 1238 | } |
| 1239 | } // End _preview |
| 1240 | |
| 1241 | private function _createDir() { |
| 1242 | // Generate upload dir |
| 1243 | $_files_directory = wp_upload_dir(); |
| 1244 | $this->_files_directory_path = rtrim( $_files_directory['basedir'], '/' ) . '/wcmp/'; |
| 1245 | $this->_files_directory_url = rtrim( $_files_directory['baseurl'], '/' ) . '/wcmp/'; |
| 1246 | $this->_files_directory_url = preg_replace( '/^http(s)?:\/\//', '//', $this->_files_directory_url ); |
| 1247 | if ( ! file_exists( $this->_files_directory_path ) ) { |
| 1248 | @mkdir( $this->_files_directory_path, 0755 ); |
| 1249 | } |
| 1250 | } // End _createDir |
| 1251 | |
| 1252 | private function _deleteDir( $dirPath ) { |
| 1253 | try { |
| 1254 | if ( ! is_dir( $dirPath ) ) { |
| 1255 | return; |
| 1256 | } |
| 1257 | if ( substr( $dirPath, strlen( $dirPath ) - 1, 1 ) != '/' ) { |
| 1258 | $dirPath .= '/'; |
| 1259 | } |
| 1260 | $files = glob( $dirPath . '*', GLOB_MARK ); |
| 1261 | foreach ( $files as $file ) { |
| 1262 | if ( is_dir( $file ) ) { |
| 1263 | $this->_deleteDir( $file ); |
| 1264 | } else { |
| 1265 | unlink( $file ); |
| 1266 | } |
| 1267 | } |
| 1268 | rmdir( $dirPath ); |
| 1269 | } catch ( Exception $err ) { |
| 1270 | return; |
| 1271 | } |
| 1272 | } // End _deleteDir |
| 1273 | |
| 1274 | private function _get_duration_by_url( $url ) { |
| 1275 | global $wpdb; |
| 1276 | try { |
| 1277 | $attachment = $wpdb->get_col( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE guid RLIKE %s;", $url ) ); |
| 1278 | if ( empty( $attachment ) ) { |
| 1279 | $uploads_dir = wp_upload_dir(); |
| 1280 | $uploads_url = $uploads_dir['baseurl']; |
| 1281 | $parsed_url = explode( parse_url( $uploads_url, PHP_URL_PATH ), $url ); |
| 1282 | $this_host = str_ireplace( 'www.', '', parse_url( home_url(), PHP_URL_HOST ) ); |
| 1283 | $file_host = str_ireplace( 'www.', '', parse_url( $url, PHP_URL_HOST ) ); |
| 1284 | if ( ! isset( $parsed_url[1] ) || empty( $parsed_url[1] ) || ( $this_host != $file_host ) ) { |
| 1285 | return false; |
| 1286 | } |
| 1287 | $file = trim( $parsed_url[1], '/' ); |
| 1288 | $attachment = $wpdb->get_col( $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key='_wp_attached_file' AND meta_value RLIKE %s;", $file ) ); |
| 1289 | } |
| 1290 | if ( ! empty( $attachment ) ) { |
| 1291 | $metadata = wp_get_attachment_metadata( $attachment[0] ); |
| 1292 | if ( false !== $metadata && ! empty( $metadata['length_formatted'] ) ) { |
| 1293 | return $metadata['length_formatted']; |
| 1294 | } |
| 1295 | } |
| 1296 | } catch ( Exception $err ) { |
| 1297 | error_log( $err->getMessage() ); |
| 1298 | } |
| 1299 | return false; |
| 1300 | } // End _get_duration_by_url |
| 1301 | |
| 1302 | private function _generate_audio_url( $product_id, $file_index, $file_data = array() ) { |
| 1303 | if ( ! empty( $file_data['file'] ) ) { |
| 1304 | $file_url = $file_data['file']; |
| 1305 | if ( ! empty( $file_data['play_src'] ) || $this->_is_playlist( $file_url ) ) { |
| 1306 | return $file_url; // Play src audio file, without copying or truncate it. |
| 1307 | } |
| 1308 | |
| 1309 | // If the playback of music are tracked with Google Analytics, should not be loaded directly the audio files. |
| 1310 | $_wcmp_analytics_property = trim( $this->get_global_attr( '_wcmp_analytics_property', '' ) ); |
| 1311 | if ( '' == $_wcmp_analytics_property ) { |
| 1312 | $file_name = $this->_demo_file_name( $file_url ); |
| 1313 | |
| 1314 | $file_path = $this->_files_directory_path . $file_name; |
| 1315 | |
| 1316 | if ( $this->_valid_demo( $file_path ) ) { |
| 1317 | return 'http' . ( ( is_ssl() ) ? 's:' : ':' ) . $this->_files_directory_url . $file_name; |
| 1318 | } |
| 1319 | } |
| 1320 | } |
| 1321 | $url = isset( $_SERVER['REQUEST_URI'] ) ? esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : ''; |
| 1322 | $url .= ( ( strpos( $url, '?' ) === false ) ? '?' : '&' ) . 'wcmp-action=play&wcmp-product=' . $product_id . '&wcmp-file=' . $file_index; |
| 1323 | return $url; |
| 1324 | } // End _generate_audio_url |
| 1325 | |
| 1326 | private function _delete_truncated_files( $product_id ) { |
| 1327 | $files_arr = get_post_meta( $product_id, '_downloadable_files', true ); |
| 1328 | if ( ! empty( $files_arr ) && is_array( $files_arr ) ) { |
| 1329 | foreach ( $files_arr as $file ) { |
| 1330 | if ( is_array( $file ) && ! empty( $file['file'] ) ) { |
| 1331 | $ext = pathinfo( $file['file'], PATHINFO_EXTENSION ); |
| 1332 | $file_name = md5( $file['file'] ) . ( ( ! empty( $ext ) ) ? '.' . $ext : '' ); |
| 1333 | if ( file_exists( $this->_files_directory_path . $file_name ) ) { |
| 1334 | @unlink( $this->_files_directory_path . $file_name ); |
| 1335 | } |
| 1336 | } |
| 1337 | } |
| 1338 | } |
| 1339 | |
| 1340 | } // End _delete_truncated_files |
| 1341 | |
| 1342 | /** |
| 1343 | * Check if the file is an m3u or m3u8 playlist |
| 1344 | */ |
| 1345 | private function _is_playlist( $file_path ) { |
| 1346 | return preg_match( '/\.(m3u|m3u8)$/i', $file_path ); |
| 1347 | } // End _is_playlist |
| 1348 | |
| 1349 | /** |
| 1350 | * Check if the file is an audio file and return its type or false |
| 1351 | */ |
| 1352 | private function _is_audio( $file_path ) { |
| 1353 | if ( preg_match( '/\.(mp3|ogg|oga|wav|wma|mp4)$/i', $file_path, $match ) ) { |
| 1354 | return $match[1]; |
| 1355 | } |
| 1356 | if ( preg_match( '/\.m4a$/i', $file_path ) ) { |
| 1357 | return 'mp4'; |
| 1358 | } |
| 1359 | if ( $this->_is_playlist( $file_path ) ) { |
| 1360 | return 'hls'; |
| 1361 | } |
| 1362 | |
| 1363 | // From troubleshoot |
| 1364 | $extension = pathinfo( $file_path, PATHINFO_EXTENSION ); |
| 1365 | $troubleshoot_default_extension = $GLOBALS['WooCommerceMusicPlayer']->get_global_attr( '_wcmp_default_extension', false ); |
| 1366 | if ( ( empty( $extension ) || ! preg_match( '/^[a-z\d]{3,4}$/i', $extension ) ) && $troubleshoot_default_extension ) { |
| 1367 | return 'mp3'; |
| 1368 | } |
| 1369 | |
| 1370 | return false; |
| 1371 | } // End _is_audio |
| 1372 | |
| 1373 | private function _sort_list( $product_a, $product_b ) { |
| 1374 | if ( |
| 1375 | ! is_object( $product_a ) || ! method_exists( $product_a, 'get_menu_order' ) || |
| 1376 | ! is_object( $product_b ) || ! method_exists( $product_b, 'get_menu_order' ) |
| 1377 | ) { |
| 1378 | return 0; |
| 1379 | } |
| 1380 | |
| 1381 | $menu_order_a = $product_a->get_menu_order(); |
| 1382 | $menu_order_b = $product_b->get_menu_order(); |
| 1383 | if ( $menu_order_a == $menu_order_b ) { |
| 1384 | if ( |
| 1385 | ! method_exists( $product_a, 'get_name' ) || |
| 1386 | ! method_exists( $product_b, 'get_name' ) |
| 1387 | ) { |
| 1388 | return 0; |
| 1389 | } |
| 1390 | |
| 1391 | $name_a = $product_a->get_name(); |
| 1392 | $name_b = $product_b->get_name(); |
| 1393 | if ( $name_a == $name_b ) { |
| 1394 | return 0; |
| 1395 | } |
| 1396 | return ( $name_a < $name_b ) ? -1 : 1; |
| 1397 | } |
| 1398 | return ( $menu_order_a < $menu_order_b ) ? -1 : 1; |
| 1399 | } // End _sort_list |
| 1400 | |
| 1401 | private function _edit_files_array( $product_id, $files, $play_src = 0 ) { |
| 1402 | $p_files = array(); |
| 1403 | foreach ( $files as $key => $file ) { |
| 1404 | $p_key = $key . '_' . $product_id; |
| 1405 | if ( gettype( $file ) == 'object' ) { |
| 1406 | $file = (array) $file->get_data(); |
| 1407 | } |
| 1408 | $file['product'] = $product_id; |
| 1409 | $file['play_src'] = $play_src; |
| 1410 | $p_files[ $p_key ] = $file; |
| 1411 | } |
| 1412 | return $p_files; |
| 1413 | } // end _edit_files_array |
| 1414 | |
| 1415 | private function _get_recursive_product_files( $product, $files_arr ) { |
| 1416 | if ( ! is_object( $product ) || ! method_exists( $product, 'get_type' ) ) { |
| 1417 | return $files_arr; |
| 1418 | } |
| 1419 | |
| 1420 | $product_type = $product->get_type(); |
| 1421 | $id = $product->get_id(); |
| 1422 | |
| 1423 | if ( 'variation' == $product_type ) { |
| 1424 | // $_files = $product->get_files(); |
| 1425 | $_files = $product->get_downloads(); |
| 1426 | $_files = $this->_edit_files_array( $id, $_files ); |
| 1427 | $files_arr = array_merge( $files_arr, $_files ); |
| 1428 | } else { |
| 1429 | |
| 1430 | if ( ! $this->get_product_attr( $id, '_wcmp_enable_player', false ) ) { |
| 1431 | return $files_arr; |
| 1432 | } |
| 1433 | |
| 1434 | switch ( $product_type ) { |
| 1435 | case 'variable': |
| 1436 | case 'grouped': |
| 1437 | $children = $product->get_children(); |
| 1438 | |
| 1439 | foreach ( $children as $key => $child_id ) { |
| 1440 | $children[ $key ] = wc_get_product( $child_id ); |
| 1441 | } |
| 1442 | |
| 1443 | uasort( $children, array( &$this, '_sort_list' ) ); |
| 1444 | |
| 1445 | foreach ( $children as $child_obj ) { |
| 1446 | $files_arr = $this->_get_recursive_product_files( $child_obj, $files_arr ); |
| 1447 | } |
| 1448 | break; |
| 1449 | default: |
| 1450 | $_files = $product->get_downloads(); |
| 1451 | $_files = $this->_edit_files_array( $id, $_files ); |
| 1452 | $files_arr = array_merge( $files_arr, $_files ); |
| 1453 | break; |
| 1454 | } |
| 1455 | } |
| 1456 | return $files_arr; |
| 1457 | } // End _get_recursive_product_files |
| 1458 | |
| 1459 | private function _get_product_files( $args ) { |
| 1460 | if ( empty( $args['product'] ) ) { |
| 1461 | return false; |
| 1462 | } |
| 1463 | |
| 1464 | $product = $args['product']; |
| 1465 | $files = $this->_get_recursive_product_files( $product, array() ); |
| 1466 | |
| 1467 | if ( empty( $files ) ) { |
| 1468 | return false; |
| 1469 | } |
| 1470 | |
| 1471 | $audio_files = array(); |
| 1472 | foreach ( $files as $index => $file ) { |
| 1473 | if ( ! empty( $file['file'] ) && false !== ( $media_type = $this->_is_audio( $file['file'] ) ) ) { // phpcs:ignore Squiz.PHP.DisallowMultipleAssignments |
| 1474 | $file['media_type'] = $media_type; |
| 1475 | |
| 1476 | if ( ! empty( $args['file_id'] ) ) { |
| 1477 | if ( $args['file_id'] == $index ) { |
| 1478 | $audio_files[ $index ] = $file; |
| 1479 | return $audio_files; |
| 1480 | } |
| 1481 | } elseif ( ! empty( $args['first'] ) ) { |
| 1482 | $audio_files[ $index ] = $file; |
| 1483 | return $audio_files; |
| 1484 | } elseif ( ! empty( $args['all'] ) ) { |
| 1485 | $audio_files[ $index ] = $file; |
| 1486 | } |
| 1487 | } |
| 1488 | } |
| 1489 | |
| 1490 | return $audio_files; |
| 1491 | } // End _get_product_files |
| 1492 | |
| 1493 | private function _demo_file_name( $url ) { |
| 1494 | $file_extension = pathinfo( $url, PATHINFO_EXTENSION ); |
| 1495 | $file_name = md5( $url ) . ( ( ! empty( $file_extension ) && preg_match( '/^[a-z\d]{3,4}$/i', $file_extension ) ) ? '.' . $file_extension : '.mp3' ); |
| 1496 | return $file_name; |
| 1497 | } // End _demo_file_name |
| 1498 | |
| 1499 | private function _valid_demo( $file_path ) { |
| 1500 | if ( ! file_exists( $file_path ) || filesize( $file_path ) == 0 ) { |
| 1501 | return false; |
| 1502 | } |
| 1503 | if ( function_exists( 'finfo_open' ) ) { |
| 1504 | $finfo = finfo_open( FILEINFO_MIME ); |
| 1505 | return substr( finfo_file( $finfo, $file_path ), 0, 4 ) !== 'text'; |
| 1506 | } |
| 1507 | return true; |
| 1508 | } // End _valid_demo |
| 1509 | |
| 1510 | /** |
| 1511 | * Create a temporal file and redirect to the new file |
| 1512 | */ |
| 1513 | private function _output_file( $args ) { |
| 1514 | if ( empty( $args['url'] ) ) { |
| 1515 | return; |
| 1516 | } |
| 1517 | $url = $args['url']; |
| 1518 | $url = do_shortcode( $url ); |
| 1519 | |
| 1520 | if ( file_exists( $url ) ) { |
| 1521 | $url_fixed = $url; |
| 1522 | } elseif ( strpos( $url, '//' ) === 0 ) { |
| 1523 | $url_fixed = 'http' . ( is_ssl() ? 's:' : ':' ) . $url; |
| 1524 | } elseif ( strpos( $url, '/' ) === 0 ) { |
| 1525 | $url_fixed = rtrim( WCMP_WEBSITE_URL, '/' ) . $url; |
| 1526 | } else { |
| 1527 | $url_fixed = $url; |
| 1528 | } |
| 1529 | |
| 1530 | $file_name = $this->_demo_file_name( $url ); |
| 1531 | $text = 'The requested URL was not found on this server'; |
| 1532 | $file_path = $this->_files_directory_path . $file_name; |
| 1533 | |
| 1534 | if ( $this->_valid_demo( $file_path ) ) { |
| 1535 | header( 'location: http' . ( ( is_ssl() ) ? 's:' : ':' ) . $this->_files_directory_url . $file_name ); |
| 1536 | exit; |
| 1537 | } else { |
| 1538 | try { |
| 1539 | $c = false; |
| 1540 | if ( ( $path = $this->_is_local( $url_fixed ) ) !== false ) { // phpcs:ignore Squiz.PHP.DisallowMultipleAssignments |
| 1541 | $c = copy( $path, $file_path ); |
| 1542 | } else { |
| 1543 | $response = wp_remote_get( |
| 1544 | $url_fixed, |
| 1545 | array( |
| 1546 | 'timeout' => WCMP_REMOTE_TIMEOUT, |
| 1547 | 'stream' => true, |
| 1548 | 'filename' => $file_path, |
| 1549 | ) |
| 1550 | ); |
| 1551 | if ( ! is_wp_error( $response ) && 200 == $response['response']['code'] ) { |
| 1552 | $c = true; |
| 1553 | } |
| 1554 | } |
| 1555 | |
| 1556 | if ( true === $c ) { |
| 1557 | header( 'Content-Type: audio/mpeg' ); |
| 1558 | readfile($file_path); |
| 1559 | // header( 'location: http' . ( ( is_ssl() ) ? 's:' : ':' ) . $this->_files_directory_url . $file_name ); |
| 1560 | exit; |
| 1561 | } |
| 1562 | } catch ( Exception $err ) { |
| 1563 | error_log( $err->getMessage() ); |
| 1564 | } |
| 1565 | $text = 'It is not possible to generate the file for demo. Possible causes are: - the amount of memory allocated to the php script on the web server is not enough, - the execution time is too short, - or the "uploads/wcmp" directory does not have write permissions.'; |
| 1566 | } |
| 1567 | $this->_print_page_not_found( $text ); |
| 1568 | } // End _output_file |
| 1569 | |
| 1570 | /** |
| 1571 | * Add the class name: product-<product id> to cover images associated to the products. |
| 1572 | * |
| 1573 | * @param $html, a html piece of code that includes the <img> tag. |
| 1574 | * @param $product, the product object. |
| 1575 | */ |
| 1576 | private function _add_class( $html, $product ) { |
| 1577 | if ( preg_match( '/<img\b[^>]*>/i', $html, $image ) ) { |
| 1578 | $id = $product->get_id(); |
| 1579 | if ( $GLOBALS['WooCommerceMusicPlayer']->get_product_attr( $id, '_wcmp_on_cover', 0 ) ) { |
| 1580 | if ( preg_match( '/\bclass\s*=/i', $image[0] ) ) { |
| 1581 | $tmp_image = preg_replace( '/\bclass\s*=\s*[\'"]/i', "$0product-$id ", $image[0] ); |
| 1582 | } else { |
| 1583 | $tmp_image = preg_replace( '/<img\b/i', "<img $0 class=\"product-$id\" ", $image[0] ); |
| 1584 | } |
| 1585 | |
| 1586 | $html = str_replace( $image[0], $tmp_image, $html ); |
| 1587 | } |
| 1588 | } |
| 1589 | |
| 1590 | return $html; |
| 1591 | } // End _add_class |
| 1592 | |
| 1593 | /** |
| 1594 | * Print not found page if file it is not accessible |
| 1595 | */ |
| 1596 | private function _print_page_not_found( $text = 'The requested URL was not found on this server' ) { |
| 1597 | header( 'Status: 404 Not Found' ); |
| 1598 | echo '<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> |
| 1599 | <HTML><HEAD> |
| 1600 | <TITLE>404 Not Found</TITLE> |
| 1601 | </HEAD><BODY> |
| 1602 | <H1>Not Found</H1> |
| 1603 | <P>' . esc_html( $text ) . '</P> |
| 1604 | </BODY></HTML> |
| 1605 | '; |
| 1606 | } // End _print_page_not_found |
| 1607 | |
| 1608 | private function _is_local( $url ) { |
| 1609 | $file_path = false; |
| 1610 | if ( file_exists( $url ) ) { |
| 1611 | $file_path = $url; |
| 1612 | } else { |
| 1613 | $attachment_id = attachment_url_to_postid( $url ); |
| 1614 | if ( $attachment_id ) { |
| 1615 | $attachment_path = get_attached_file( $attachment_id ); |
| 1616 | if ( $attachment_path && file_exists( $attachment_path ) ) { |
| 1617 | $file_path = $attachment_path; |
| 1618 | } |
| 1619 | } |
| 1620 | } |
| 1621 | return apply_filters( 'wcmp_is_local', $file_path, $url ); |
| 1622 | } // End _is_local |
| 1623 | |
| 1624 | private function _tracking_play_event( $product_id, $file_url ) { |
| 1625 | $_wcmp_analytics_integration = $this->get_global_attr( '_wcmp_analytics_integration', 'ua' ); |
| 1626 | $_wcmp_analytics_property = trim( $this->get_global_attr( '_wcmp_analytics_property', '' ) ); |
| 1627 | $_wcmp_analytics_api_secret = trim( $this->get_global_attr( '_wcmp_analytics_api_secret', '' ) ); |
| 1628 | if ( ! empty( $_wcmp_analytics_property ) ) { |
| 1629 | $cid = isset( $_SERVER['REMOTE_ADDR'] ) ? sanitize_text_field( wp_unslash( $_SERVER['REMOTE_ADDR'] ) ) : 555; |
| 1630 | try { |
| 1631 | if ( isset( $_COOKIE['_ga'] ) ) { |
| 1632 | $cid_parts = explode( '.', sanitize_text_field( wp_unslash( $_COOKIE['_ga'] ) ), 3 ); |
| 1633 | $cid = $cid_parts[2]; |
| 1634 | } |
| 1635 | } catch ( Exception $err ) { |
| 1636 | error_log( $err->getMessage() ); |
| 1637 | } |
| 1638 | |
| 1639 | if ( 'ua' == $_wcmp_analytics_integration ) { |
| 1640 | $_response = wp_remote_post( |
| 1641 | 'http://www.google-analytics.com/collect', |
| 1642 | array( |
| 1643 | 'body' => array( |
| 1644 | 'v' => 1, |
| 1645 | 'tid' => $_wcmp_analytics_property, |
| 1646 | 'cid' => $cid, |
| 1647 | 't' => 'event', |
| 1648 | 'ec' => 'Music Player for WooCommerce', |
| 1649 | 'ea' => 'play', |
| 1650 | 'el' => $file_url, |
| 1651 | 'ev' => $product_id, |
| 1652 | ), |
| 1653 | ) |
| 1654 | ); |
| 1655 | } else { |
| 1656 | $_response = wp_remote_post( |
| 1657 | 'https://www.google-analytics.com/mp/collect?api_secret=' . $_wcmp_analytics_api_secret . '&measurement_id=' . $_wcmp_analytics_property, |
| 1658 | array( |
| 1659 | 'sslverify' => true, |
| 1660 | 'headers' => array( |
| 1661 | 'Content-Type' => 'application/json', |
| 1662 | ), |
| 1663 | 'body' => json_encode( |
| 1664 | array( |
| 1665 | 'client_id' => $cid, |
| 1666 | 'events' => array( |
| 1667 | array( |
| 1668 | 'name' => 'play', |
| 1669 | 'params' => array( |
| 1670 | 'event_category' => 'Music Player for WooCommerce', |
| 1671 | 'event_label' => $file_url, |
| 1672 | 'event_value' => $product_id, |
| 1673 | ), |
| 1674 | ), |
| 1675 | ), |
| 1676 | ) |
| 1677 | ), |
| 1678 | ) |
| 1679 | ); |
| 1680 | } |
| 1681 | |
| 1682 | if ( is_wp_error( $_response ) ) { |
| 1683 | error_log( $_response->get_error_message() ); |
| 1684 | } |
| 1685 | } |
| 1686 | } // _tracking_play_event |
| 1687 | |
| 1688 | public static function troubleshoot( $option ) { |
| 1689 | if ( ! is_admin() ) { |
| 1690 | // Solves a conflict caused by the "Speed Booster Pack" plugin |
| 1691 | if ( is_array( $option ) && isset( $option['jquery_to_footer'] ) ) { |
| 1692 | unset( $option['jquery_to_footer'] ); |
| 1693 | } |
| 1694 | } |
| 1695 | return $option; |
| 1696 | } // End troubleshoot |
| 1697 | } // End Class WooCommerceMusicPlayer |
| 1698 | |
| 1699 | $GLOBALS['WooCommerceMusicPlayer'] = new WooCommerceMusicPlayer(); |
| 1700 | } |
| 1701 |