PluginProbe ʕ •ᴥ•ʔ
Music Player for WooCommerce / 1.6.2
Music Player for WooCommerce v1.6.2
1.8.3 1.8.2 1.8.1 1.1.10 1.1.11 1.1.2 1.1.3 1.1.4 1.1.5 1.1.6 1.1.7 1.1.8 1.1.9 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 1.3.0 1.3.1 1.3.10 1.3.11 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 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.7.4 1.7.5 1.7.6 1.7.7 1.7.8 1.7.9 1.8.0 trunk 1.0.173 1.0.174 1.0.175 1.0.176 1.0.177 1.0.178 1.0.179 1.0.180 1.0.181 1.0.182 1.0.183 1.0.184 1.0.185 1.0.186 1.0.187 1.0.188 1.0.189 1.0.190 1.0.191 1.0.192 1.0.193 1.0.194 1.0.195 1.0.196 1.0.197 1.1.0 1.1.1
music-player-for-woocommerce / wcmp.php
music-player-for-woocommerce Last commit date
addons 1 year ago css 1 year ago feedback 1 year ago inc 1 year ago js 1 year ago languages 1 year ago pagebuilders 1 year ago vendors 1 year ago views 1 year ago widgets 1 year ago banner.php 1 year ago readme.txt 1 year ago wcmp.php 1 year ago
wcmp.php
2146 lines
1 <?php
2 /*
3 Plugin Name: Music Player for WooCommerce
4 Plugin URI: https://wcmp.dwbooster.com
5 Version: 1.6.2
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 add_action( 'init', function(){
21 add_filter( 'get_post_metadata', function( $v, $object_id, $meta_key, $single, $meta_type = '' ){
22 if ( '_elementor_element_cache' == $meta_key ) {
23 global $wpdb;
24 if ( $wpdb->get_var( $wpdb->prepare('SELECT COUNT(*) FROM ' . $wpdb->postmeta . ' WHERE post_id=%d AND meta_key="_elementor_element_cache" AND meta_value LIKE "%wcmp%";', $object_id ) ) ) return false;
25 }
26 return $v;
27 }, 10, 5 );
28 } );
29
30 // Feedback system
31 require_once 'feedback/cp-feedback.php';
32 new WCMP_FEEDBACK( 'music-player-for-woocommerce', __FILE__, 'https://wcmp.dwbooster.com/contact-us' );
33
34 // CONSTANTS
35
36 define( 'WCMP_WEBSITE_URL', get_home_url( get_current_blog_id(), '', is_ssl() ? 'https' : 'http' ) );
37 define( 'WCMP_PLUGIN_URL', plugins_url( '', __FILE__ ) );
38 define( 'WCMP_DEFAULT_PLAYER_LAYOUT', 'mejs-classic' );
39 define( 'WCMP_DEFAULT_SINGLE_PLAYER', 0 );
40 define( 'WCMP_DEFAULT_PLAYER_VOLUME', 1 );
41 define( 'WCMP_DEFAULT_PLAYER_CONTROLS', 'default' );
42 define( 'WCMP_DEFAULT_PlAYER_TITLE', 1 );
43 define( 'WCMP_REMOTE_TIMEOUT', 120 );
44 define( 'WCMP_VERSION', '1.6.2' );
45
46 // Load Tools
47 require_once 'inc/tools.inc.php';
48
49 // Load widgets
50 require_once 'widgets/playlist_widget.php';
51
52 add_filter( 'option_sbp_settings', array( 'WooCommerceMusicPlayer', 'troubleshoot' ) );
53 if ( ! class_exists( 'WooCommerceMusicPlayer' ) ) {
54 class WooCommerceMusicPlayer {
55
56 // ******************** ATTRIBUTES ************************
57
58 private $_products_attrs = array();
59 private $_global_attrs = array();
60 private $_player_layouts = array( 'mejs-classic', 'mejs-ted', 'mejs-wmp' );
61 private $_player_controls = array( 'button', 'all', 'default' );
62 private $_files_directory_path;
63 private $_files_directory_url;
64 private $_enqueued_resources = false;
65 private $_inserted_player = false;
66 private $_insert_player = true;
67
68 private $_insert_main_player = true;
69 private $_insert_all_players = true;
70
71 private $_force_hook_title = 0;
72
73 private $_current_user_downloads = array();
74
75 private $_preload_times = 0; // Multiple preloads with demo generators can affect the server performance
76
77 private $_hooks = array();
78
79 /**
80 * WCMP constructor
81 *
82 * @access public
83 * @return void
84 */
85 public function __construct() {
86
87 // Initialize $_hooks list
88 $this->_hooks = array(
89 'main_player' => array(),
90 'all_players' => array(
91 // 'woocommerce_before_single_product_summary' => 1,
92 'woocommerce_single_product_summary' => 1,
93 'woocommerce_after_single_product_summary' => 1,
94 'woocommerce_before_add_to_cart_form' => 1,
95 'woocommerce_after_add_to_cart_form' => 1,
96 )
97 );
98
99 $this->_createDir();
100 register_activation_hook( __FILE__, array( &$this, 'activation' ) );
101 register_deactivation_hook( __FILE__, array( &$this, 'deactivation' ) );
102
103 add_action( 'plugins_loaded', array( &$this, 'plugins_loaded' ) );
104 add_action( 'init', array( &$this, 'init' ) );
105 add_action( 'admin_init', array( &$this, 'admin_init' ), 99 );
106
107 // EXPORT / IMPORT PRODUCTS
108
109 add_filter( 'woocommerce_product_export_meta_value', function( $value, $meta, $product, $row ){
110 if (
111 preg_match( '/^' . preg_quote( '_wcmp_' ) . '/i', $meta->key ) &&
112 ! is_scalar( $value )
113 ) {
114 $value = serialize( $value );
115 }
116 return $value;
117 }, 10, 4 );
118
119 add_filter( 'woocommerce_product_importer_pre_expand_data', function( $data ){
120 foreach ( $data as $_key => $_value ) {
121 if (
122 preg_match( '/^' . preg_quote( 'meta:_wcmp_' ) . '/i', $_key ) &&
123 function_exists( 'is_serialized' ) &&
124 is_serialized( $_value )
125 ) {
126 try {
127 $data[ $_key ] = unserialize( $_value );
128 } catch ( Exception $err ) {
129 $data[ $_key ] = $_value;
130 } catch ( Error $err ) {
131 $data[ $_key ] = $_value;
132 }
133 }
134 }
135 return $data;
136 }, 10 );
137
138 /** WooCommerce Product Table by Barn2 Plugins integration **/
139 add_filter( 'wc_product_table_data_name', function( $title, $product ) {
140 return ( false === stripos( $title, '<audio' ) ? $this->include_main_player( $product, false ) : '' ) . $title;
141 }, 10, 2 );
142
143 add_action( 'wc_product_table_before_get_data', function( $table ) {
144 $GLOBALS['_insert_all_players_BK'] = $this->_insert_all_players;
145 $this->_insert_all_players = false;
146 }, 10 );
147
148 add_action( 'wc_product_table_after_get_data', function( $table ) {
149 if ( isset( $GLOBALS['_insert_all_players_BK'] ) ) {
150 $this->_insert_all_players = $GLOBALS['_insert_all_players_BK'];
151 unset( $GLOBALS['_insert_all_players_BK'] );
152 } else {
153 $this->_insert_all_players = true;
154 }
155 }, 10 );
156
157 add_filter( 'pre_do_shortcode_tag', function( $output, $tag, $attr, $m ){
158 if( strtolower( $tag ) == 'product_table' ) {
159 $this->enqueue_resources();
160 }
161 return $output;
162 }, 10, 4 );
163
164 /** ListeSpeed Cache integration **/
165 add_filter( 'litespeed_optimize_js_excludes', function( $p ){
166 $p[] = 'jquery.js';
167 $p[] = 'jquery.min.js';
168 $p[] = '/mediaelement/';
169 $p[] = plugin_dir_url( __FILE__ ) . 'js/public.js';
170 return $p;
171 } );
172 add_filter( 'litespeed_optm_js_defer_exc', function( $p ){
173 $p[] = 'jquery.js';
174 $p[] = 'jquery.min.js';
175 $p[] = '/mediaelement/';
176 $p[] = plugin_dir_url( __FILE__ ) . 'js/public.js';
177 return $p;
178 } );
179
180 } // End __constructor
181
182 public function activation() {
183 $this->_clearDir( $this->_files_directory_path );
184 $this->_createDir();
185 }
186
187 public function deactivation() {
188 $this->_clearDir( $this->_files_directory_path );
189 }
190
191 public function plugins_loaded() {
192 if ( ! class_exists( 'woocommerce' ) ) {
193 return;
194 }
195
196 add_action( 'init', function() {
197 load_plugin_textdomain( 'music-player-for-woocommerce', false, basename( dirname( __FILE__ ) ) . '/languages/' );
198 });
199
200 add_filter( 'the_title', array( &$this, 'include_main_player_filter' ), 11, 2 );
201 $this->init_force_in_title();
202 $this->_load_addons();
203
204 // Integration with the content editors
205 require_once dirname( __FILE__ ) . '/pagebuilders/builders.php';
206 WCMP_BUILDERS::run();
207 }
208
209 public function get_product_attr( $product_id, $attr, $default = false ) {
210 if ( ! isset( $this->_products_attrs[ $product_id ] ) ) {
211 $this->_products_attrs[ $product_id ] = array();
212 }
213 if ( ! isset( $this->_products_attrs[ $product_id ][ $attr ] ) ) {
214 if ( metadata_exists( 'post', $product_id, $attr ) ) {
215 $this->_products_attrs[ $product_id ][ $attr ] = get_post_meta( $product_id, $attr, true );
216 } else {
217 $this->_products_attrs[ $product_id ][ $attr ] = $this->get_global_attr( $attr, $default );
218 }
219 }
220 return apply_filters( 'wcmp_product_attr', $this->_products_attrs[ $product_id ][ $attr ], $product_id, $attr );
221
222 } // End get_product_attr
223
224 public function get_global_attr( $attr, $default = false ) {
225 if ( empty( $this->_global_attrs ) ) {
226 $this->_global_attrs = get_option( 'wcmp_global_settings', array() );
227 }
228 if ( ! isset( $this->_global_attrs[ $attr ] ) ) {
229 $this->_global_attrs[ $attr ] = $default;
230 }
231 return apply_filters( 'wcmp_global_attr', $this->_global_attrs[ $attr ], $attr );
232
233 } // End get_global_attr
234
235 // ******************** WordPress ACTIONS **************************
236
237 public function init() {
238 // Check if WooCommerce is installed or not
239 if ( ! class_exists( 'woocommerce' ) ) {
240 add_shortcode(
241 'wcmp-playlist',
242 function( $atts ) {
243 return '';
244 }
245 );
246 return; }
247 $_current_user_id = get_current_user_id();
248 if (
249 $this->get_global_attr( '_wcmp_registered_only', 0 ) &&
250 0 == $_current_user_id
251 ) {
252 $this->_insert_player = false;
253 }
254
255 if ( ! is_admin() ) {
256 add_filter( 'wcmp_preload', array( $this, 'preload' ), 10, 2 );
257
258 // Define the shortcode for the playlist_widget
259 add_shortcode( 'wcmp-playlist', array( &$this, 'replace_playlist_shortcode' ) );
260 $this->_preview();
261 if ( isset( $_REQUEST['wcmp-action'] ) && 'play' == $_REQUEST['wcmp-action'] ) {
262 if ( isset( $_REQUEST['wcmp-product'] ) ) {
263 $product_id = @intval( $_REQUEST['wcmp-product'] );
264 if ( ! empty( $product_id ) ) {
265 $product = wc_get_product( $product_id );
266 if ( false !== $product ){
267 $this->update_playback_counter( $product_id );
268 if ( isset( $_REQUEST['wcmp-file'] ) ) {
269 $files = $this->_get_product_files(
270 array(
271 'product' => $product,
272 'file_id' => sanitize_key( $_REQUEST['wcmp-file'] ),
273 )
274 );
275
276 if ( ! empty( $files ) ) {
277 $file_url = $files[ sanitize_key( $_REQUEST['wcmp-file'] ) ]['file'];
278 $this->_tracking_play_event( $product_id, $file_url );
279 $this->_output_file( array( 'url' => $file_url ) );
280 }
281 }
282 }
283 }
284 }
285 exit;
286 } else {
287 // To allow customize the hooks
288 $include_main_player_hook = preg_replace( '/[\t\s]/', '', $this->get_global_attr( '_wcmp_main_player_hook', '' ) );
289 $include_all_players_hook = preg_replace( '/[\t\s]/', '', $this->get_global_attr( '_wcmp_all_players_hook', '' ) );
290
291 if ( empty( $include_main_player_hook ) ) {
292 $include_main_player_hook = 'woocommerce_shop_loop_item_title';
293 }
294
295 if ( empty( $include_all_players_hook ) ) {
296 foreach ( $this->_hooks['all_players'] as $_hook_name => $_hook_data ) {
297 add_action( $_hook_name, array( $this, 'include_players' ), 10, $_hook_data );
298 }
299 } else {
300 $include_all_players_hook = explode( ',', $include_all_players_hook );
301 foreach ( $include_all_players_hook as $_hook_name ) {
302 if ( ! empty( $_hook_name ) ) {
303 add_action( $_hook_name, array( &$this, 'include_all_players' ), 11 );
304 }
305 }
306 }
307
308 if ( 0 == $this->_force_hook_title ) {
309 $include_main_player_hook = explode( ',', $include_main_player_hook );
310 foreach ( $include_main_player_hook as $_hook_name ) {
311 if ( ! empty( $_hook_name ) ) {
312 add_action( $_hook_name, array( &$this, 'include_main_player' ), 11 );
313 }
314 }
315 }
316
317 // Allows to call the players directly by themes
318 add_action( 'wcmp_main_player', array( &$this, 'include_main_player' ), 11 );
319 add_action( 'wcmp_all_players', array( &$this, 'include_all_players' ), 11 );
320
321 // Integration with woocommerce-product-table by barn2media
322 add_filter( 'wc_product_table_data_name', array( &$this, 'product_table_data_name' ), 11, 2 );
323
324 $players_in_cart = $this->get_global_attr( '_wcmp_players_in_cart', false );
325 if ( $players_in_cart ) {
326 add_action( 'woocommerce_after_cart_item_name', array( &$this, 'player_in_cart' ), 11, 2 );
327 }
328
329 // Add product id to audio tag
330 add_filter( 'wcmp_audio_tag', array( &$this, 'add_data_product' ), 99, 4 );
331
332 // Add class name to the feature image of product
333 add_filter( 'woocommerce_product_get_image', array( &$this, 'add_class_attachment' ), 99, 6 );
334 add_filter( 'woocommerce_single_product_image_thumbnail_html', array( &$this, 'add_class_single_product_image' ), 99, 2 );
335
336 // Include players with the titles
337 if (
338 $this->get_global_attr( '_wcmp_force_main_player_in_title', 1 ) &&
339 ! empty( $_SERVER['REQUEST_URI'] )
340 /*
341 ! empty( $_SERVER['REQUEST_URI'] ) &&
342 stripos( esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ), 'wc/store' ) !== false */
343 ) {
344 add_filter( 'woocommerce_product_title', array( &$this, 'woocommerce_product_title' ), 10, 2 );
345
346 add_filter( 'esc_html', array( &$this, 'esc_html' ), 10, 2 );
347 }
348
349 // For accepting the <source> tags
350 add_filter( 'wp_kses_allowed_html', array( &$this, 'allowed_html_tags' ), 10, 2 );
351 }
352 } else {
353 add_action( 'admin_menu', array( &$this, 'menu_links' ), 10 );
354 }
355
356 } // End init
357
358 public function admin_init() {
359 // Check if WooCommerce is installed or not
360 if ( ! class_exists( 'woocommerce' ) ) {
361 return;
362 }
363
364 $this->clear_expired_transients();
365
366 add_meta_box( 'wcmp_woocommerce_metabox', __( 'Music Player for WooCommerce', 'music-player-for-woocommerce' ), array( &$this, 'woocommerce_player_settings' ), $this->_get_post_types(), 'normal' );
367 add_action( 'save_post', array( &$this, 'save_post' ), 10, 3 );
368 add_action( 'after_delete_post', function($post_id, $post_obj) { $this->delete_post($post_id); }, 10, 2 );
369 add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), array( &$this, 'help_link' ) );
370
371 // Products list "Playback Counter"
372
373 $manage_product_posts_columns = function( $columns ) {
374 if ( $this->get_global_attr( '_wcmp_playback_counter_column', 1 ) ) {
375 wp_enqueue_style( 'wcmp-Playback-counter', plugin_dir_url( __FILE__ ) . 'css/style.admin.css', array(), '1.0.175' );
376 $columns = array_merge( $columns, [ 'wcmp_playback_counter' => __( 'Playback Counter', 'music-player-for-woocommerce' ) ] );
377 }
378 return $columns;
379 };
380 add_filter( 'manage_product_posts_columns', $manage_product_posts_columns );
381
382 $manage_product_posts_custom_column = function( $column_key, $product_id ) {
383 if (
384 $this->get_global_attr( '_wcmp_playback_counter_column', 1 ) &&
385 'wcmp_playback_counter' == $column_key
386 ) {
387 $counter = get_post_meta( $product_id, '_wcmp_playback_counter', true);
388 echo '<span class="wcmp-playback-counter">' . esc_html( ! empty( $counter ) ? $counter : '' ) . '</span>';
389 }
390 };
391 add_action( 'manage_product_posts_custom_column', $manage_product_posts_custom_column, 10, 2 );
392 } // End admin_init
393
394 public function help_link( $links ) {
395 array_unshift(
396 $links,
397 '<a href="https://wordpress.org/support/plugin/music-player-for-woocommerce/#new-post" target="_blank">' . __( 'Help' ) . '</a>'
398 );
399 return $links;
400 } // End help_link
401
402 public function menu_links() {
403 add_options_page( 'Music Player for WooCommerce', 'Music Player for WooCommerce', 'manage_options', 'music-player-for-woocommerce-settings', array( &$this, 'settings_page' ) );
404 } // End menu_links
405
406 public function settings_page() {
407 if (
408 isset( $_POST['wcmp_nonce'] ) &&
409 wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['wcmp_nonce'] ) ), 'wcmp_updating_plugin_settings' )
410 ) {
411 $_REQUEST = stripslashes_deep( $_REQUEST );
412 // Save the player settings
413 $registered_only = ( isset( $_REQUEST['_wcmp_registered_only'] ) ) ? 1 : 0;
414 $fade_out = ( isset( $_REQUEST['_wcmp_fade_out'] ) ) ? 1 : 0;
415 $purchased_times_text = sanitize_text_field( isset( $_REQUEST['_wcmp_purchased_times_text'] ) ? wp_unslash( $_REQUEST['_wcmp_purchased_times_text'] ) : '' );
416 $troubleshoot_default_extension = ( isset( $_REQUEST['_wcmp_default_extension'] ) ) ? true : false;
417 $force_main_player_in_title = ( isset( $_REQUEST['_wcmp_force_main_player_in_title'] ) ) ? 1 : 0;
418 $ios_controls = ( isset( $_REQUEST['_wcmp_ios_controls'] ) ) ? true : false;
419 $troubleshoot_onload = ( isset( $_REQUEST['_wcmp_onload'] ) ) ? true : false;
420 $include_main_player_hook = ( isset( $_REQUEST['_wcmp_main_player_hook'] ) ) ? sanitize_text_field( wp_unslash( $_REQUEST['_wcmp_main_player_hook'] ) ) : '';
421 $main_player_hook_title = ( isset( $_REQUEST['_wcmp_main_player_hook_title'] ) ) ? 1 : 0;
422 $disable_302 = ( isset( $_REQUEST['_wcmp_disable_302'] ) ) ? 1 : 0;
423 $include_all_players_hook = ( isset( $_REQUEST['_wcmp_all_players_hook'] ) ) ? sanitize_text_field( wp_unslash( $_REQUEST['_wcmp_all_players_hook'] ) ) : '';
424
425 $enable_player = ( isset( $_REQUEST['_wcmp_enable_player'] ) ) ? 1 : 0;
426 $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';
427 $players_in_cart = ( isset( $_REQUEST['_wcmp_players_in_cart'] ) ) ? true : false;
428 $player_style = (
429 isset( $_REQUEST['_wcmp_player_layout'] ) &&
430 in_array( $_REQUEST['_wcmp_player_layout'], $this->_player_layouts )
431 ) ? sanitize_text_field( wp_unslash( $_REQUEST['_wcmp_player_layout'] ) ) : WCMP_DEFAULT_PLAYER_LAYOUT;
432 $single_player = ( isset( $_REQUEST['_wcmp_single_player'] ) ) ? 1 : 0;
433 $player_controls = (
434 isset( $_REQUEST['_wcmp_player_controls'] ) &&
435 in_array( $_REQUEST['_wcmp_player_controls'], $this->_player_controls )
436 ) ? sanitize_text_field( wp_unslash( $_REQUEST['_wcmp_player_controls'] ) ) : WCMP_DEFAULT_PLAYER_CONTROLS;
437
438 $on_cover = ( ( 'button' == $player_controls || 'default' == $player_controls ) && isset( $_REQUEST['_wcmp_player_on_cover'] ) ) ? 1 : 0;
439
440 $player_title = ( isset( $_REQUEST['_wcmp_player_title'] ) ) ? 1 : 0;
441 $merge_grouped = ( isset( $_REQUEST['_wcmp_merge_in_grouped'] ) ) ? 1 : 0;
442 $play_all = ( isset( $_REQUEST['_wcmp_play_all'] ) ) ? 1 : 0;
443 $loop = ( isset( $_REQUEST['_wcmp_loop'] ) ) ? 1 : 0;
444 $play_simultaneously = ( isset( $_REQUEST['_wcmp_play_simultaneously'] ) ) ? 1 : 0;
445 $volume = ( isset( $_REQUEST['_wcmp_player_volume'] ) && is_numeric( $_REQUEST['_wcmp_player_volume'] ) ) ? floatval( $_REQUEST['_wcmp_player_volume'] ) : 1;
446 $preload = (
447 isset( $_REQUEST['_wcmp_preload'] ) &&
448 in_array( $_REQUEST['_wcmp_preload'], array( 'none', 'metadata', 'auto' ) )
449 ) ? sanitize_text_field( wp_unslash( $_REQUEST['_wcmp_preload'] ) ) : 'none';
450
451 $apply_to_all_players = ( isset( $_REQUEST['_wcmp_apply_to_all_players'] ) ) ? 1 : 0;
452
453 $global_settings = array(
454 '_wcmp_registered_only' => $registered_only,
455 '_wcmp_fade_out' => $fade_out,
456 '_wcmp_purchased_times_text' => $purchased_times_text,
457 '_wcmp_enable_player' => $enable_player,
458 '_wcmp_show_in' => $show_in,
459 '_wcmp_players_in_cart' => $players_in_cart,
460 '_wcmp_player_layout' => $player_style,
461 '_wcmp_player_volume' => $volume,
462 '_wcmp_single_player' => $single_player,
463 '_wcmp_player_controls' => $player_controls,
464 '_wcmp_player_title' => $player_title,
465 '_wcmp_merge_in_grouped' => $merge_grouped,
466 '_wcmp_play_all' => $play_all,
467 '_wcmp_loop' => $loop,
468 '_wcmp_play_simultaneously' => $play_simultaneously,
469 '_wcmp_preload' => $preload,
470 '_wcmp_on_cover' => $on_cover,
471 '_wcmp_default_extension' => $troubleshoot_default_extension,
472 '_wcmp_force_main_player_in_title' => $force_main_player_in_title,
473 '_wcmp_ios_controls' => $ios_controls,
474 '_wcmp_onload' => $troubleshoot_onload,
475 '_wcmp_main_player_hook' => $include_main_player_hook,
476 '_wcmp_main_player_hook_title' => $main_player_hook_title,
477 '_wcmp_disable_302' => $disable_302,
478 '_wcmp_all_players_hook' => $include_all_players_hook,
479 '_wcmp_playback_counter_column' => ( isset( $_REQUEST['_wcmp_playback_counter_column'] ) ) ? sanitize_text_field( wp_unslash( $_REQUEST['_wcmp_playback_counter_column'] ) ) : 0,
480 '_wcmp_analytics_integration' => ( isset( $_REQUEST['_wcmp_analytics_integration'] ) ) ? sanitize_text_field( wp_unslash( $_REQUEST['_wcmp_analytics_integration'] ) ) : 'ua',
481 '_wcmp_analytics_property' => ( isset( $_REQUEST['_wcmp_analytics_property'] ) ) ? sanitize_text_field( wp_unslash( $_REQUEST['_wcmp_analytics_property'] ) ) : '',
482 '_wcmp_analytics_api_secret' => ( isset( $_REQUEST['_wcmp_analytics_api_secret'] ) ) ? sanitize_text_field( wp_unslash( $_REQUEST['_wcmp_analytics_api_secret'] ) ) : '',
483 '_wcmp_apply_to_all_players' => $apply_to_all_players,
484 );
485
486 if ( $apply_to_all_players ) {
487 $this->_clearDir( $this->_files_directory_path );
488
489 $products_ids = array(
490 'post_type' => $this->_get_post_types(),
491 'numberposts' => -1,
492 'post_status' => array( 'publish', 'pending', 'draft', 'future' ),
493 'fields' => 'ids',
494 'cache_results' => false,
495 );
496
497 $products = get_posts( $products_ids );
498 foreach ( $products as $product_id ) {
499 update_post_meta( $product_id, '_wcmp_enable_player', $enable_player );
500 update_post_meta( $product_id, '_wcmp_show_in', $show_in );
501 update_post_meta( $product_id, '_wcmp_player_layout', $player_style );
502 update_post_meta( $product_id, '_wcmp_single_player', $single_player );
503 update_post_meta( $product_id, '_wcmp_player_controls', $player_controls );
504 update_post_meta( $product_id, '_wcmp_player_volume', $volume );
505 update_post_meta( $product_id, '_wcmp_player_title', $player_title );
506 update_post_meta( $product_id, '_wcmp_merge_in_grouped', $merge_grouped );
507 update_post_meta( $product_id, '_wcmp_play_all', $play_all );
508 update_post_meta( $product_id, '_wcmp_loop', $loop );
509 update_post_meta( $product_id, '_wcmp_preload', $preload );
510 update_post_meta( $product_id, '_wcmp_on_cover', $on_cover );
511 }
512 }
513
514 update_option( 'wcmp_global_settings', $global_settings );
515 $this->_global_attrs = $global_settings;
516 do_action( 'wcmp_save_setting' );
517
518 /** Purge Cache **/
519 include_once __DIR__ . '/inc/cache.inc.php';
520 } // Save settings
521
522 print '<div class="wrap">'; // Open Wrap
523 include_once dirname( __FILE__ ) . '/views/global_options.php';
524 print '</div>'; // Close Wrap
525 } // End settings_page
526
527 public function save_post( $post_id, $post, $update ) {
528 if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
529 return;
530 }
531 if ( empty( $_POST['wcmp_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['wcmp_nonce'] ) ), 'wcmp_updating_product' ) ) {
532 return;
533 }
534 $post_types = $this->_get_post_types();
535 if ( ! isset( $post ) || ! in_array( $post->post_type, $post_types ) || ! current_user_can( 'edit_post', $post_id ) ) {
536 return;
537 }
538
539 $this->delete_post( $post_id, true );
540
541 // Save the player options
542 $enable_player = ( isset( $_REQUEST['_wcmp_enable_player'] ) ) ? 1 : 0;
543 $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';
544 $player_style = (
545 isset( $_REQUEST['_wcmp_player_layout'] ) &&
546 in_array( $_REQUEST['_wcmp_player_layout'], $this->_player_layouts )
547 ) ? sanitize_text_field( wp_unslash( $_REQUEST['_wcmp_player_layout'] ) ) : WCMP_DEFAULT_PLAYER_LAYOUT;
548
549 $single_player = ( isset( $_REQUEST['_wcmp_single_player'] ) ) ? 1 : 0;
550 $player_controls = (
551 isset( $_REQUEST['_wcmp_player_controls'] ) &&
552 in_array( $_REQUEST['_wcmp_player_controls'], $this->_player_controls )
553 ) ? sanitize_text_field( wp_unslash( $_REQUEST['_wcmp_player_controls'] ) ) : WCMP_DEFAULT_PLAYER_CONTROLS;
554
555 $player_title = ( isset( $_REQUEST['_wcmp_player_title'] ) ) ? 1 : 0;
556 $merge_grouped = ( isset( $_REQUEST['_wcmp_merge_in_grouped'] ) ) ? 1 : 0;
557 $play_all = ( isset( $_REQUEST['_wcmp_play_all'] ) ) ? 1 : 0;
558 $loop = ( isset( $_REQUEST['_wcmp_loop'] ) ) ? 1 : 0;
559 $volume = ( isset( $_REQUEST['_wcmp_player_volume'] ) && is_numeric( $_REQUEST['_wcmp_player_volume'] ) ) ? floatval( $_REQUEST['_wcmp_player_volume'] ) : 1;
560 $preload = (
561 isset( $_REQUEST['_wcmp_preload'] ) &&
562 in_array( $_REQUEST['_wcmp_preload'], array( 'none', 'metadata', 'auto' ) )
563 ) ? sanitize_text_field( wp_unslash( $_REQUEST['_wcmp_preload'] ) ) : 'none';
564
565 $on_cover = ( ( 'button' == $player_controls || 'default' == $player_controls ) && isset( $_REQUEST['_wcmp_player_on_cover'] ) ) ? 1 : 0;
566
567 add_post_meta( $post_id, '_wcmp_enable_player', $enable_player, true );
568 add_post_meta( $post_id, '_wcmp_show_in', $show_in, true );
569 add_post_meta( $post_id, '_wcmp_player_layout', $player_style, true );
570 add_post_meta( $post_id, '_wcmp_player_volume', $volume, true );
571 add_post_meta( $post_id, '_wcmp_single_player', $single_player, true );
572 add_post_meta( $post_id, '_wcmp_player_controls', $player_controls, true );
573 add_post_meta( $post_id, '_wcmp_player_title', $player_title, true );
574 add_post_meta( $post_id, '_wcmp_merge_in_grouped', $merge_grouped, true );
575 add_post_meta( $post_id, '_wcmp_preload', $preload, true );
576 add_post_meta( $post_id, '_wcmp_play_all', $play_all, true );
577 add_post_meta( $post_id, '_wcmp_loop', $loop, true );
578 add_post_meta( $post_id, '_wcmp_on_cover', $on_cover, true );
579 } // End save_post
580
581 public function delete_post( $post_id, $force = false ) {
582 $post = get_post( $post_id );
583 $post_types = $this->_get_post_types();
584 if (
585 isset( $post) &&
586 (
587 ! $force ||
588 ! in_array( $post->post_type, $post_types ) ||
589 ! current_user_can( 'edit_post', $post_id )
590 )
591 ) {
592 return;
593 }
594
595 // Delete truncated version of the audio file
596 $this->_delete_truncated_files( $post_id );
597
598 delete_post_meta( $post_id, '_wcmp_enable_player' );
599 delete_post_meta( $post_id, '_wcmp_show_in' );
600 delete_post_meta( $post_id, '_wcmp_merge_in_grouped' );
601 delete_post_meta( $post_id, '_wcmp_player_layout' );
602 delete_post_meta( $post_id, '_wcmp_player_volume' );
603 delete_post_meta( $post_id, '_wcmp_single_player' );
604 delete_post_meta( $post_id, '_wcmp_player_controls' );
605 delete_post_meta( $post_id, '_wcmp_player_title' );
606 delete_post_meta( $post_id, '_wcmp_preload' );
607 delete_post_meta( $post_id, '_wcmp_play_all' );
608 delete_post_meta( $post_id, '_wcmp_loop' );
609 delete_post_meta( $post_id, '_wcmp_on_cover' );
610
611 delete_post_meta( $post_id, '_wcmp_playback_counter' );
612 } // End delete_post
613
614 public function esc_html( $safe_text, $text ) {
615 if ( strpos( $safe_text, 'wcmp-player-container' ) !== false ) {
616 return $text;
617 }
618 return $safe_text;
619 } // End esc_html
620
621 public function enqueue_resources() {
622 if ( $this->_enqueued_resources ) {
623 return;
624 }
625 $this->_enqueued_resources = true;
626
627 if ( function_exists( 'wp_add_inline_script' ) ) {
628 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);};' );
629 }
630
631 // Registering resources
632 wp_enqueue_style( 'wp-mediaelement' );
633 wp_enqueue_style( 'wp-mediaelement-skins', plugin_dir_url( __FILE__ ) . 'vendors/mejs-skins/mejs-skins.min.css', array(), WCMP_VERSION );
634 wp_enqueue_style( 'wcmp-style', plugin_dir_url( __FILE__ ) . 'css/style.css', array(), WCMP_VERSION );
635 wp_enqueue_script( 'jquery' );
636 wp_enqueue_script( 'wp-mediaelement' );
637 wp_enqueue_script( 'wcmp-script', plugin_dir_url( __FILE__ ) . 'js/public.js', array( 'jquery', 'wp-mediaelement' ), WCMP_VERSION );
638
639 $play_all = $GLOBALS['WooCommerceMusicPlayer']->get_global_attr(
640 '_wcmp_play_all',
641 // This option is only for compatibility with versions previous to 1.0.28
642 $GLOBALS['WooCommerceMusicPlayer']->get_global_attr( 'play_all', 0 )
643 );
644
645 $play_simultaneously = $GLOBALS['WooCommerceMusicPlayer']->get_global_attr( '_wcmp_play_simultaneously', 0 );
646
647 if ( function_exists( 'is_product' ) && is_product() ) {
648 global $post;
649 $post_types = $this->_get_post_types();
650 if ( ! empty( $post ) && in_array( $post->post_type, $post_types ) ) {
651 $play_all = $GLOBALS['WooCommerceMusicPlayer']->get_product_attr(
652 $post->ID,
653 '_wcmp_play_all',
654 // This option is only for compatibility with versions previous to 1.0.28
655 $GLOBALS['WooCommerceMusicPlayer']->get_product_attr(
656 $post->ID,
657 'play_all',
658 $play_all
659 )
660 );
661 }
662 }
663
664 wp_localize_script(
665 'wcmp-script',
666 'wcmp_global_settings',
667 array(
668 'fade_out' => $GLOBALS['WooCommerceMusicPlayer']->get_global_attr( '_wcmp_fade_out', 1 ),
669 'play_all' => intval( $play_all ),
670 'play_simultaneously' => intval( $play_simultaneously ),
671 'ios_controls' => $GLOBALS['WooCommerceMusicPlayer']->get_global_attr( '_wcmp_ios_controls', false ),
672 'onload' => $GLOBALS['WooCommerceMusicPlayer']->get_global_attr( '_wcmp_onload', false ),
673 )
674 );
675 } // End enqueue_resources
676
677 /**
678 * Replace the shortcode to display a playlist with all songs.
679 */
680 public function replace_playlist_shortcode( $atts ) {
681 if ( ! class_exists( 'woocommerce' ) || is_admin() ) {
682 return '';
683 }
684
685 $get_times = function( $product_id, $products_list ) {
686 if ( ! empty( $products_list ) ) {
687 foreach ( $products_list as $product ) {
688 if ( $product->product_id == $product_id ) {
689 return $product->times;
690 }
691 }
692 }
693 return 0;
694 };
695
696 global $post;
697
698 $output = '';
699 if ( ! $this->_insert_player ) {
700 return $output;
701 }
702
703 if ( ! is_array( $atts ) ) {
704 $atts = array();
705 }
706 $post_types = $this->_get_post_types();
707 if (
708 empty( $atts['products_ids'] ) &&
709 empty( $atts['purchased_products'] ) &&
710 empty( $atts['product_categories'] ) &&
711 empty( $atts['product_tags'] ) &&
712 ! empty( $post ) &&
713 in_array( $post->post_type, $post_types )
714 ) {
715 try {
716 ob_start();
717 $this->include_all_players( $post->ID );
718 $output = ob_get_contents();
719 ob_end_clean();
720
721 $class = esc_attr( isset( $atts['class'] ) ? $atts['class'] : '' );
722
723 return strpos( $output, 'wcmp-player-list' ) !== false ?
724 str_replace( 'wcmp-player-list', $class . ' wcmp-player-list', $output ) :
725 str_replace( 'wcmp-player-container', $class . ' wcmp-player-container', $output );
726 } catch ( Exception $err ) {
727 $atts['products_ids'] = $post->ID;
728 }
729 }
730
731 $atts = shortcode_atts(
732 array(
733 'products_ids' => '*',
734 'purchased_products' => 0,
735 'highlight_current_product' => 0,
736 'continue_playing' => 0,
737 'player_style' => WCMP_DEFAULT_PLAYER_LAYOUT,
738 'controls' => 'track',
739 'layout' => 'new',
740 'cover' => 0,
741 'volume' => 1,
742 'hide_purchase_buttons' => 0,
743 'class' => '',
744 'loop' => 0,
745 'purchased_times' => 0,
746 'download_links' => 0,
747 'duration' => 1,
748 'product_categories' => '',
749 'product_tags' => '',
750 'title' => '',
751 ),
752 $atts
753 );
754
755 $playlist_title = trim( $atts['title'] );
756 $products_ids = $atts['products_ids'];
757 $product_categories = $atts['product_categories'];
758 $product_tags = $atts['product_tags'];
759 $purchased_products = $atts['purchased_products'];
760 $highlight_current_product = $atts['highlight_current_product'];
761 $continue_playing = $atts['continue_playing'];
762 $player_style = $atts['player_style'];
763 $controls = $atts['controls'];
764 $layout = $atts['layout'];
765 $cover = $atts['cover'];
766 $volume = $atts['volume'];
767 $hide_purchase_buttons = $atts['hide_purchase_buttons'];
768 $class = $atts['class'];
769 $loop = $atts['loop'];
770 $purchased_times = $atts['purchased_times'];
771 $download_links_flag = $atts['download_links'];
772
773 // Typecasting variables.
774 $cover = is_numeric( $cover ) ? intval( $cover ) : 0;
775 $volume = is_numeric( $volume ) ? floatval( $volume ) : 0;
776 $purchased_products = is_numeric( $purchased_products ) ? intval( $purchased_products ) : 0;
777 $highlight_current_product = is_numeric( $highlight_current_product ) ? intval( $highlight_current_product ) : 0;
778 $continue_playing = is_numeric( $continue_playing ) ? intval( $continue_playing ) : 0;
779 $hide_purchase_buttons = is_numeric( $hide_purchase_buttons ) ? intval( $hide_purchase_buttons ) : 0;
780 $loop = is_numeric( $loop ) ? intval( $loop ) : 0;
781 $purchased_times = is_numeric( $purchased_times ) ? intval( $purchased_times ) : 0;
782
783 // get the produts ids
784 $products_ids = preg_replace( '/[^\d\,\*]/', '', $products_ids );
785 $products_ids = preg_replace( '/\,+/', ',', $products_ids );
786 $products_ids = trim( $products_ids, ',' );
787
788 // get the produt categories
789 $product_categories = preg_replace( '/\s*\,\s*/', ',', $product_categories );
790 $product_categories = preg_replace( '/\,+/', ',', $product_categories );
791 $product_categories = trim( $product_categories, ',' );
792
793 // get the produt tags
794 $product_tags = preg_replace( '/\s*\,\s*/', ',', $product_tags );
795 $product_tags = preg_replace( '/\,+/', ',', $product_tags );
796 $product_tags = trim( $product_tags, ',' );
797
798 if (
799 strlen( $products_ids ) == 0 &&
800 strlen( $product_categories ) == 0 &&
801 strlen( $product_tags ) == 0
802 ) {
803 return $output;
804 }
805
806 // MAIN CODE GOES HERE
807 global $wpdb, $post;
808
809 $current_post_id = ! empty( $post ) ? ( is_int( $post ) ? $post : $post->ID ) : -1;
810
811 $query = 'SELECT posts.ID, posts.post_title 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")';
812
813 if ( ! empty( $purchased_products ) ) {
814 // Hide the purchase buttons
815 $hide_purchase_buttons = 1;
816
817 // Getting the list of purchased products
818 $_current_user_id = get_current_user_id();
819 if ( 0 == $_current_user_id ) {
820 return $output;
821 }
822
823 // GET USER ORDERS (COMPLETED + PROCESSING)
824 $customer_orders = get_posts(
825 array(
826 'numberposts' => -1,
827 'meta_key' => '_customer_user',
828 'meta_value' => $_current_user_id,
829 'post_type' => wc_get_order_types(),
830 'post_status' => array_keys( wc_get_is_paid_statuses() ),
831 )
832 );
833
834 if ( empty( $customer_orders ) ) {
835 return $output;
836 }
837
838 // LOOP THROUGH ORDERS AND GET PRODUCT IDS
839 $products_ids = array();
840
841 foreach ( $customer_orders as $customer_order ) {
842 $order = wc_get_order( $customer_order->ID );
843 $items = $order->get_items();
844 foreach ( $items as $item ) {
845 $product_id = $item->get_product_id();
846 $products_ids[] = $product_id;
847 }
848 }
849 $products_ids = array_unique( $products_ids );
850 $products_ids_str = implode( ',', $products_ids );
851
852 $query .= ' AND posts.ID IN (' . $products_ids_str . ')';
853 $query .= ' ORDER BY FIELD(posts.ID,' . $products_ids_str . ')';
854 } else {
855 if ( strpos( '*', $products_ids ) === false ) {
856 $query .= ' AND posts.ID IN (' . $products_ids . ')';
857 $query .= ' ORDER BY FIELD(posts.ID,' . $products_ids . ')';
858 } else {
859
860 $tax_query = [];
861
862 // Product categories
863 if ( '' != $product_categories ) {
864 $product_cat_slugs = explode( ',', $product_categories );
865
866 $tax_query = [
867 'taxonomy' => 'product_cat',
868 'field' => 'slug',
869 'terms' => $product_cat_slugs,
870 'operator' => 'IN',
871 ];
872 }
873
874 // Product tags
875 if ( '' != $product_tags ) {
876 $product_tags_slugs = explode( ',', $product_tags );
877
878 if ( empty( $tax_query ) ) {
879 $tax_query = [
880 'taxonomy' => 'product_tag',
881 'field' => 'slug',
882 'terms' => $product_tags_slugs,
883 'operator' => 'IN',
884 ];
885 } else {
886 $tax_query = [
887 'relation' => 'AND',
888 $tax_query,
889 ['taxonomy' => 'product_tag',
890 'field' => 'slug',
891 'terms' => $product_tags_slugs,
892 'operator' => 'IN',]
893 ];
894 }
895 }
896
897 if ( ! empty( $tax_query ) ) {
898 $products_ids_args = [
899 'post_type' => $this->_get_post_types( false ),
900 'posts_per_page' => -1,
901 'fields' => 'ids',
902 'tax_query' => [$tax_query],
903 ];
904
905 $query_products_ids = new WP_Query( $products_ids_args );
906 $products_ids = $query_products_ids->posts;
907 if ( empty( $products_ids ) ) return $output;
908 $query .= ' AND posts.ID IN (' . implode( ',', $products_ids ) . ')';
909 }
910
911 $query .= ' ORDER BY posts.post_title ASC';
912 }
913 }
914
915 $products = $wpdb->get_results( $query ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
916
917 if ( ! empty( $products ) ) {
918 $product_purchased_times = array();
919 if ( $purchased_times ) {
920 $products_ids_str = ( is_array( $products_ids ) ) ? implode( ',', $products_ids ) : $products_ids;
921
922 $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
923 }
924
925 // Enqueue resources
926
927 $this->enqueue_resources();
928 wp_enqueue_style( 'wcmp-playlist-widget-style', plugin_dir_url( __FILE__ ) . 'widgets/playlist_widget/css/style.css', array(), WCMP_VERSION );
929 wp_enqueue_script( 'wcmp-playlist-widget-script', plugin_dir_url( __FILE__ ) . 'widgets/playlist_widget/js/public.js', array(), WCMP_VERSION );
930 wp_localize_script(
931 'wcmp-playlist-widget-script',
932 'wcmp_widget_settings',
933 array( 'continue_playing' => $continue_playing )
934 );
935 $counter = 0;
936 $output .= '<div data-loop="' . ( $loop ? 1 : 0 ) . '">';
937 foreach ( $products as $product ) {
938 $product_obj = wc_get_product( $product->ID );
939
940 $counter++;
941 $preload = $this->get_product_attr( $product->ID, '_wcmp_preload', '' );
942 $row_class = 'wcmp-even-product';
943 if ( 1 == $counter % 2 ) {
944 $row_class = 'wcmp-odd-product';
945 }
946
947 $audio_files = $this->get_product_files( $product->ID );
948 if ( ! is_array( $audio_files ) ) {
949 continue;
950 }
951
952 if ( $cover ) {
953 $featured_image = get_the_post_thumbnail_url( $product->ID );
954 }
955
956 // Download files links
957 $download_links = '';
958
959 if ( $download_links_flag ) {
960 $download_links = $this->woocommerce_user_download( $product->ID );
961 if ( ! empty( $download_links ) ) {
962 $download_links = '<span class="wcmp-download-links">(' . $download_links . ')</span>';
963 }
964 }
965
966 if ( 'new' == $layout ) {
967 $price = $product_obj->get_price();
968 $output .= '
969 <div class="wcmp-new-layout 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' : '' ) . '">
970 <div class="wcmp-widget-product-header">
971 <div class="wcmp-widget-product-title">
972 <a href="' . esc_url( get_permalink( $product->ID ) ) . '">' . $product_obj->get_name() . '</a>' .
973 (
974 $purchased_times ?
975 '<span class="wcmp-purchased-times">' .
976 sprintf(
977 /* translators: %d: purchased times */
978 __( $this->get_global_attr( '_wcmp_purchased_times_text', '- purchased %d time(s)' ), 'music-player-for-woocommerce' ), // phpcs:ignore WordPress.WP.I18n.NonSingularStringLiteralText
979 $get_times( $product->ID, $product_purchased_times )
980 ) . '</span>' : ''
981 ) .
982 $download_links .
983 '</div><!-- product title -->
984 ';
985
986 if ( 0 != @floatval( $price ) && 0 == $hide_purchase_buttons ) {
987 $product_id_for_add_to_cart = $product->ID;
988 if( $product_obj->is_type( 'variable' ) ){
989 $variations = $product_obj->get_available_variations();
990 $variations_id = wp_list_pluck( $variations, 'variation_id' );
991 if( ! empty( $variations_id ) ) $product_id_for_add_to_cart = $variations_id[0];
992 } elseif ( $product_obj->is_type( 'grouped' ) ) {
993 $children = $product_obj->get_children();
994 if( ! empty( $children ) ) $product_id_for_add_to_cart = $children[0];
995 }
996
997 $output .= '<div class="wcmp-widget-product-purchase">
998 ' . wc_price( $product_obj->get_price(), '' ) . ' <a href="?add-to-cart=' . $product_id_for_add_to_cart . '"></a>
999 </div><!-- product purchase -->
1000 ';
1001 }
1002 $output .= '</div>
1003 <div class="wcmp-widget-product-files">
1004 ';
1005
1006 if ( ! empty( $featured_image ) ) {
1007 $output .= '<img src="' . esc_attr( $featured_image ) . '" class="wcmp-widget-feature-image" /><div class="wcmp-widget-product-files-list">';
1008 }
1009
1010 foreach ( $audio_files as $index => $file ) {
1011 $audio_url = $this->generate_audio_url( $product->ID, $index, $file );
1012 $duration = $this->_get_duration_by_url( $file['file'] );
1013 $audio_tag = apply_filters(
1014 'wcmp_widget_audio_tag',
1015 $this->get_player(
1016 $audio_url,
1017 array(
1018 'player_controls' => $controls,
1019 'player_style' => $player_style,
1020 'media_type' => $file['media_type'],
1021 'id' => $index,
1022 'duration' => $duration,
1023 'preload' => $preload,
1024 'volume' => $volume,
1025 )
1026 ),
1027 $product->ID,
1028 $index,
1029 $audio_url
1030 );
1031 $file_title = esc_html( apply_filters( 'wcmp_widget_file_name', $file['name'], $product->ID, $index ) );
1032 $output .= '
1033 <div class="wcmp-widget-product-file">
1034 ' . $audio_tag . '<span class="wcmp-file-name">' . $file_title . '</span>' . ( ! isset( $atts['duration'] ) || $atts['duration'] == 1 ? '<span class="wcmp-file-duration">' . esc_html( $duration ) . '</span>' : '' ) . '<div style="clear:both;"></div>
1035 </div><!--product file -->
1036 ';
1037 }
1038
1039 if ( ! empty( $featured_image ) ) {
1040 $output .= '</div>';
1041 }
1042
1043 $output .= '
1044 </div><!-- product-files -->
1045 </div><!-- product -->
1046 ';
1047 } else // Load the previous playlist layout
1048 {
1049 $output .= '<ul class="wcmp-widget-playlist wcmp-classic-layout controls-' . esc_attr( $controls ) . ' ' . esc_attr( $class ) . ' ' . esc_attr( $row_class ) . ' ' . esc_attr( ( $product->ID == $current_post_id && $highlight_current_product ) ? 'wcmp-current-product' : '' ) . '">';
1050
1051 if ( ! empty( $featured_image ) ) {
1052 $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>';
1053 }
1054
1055 foreach ( $audio_files as $index => $file ) {
1056 $audio_url = $this->generate_audio_url( $product->ID, $index, $file );
1057 $duration = $this->_get_duration_by_url( $file['file'] );
1058 $audio_tag = apply_filters(
1059 'wcmp_widget_audio_tag',
1060 $this->get_player(
1061 $audio_url,
1062 array(
1063 'player_controls' => $controls,
1064 'player_style' => $player_style,
1065 'media_type' => $file['media_type'],
1066 'id' => $index,
1067 'duration' => $duration,
1068 'preload' => $preload,
1069 'volume' => $volume,
1070 )
1071 ),
1072 $product->ID,
1073 $index,
1074 $audio_url
1075 );
1076 $file_title = esc_html( apply_filters( 'wcmp_widget_file_name', ( ( ! empty( $file['name'] ) ) ? $file['name'] : $product->post_title ), $product->ID, $index ) );
1077
1078 $output .= '<li class="wcmp-widget-playlist-item">' . $audio_tag . '<a href="' . esc_url( get_permalink( $product->ID ) ) . '">' . $file_title . '</a>' .
1079 (
1080 $purchased_times ?
1081 '<span class="wcmp-purchased-times">' .
1082 sprintf(
1083 /* translators: %d: purchased times */
1084 __( $this->get_global_attr( '_wcmp_purchased_times_text', '- purchased %d time(s)' ), 'music-player-for-woocommerce' ), // phpcs:ignore WordPress.WP.I18n.NonSingularStringLiteralText
1085 $get_times( $product->ID, $product_purchased_times )
1086 ) . '</span>' : ''
1087 )
1088 . ( ! isset( $atts['duration'] ) || $atts['duration'] == 1 ? '<span class="wcmp-file-duration">' . esc_html( $duration ) . '</span>' : '' )
1089 . '<div style="clear:both;"/></li>';
1090 }
1091 if ( ! empty( $featured_image ) ) {
1092 $output .= '</ul></div></li>';
1093 }
1094
1095 $output .= $download_links; // Download links
1096
1097 $output .= '</ul>';
1098 }
1099 }
1100 $output .= '</div>';
1101 }
1102
1103 if ( ! empty( $playlist_title ) && ! empty( $output ) ) {
1104 $output = '<div class="wcmp-widget-playlist-title">' . esc_html( $playlist_title ) . '</div>' . $output;
1105 }
1106
1107 return $output;
1108 } // End replace_playlist_shortcode
1109
1110 /**
1111 * Used for accepting the <source> tags
1112 */
1113 public function allowed_html_tags( $allowedposttags, $context ) {
1114 if ( ! in_array( 'source', $allowedposttags ) ) {
1115 $allowedposttags['source'] = array(
1116 'src' => true,
1117 'type' => true,
1118 );
1119 }
1120 return $allowedposttags;
1121 } // End allowed_html_tags
1122
1123 public function preload( $preload, $audio_url ) {
1124 $result = $preload;
1125 if ( strpos( $audio_url, 'wcmp-action=play' ) !== false ) {
1126 if ( $this->_preload_times ) {
1127 $result = 'none';
1128 }
1129 $this->_preload_times++;
1130 }
1131 return $result;
1132 } // End preload
1133
1134 // ******************** WOOCOMMERCE ACTIONS ************************
1135
1136 public function woocommerce_user_download( $product_id ) {
1137 $download_links = [];
1138 if ( is_user_logged_in() ) {
1139 if ( empty( $this->_current_user_downloads ) && function_exists( 'wc_get_customer_available_downloads' ) ) {
1140 $current_user = wp_get_current_user();
1141 $this->_current_user_downloads = wc_get_customer_available_downloads( $current_user->ID );
1142 }
1143
1144 foreach ( $this->_current_user_downloads as $download ) {
1145 if ( $download['product_id'] == $product_id ) {
1146 $download_links[ $download['download_id'] ] = $download['download_url'];
1147 }
1148 }
1149 }
1150
1151 $download_links = array_unique( $download_links );
1152 if ( count( $download_links ) ) {
1153 $download_links = array_values( $download_links );
1154 return '<a href="javascript:void(0);" data-download-links="' . esc_attr( json_encode( $download_links ) ) . '" class="wcmp-download-link">' . esc_html__( 'download', 'music-player-for-woocommerce' ) . '</a>';
1155 }
1156 return '';
1157
1158 }
1159
1160 public function woocommerce_product_title( $title, $product ) {
1161 global $wp;
1162 if ( ! empty( $wp->query_vars['wcfm-products-manage'] )) {
1163 return $title;
1164 }
1165 $player = '';
1166 if ( false === stripos( $title, '<audio' ) ) {
1167 $player .= $this->include_main_player( $product, false );
1168 }
1169 return $player . $title;
1170 } // End woocommerce_product_title
1171
1172 /**
1173 * Load the additional attributes to select the player layout
1174 */
1175 public function woocommerce_player_settings() {
1176 include_once 'views/player_options.php';
1177 } // End woocommerce_player_settings
1178
1179 public function get_player(
1180 $audio_url,
1181 $args = array()
1182 ) {
1183 $default_args = array(
1184 'media_type' => 'mp3',
1185 'player_style' => WCMP_DEFAULT_PLAYER_LAYOUT,
1186 'player_controls' => WCMP_DEFAULT_PLAYER_CONTROLS,
1187 'duration' => false,
1188 'volume' => 1,
1189 );
1190
1191 $args = array_merge( $default_args, $args );
1192 $id = ( ! empty( $args['id'] ) ) ? 'id="' . esc_attr( $args['id'] ) . '"' : '';
1193
1194 $preload = ( ! empty( $args['preload'] ) ) ? $args['preload'] : $GLOBALS['WooCommerceMusicPlayer']->get_global_attr(
1195 '_wcmp_preload',
1196 // This option is only for compatibility with versions previous to 1.0.28
1197 $GLOBALS['WooCommerceMusicPlayer']->get_global_attr( 'preload', 'none' )
1198 );
1199 $preload = apply_filters( 'wcmp_preload', $preload, $audio_url );
1200
1201 return '<audio ' . (
1202 (
1203 isset( $args['volume'] ) &&
1204 is_numeric( $args['volume'] ) &&
1205 0 <= $args['volume'] * 1 &&
1206 $args['volume'] * 1 <= 1
1207 ) ? 'volume="' . esc_attr( $args['volume'] ) . '"' : ''
1208 ) . ' ' . $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>';
1209
1210 } // End get_player
1211
1212 public function get_product_files( $id ) {
1213 $product = wc_get_product( $id );
1214 if ( ! empty( $product ) ) {
1215 return $this->_get_product_files(
1216 array(
1217 'product' => $product,
1218 'all' => 1,
1219 )
1220 );
1221 }
1222 return array();
1223 }
1224
1225 public function generate_audio_url( $product_id, $file_id, $file_data = array() ) {
1226 return $this->_generate_audio_url( $product_id, $file_id, $file_data );
1227 }
1228
1229 public function include_main_player_filter( $value, $id ) {
1230 global $wp;
1231 if (
1232 $this->_force_hook_title &&
1233 did_action('woocommerce_init') &&
1234 false === stripos( $value, '<audio' )
1235 ) {
1236 try {
1237 if (
1238 ( wp_doing_ajax() || ! is_admin() ) &&
1239 (
1240 ! function_exists( 'is_product' ) ||
1241 ! is_product() ||
1242 ( is_product() && get_queried_object_id() != $id )
1243 ) &&
1244 ! is_cart() &&
1245 ! is_page( 'cart' ) &&
1246 ! is_checkout() &&
1247 is_int( $id ) &&
1248 empty( $_REQUEST['wcmp_nonce'] ) &&
1249 empty( $wp->query_vars['wcfm-products-manage'] )
1250 ) {
1251 $p = wc_get_product( $id );
1252 if ( ! empty( $p ) ) {
1253 add_filter( 'esc_html', array( &$this, 'esc_html' ), 10, 2 );
1254
1255 $player = '';
1256 $player = $this->include_main_player( $p, false );
1257 $value = $player . $value;
1258 }
1259 }
1260 } catch ( Exception $err ) {
1261 error_log( $err->getMessage() );
1262 }
1263 }
1264 return $value;
1265 }
1266
1267 public function include_players( ...$args ) {
1268 if ( ! $this->_inserted_player ) {
1269 $this->_inserted_player = true;
1270 if ( ! empty( $args ) ) {
1271 $this->include_all_players( $args[0] );
1272 } else {
1273 $this->include_all_players();
1274 }
1275 }
1276
1277 if ( ! empty( $args ) ) {
1278 return $args[0];
1279 }
1280 } // End include_players
1281
1282 public function include_main_player( $product = '', $_echo = true ) {
1283 $output = '';
1284
1285 if ( is_admin() ) return $output;
1286
1287 if ( ! $this->_insert_player || ! $this->_insert_main_player ) {
1288 return $output;
1289 }
1290 if ( is_numeric( $product ) ) {
1291 $product = wc_get_product( $product );
1292 }
1293 if ( ! is_object( $product ) ) {
1294 $product = wc_get_product();
1295 }
1296
1297 if ( empty( $product ) ) {
1298 return '';
1299 }
1300
1301 $files = $this->_get_product_files(
1302 array(
1303 'product' => $product,
1304 'first' => true,
1305 )
1306 );
1307 if ( ! empty( $files ) ) {
1308 $id = $product->get_id();
1309
1310 $show_in = $this->get_product_attr( $id, '_wcmp_show_in', 'all' );
1311 if (
1312 ( 'single' == $show_in && ( ! function_exists( 'is_product' ) || ! is_product() ) ) ||
1313 ( 'multiple' == $show_in && ( function_exists( 'is_product' ) && is_product() ) && get_queried_object_id() == $id )
1314 ) {
1315 return $output;
1316 }
1317 $preload = $this->get_product_attr( $id, '_wcmp_preload', '' );
1318 $this->enqueue_resources();
1319
1320 $player_style = $this->get_product_attr( $id, '_wcmp_player_layout', WCMP_DEFAULT_PLAYER_LAYOUT );
1321 $player_controls = ( $this->get_product_attr( $id, '_wcmp_player_controls', WCMP_DEFAULT_PLAYER_CONTROLS ) != 'all' ) ? 'track' : '';
1322 $volume = @floatval( $this->get_product_attr( $id, '_wcmp_player_volume', WCMP_DEFAULT_PLAYER_VOLUME ) );
1323
1324 $file = reset( $files );
1325 $index = key( $files );
1326 $audio_url = $this->_generate_audio_url( $id, $index, $file );
1327 $duration = $this->_get_duration_by_url( $file['file'] );
1328 $audio_tag = apply_filters(
1329 'wcmp_audio_tag',
1330 $this->get_player(
1331 $audio_url,
1332 array(
1333 'player_controls' => $player_controls,
1334 'player_style' => $player_style,
1335 'media_type' => $file['media_type'],
1336 'duration' => $duration,
1337 'preload' => $preload,
1338 'volume' => $volume,
1339 )
1340 ),
1341 $id,
1342 $index,
1343 $audio_url
1344 );
1345
1346 do_action( 'wcmp_before_player_shop_page', $id );
1347
1348 $output = '<div class="wcmp-player-container product-' . esc_attr( $file['product'] ) . '">' . $audio_tag . '</div>';
1349 if ( $_echo ) {
1350 print $output; // phpcs:ignore WordPress.Security.EscapeOutput
1351 }
1352
1353 do_action( 'wcmp_after_player_shop_page', $id );
1354
1355 return $output; // phpcs:ignore WordPress.Security.EscapeOutput
1356 }
1357 } // End include_main_player
1358
1359 public function include_all_players( $product = '' ) {
1360
1361 if ( ! $this->_insert_player || ! $this->_insert_all_players || is_admin() ) {
1362 return;
1363 }
1364
1365 if ( ! is_object( $product ) ) {
1366 $product = wc_get_product();
1367 }
1368
1369 if ( empty( $product ) ) {
1370 return;
1371 }
1372
1373 $files = $this->_get_product_files(
1374 array(
1375 'product' => $product,
1376 'all' => true,
1377 )
1378 );
1379 if ( ! empty( $files ) ) {
1380 $id = $product->get_id();
1381
1382 $show_in = $this->get_product_attr( $id, '_wcmp_show_in', 'all' );
1383 if (
1384 ( 'single' == $show_in && ! is_singular() ) ||
1385 ( 'multiple' == $show_in && is_singular() )
1386 ) {
1387 return;
1388 }
1389 $preload = $this->get_product_attr( $id, '_wcmp_preload', '' );
1390 $this->enqueue_resources();
1391 $player_style = $this->get_product_attr( $id, '_wcmp_player_layout', WCMP_DEFAULT_PLAYER_LAYOUT );
1392 $volume = @floatval( $this->get_product_attr( $id, '_wcmp_player_volume', WCMP_DEFAULT_PLAYER_VOLUME ) );
1393 $player_controls = $this->get_product_attr( $id, '_wcmp_player_controls', WCMP_DEFAULT_PLAYER_CONTROLS );
1394 $player_title = intval( $this->get_product_attr( $id, '_wcmp_player_title', WCMP_DEFAULT_PlAYER_TITLE ) );
1395 $loop = intval( $this->get_product_attr( $id, '_wcmp_loop', 0 ) );
1396 $merge_grouped = intval( $this->get_product_attr( $id, '_wcmp_merge_in_grouped', 0 ) );
1397 $merge_grouped_clss = ( $merge_grouped ) ? 'merge_in_grouped_products' : '';
1398
1399 $counter = count( $files );
1400
1401 do_action( 'wcmp_before_players_product_page', $id );
1402 if ( 1 == $counter ) {
1403 $player_controls = ( 'button' == $player_controls ) ? 'track' : '';
1404 $file = reset( $files );
1405 $index = key( $files );
1406 $audio_url = $this->_generate_audio_url( $id, $index, $file );
1407 $duration = $this->_get_duration_by_url( $file['file'] );
1408 $audio_tag = apply_filters(
1409 'wcmp_audio_tag',
1410 $this->get_player(
1411 $audio_url,
1412 array(
1413 'player_controls' => $player_controls,
1414 'player_style' => $player_style,
1415 'media_type' => $file['media_type'],
1416 'duration' => $duration,
1417 'preload' => $preload,
1418 'volume' => $volume,
1419 )
1420 ),
1421 $id,
1422 $index,
1423 $audio_url
1424 );
1425 $title = esc_html( ( $player_title ) ? apply_filters( 'wcmp_file_name', $file['name'], $id, $index ) : '' );
1426 print '<div class="wcmp-player-container ' . esc_attr( $merge_grouped_clss ) . ' product-' . esc_attr( $file['product'] ) . '" ' . ( $loop ? 'data-loop="1"' : '' ) . '>' . $audio_tag . '</div><div class="wcmp-player-title" data-audio-url="' . esc_attr( $audio_url ) . '">' . wp_kses_post( $title ) . '</div><div style="clear:both;"></div>'; // phpcs:ignore WordPress.Security.EscapeOutput
1427 } elseif ( $counter > 1 ) {
1428
1429 $single_player = intval( $this->get_product_attr( $id, '_wcmp_single_player', WCMP_DEFAULT_SINGLE_PLAYER ) );
1430
1431 $before = '<table class="wcmp-player-list ' . $merge_grouped_clss . ( $single_player ? ' wcmp-single-player ' : '' ) . '" ' . ( $loop ? 'data-loop="1"' : '' ) . '>';
1432 $first_player_class = 'wcmp-first-player';
1433 $after = '';
1434 foreach ( $files as $index => $file ) {
1435 $evenOdd = ( 1 == $counter % 2 ) ? 'wcmp-odd-row' : 'wcmp-even-row';
1436 $counter--;
1437 $audio_url = $this->_generate_audio_url( $id, $index, $file );
1438 $duration = $this->_get_duration_by_url( $file['file'] );
1439 $audio_tag = apply_filters(
1440 'wcmp_audio_tag',
1441 $this->get_player(
1442 $audio_url,
1443 array(
1444 'player_style' => $player_style,
1445 'player_controls' => ( 'all' != $player_controls ) ? 'track' : '',
1446 'media_type' => $file['media_type'],
1447 'duration' => $duration,
1448 'preload' => $preload,
1449 'volume' => $volume,
1450 )
1451 ),
1452 $id,
1453 $index,
1454 $audio_url
1455 );
1456 $title = esc_html( ( $player_title ) ? apply_filters( 'wcmp_file_name', $file['name'], $id, $index ) : '' );
1457
1458 print $before; // phpcs:ignore WordPress.Security.EscapeOutput
1459 $before = '';
1460 $after = '</table>';
1461 if ( 'all' != $player_controls ) {
1462 print '<tr class="' . esc_attr( $evenOdd ) . ' product-' . esc_attr( $file['product'] ) . '"><td class="wcmp-column-player-' . esc_attr( $player_style ) . '"><div class="wcmp-player-container ' . $first_player_class . '" data-wcfm-pair="' . esc_attr( $counter ) . '">' . $audio_tag . '</div></td><td class="wcmp-player-title wcmp-column-player-title" data-wcfm-pair="' . esc_attr( $counter ) . '">' . wp_kses_post( $title ) . '</td><td class="wcmp-file-duration" style="text-align:right;font-size:16px;">' . esc_html( $duration ) . '</td></tr>'; // phpcs:ignore WordPress.Security.EscapeOutput
1463 } else {
1464 print '<tr class="' . esc_attr( $evenOdd ) . ' product-' . esc_attr( $file['product'] ) . '"><td><div class="wcmp-player-container ' . $first_player_class . '" data-wcfm-pair="' . esc_attr( $counter ) . '">' . $audio_tag . '</div><div class="wcmp-player-title wcmp-column-player-title" data-wcfm-pair="' . esc_attr( $counter ) . '">' . wp_kses_post( $title ) . ( $single_player ? '<span class="wcmp-file-duration">' . esc_html( $duration ) . '</span>' : '' ) . '</div></td></tr>'; // phpcs:ignore WordPress.Security.EscapeOutput
1465 }
1466 $first_player_class = '';
1467 }
1468 print $after; // phpcs:ignore WordPress.Security.EscapeOutput
1469 }
1470 do_action( 'wcmp_after_players_product_page', $id );
1471 }
1472 } // End include_all_players
1473
1474 public function player_in_cart( $cart_item, $cart_item_key ) {
1475 $product = wc_get_product( $cart_item['product_id'] );
1476 $this->include_all_players( $product );
1477 } // player_in_cart
1478
1479 // Integration with woocommerce-product-table by barn2media
1480 public function product_table_data_name( $name, $product ) {
1481 if ( false === stripos( $name, '<audio' ) ) {
1482 $player = $this->include_main_player( $product, false );
1483 $player = str_replace( '<div ', '<div style="display:inline-block" ', $player );
1484 $name = $player . $name;
1485 }
1486 return $name;
1487 } // product_table_data_name
1488
1489 public function add_data_product( $player, $product_id, $index, $url ) {
1490 $player = preg_replace( '/<audio\b/i', '<audio controlslist="nodownload" data-product="' . esc_attr( $product_id ) . '" ', $player );
1491 return $player;
1492 } // End add_data_product
1493
1494 public function add_class_attachment( $html, $product, $size, $attr, $placeholder, $image ) {
1495 $id = $product->get_id();
1496 $html = $this->_add_class( $html, $product );
1497 return $html;
1498 } // End add_class_attachment
1499
1500 public function add_class_single_product_image( $html, $post_thumbnail_id ) {
1501 global $product;
1502
1503 if ( ! empty( $product ) ) {
1504 $html = $this->_add_class( $html, $product );
1505 }
1506 return $html;
1507 } // add_class_single_product_image
1508
1509 public function init_force_in_title( $v = null ) {
1510 if ( is_admin() ) {
1511 $this->_force_hook_title = 0;
1512 return;
1513 }
1514
1515 if ( is_numeric( $v ) ) {
1516 $this->_force_hook_title = intval( $v );
1517 return;
1518 }
1519
1520 $this->_force_hook_title = $this->get_global_attr( '_wcmp_main_player_hook_title', 1 );
1521
1522 // Integration with "WOOF – Products Filter for WooCommerce" by realmag777
1523 if ( isset( $_REQUEST['action'] ) && 'woof_draw_products' == $_REQUEST['action'] ) {
1524 $this->_force_hook_title = 1;
1525 }
1526
1527 } // End init_force_in_title
1528
1529 // ******************** PRIVATE METHODS ************************
1530
1531 private function get_ip_address() {
1532 if( ! empty( $_SERVER['HTTP_CLIENT_IP'] ) ) { //whether ip is from the share internet
1533 $ip = $_SERVER['HTTP_CLIENT_IP'];
1534 } elseif (! empty( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) { //whether ip is from the proxy
1535 $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
1536 } else{ //whether ip is from the remote address
1537 $ip = $_SERVER['REMOTE_ADDR'];
1538 }
1539 return $ip;
1540 } // End update_playback_counter
1541
1542 private function clear_expired_transients() {
1543 $transient = get_transient( 'wcmp_clear_expired_transients' );
1544 if( ! $transient || 24 * 60 * 60 <= time() - intval( $transient ) ) {
1545 set_transient( 'wcmp_clear_expired_transients', time() );
1546 delete_expired_transients();
1547 }
1548 } // End clear_expired_transients
1549
1550 private function update_playback_counter( $product_id ) {
1551
1552 $ip = $this->get_ip_address();
1553 $transient_name = 'wcmp-playback-record-' . md5( $ip ) . '-' . $product_id;
1554 $transient = get_transient( $transient_name );
1555 if ( ! get_transient( $transient_name ) ) {
1556 set_transient( $transient_name, 1, 12 * 60 * 60 );
1557
1558 $counter = get_post_meta( $product_id, '_wcmp_playback_counter', true );
1559
1560 if ( is_numeric( $counter ) ) $counter = intval( $counter );
1561 else $counter = 0;
1562
1563 $counter++;
1564 update_post_meta( $product_id, '_wcmp_playback_counter', $counter );
1565 }
1566 } // End update_playback_counter
1567
1568 private function _get_post_types( $mysql_in = false ) {
1569 $post_types = array( 'product' );
1570 if ( ! empty( $GLOBALS['wcmp_post_types'] ) && is_array( $GLOBALS['wcmp_post_types'] ) ) {
1571 $post_types = $GLOBALS['wcmp_post_types'];
1572 }
1573 if ( $mysql_in ) {
1574 return '"' . implode( '","', $post_types ) . '"';
1575 }
1576 return $post_types;
1577 } // End _get_post_types
1578
1579 private function _load_addons() {
1580 $path = __DIR__ . '/addons';
1581 $wcmp = $this;
1582
1583 if ( file_exists( $path ) ) {
1584 $addons = dir( $path );
1585 while ( false !== ( $entry = $addons->read() ) ) {
1586 if ( strlen( $entry ) > 3 && strtolower( pathinfo( $entry, PATHINFO_EXTENSION ) ) == 'php' ) {
1587 include_once $addons->path . '/' . $entry;
1588 }
1589 }
1590 }
1591 } // End _load_addons
1592
1593 private function _preview() {
1594 $user = wp_get_current_user();
1595 $allowed_roles = array( 'editor', 'administrator', 'author' );
1596
1597 if ( array_intersect( $allowed_roles, $user->roles ) ) {
1598 if ( ! empty( $_REQUEST['wcmp-preview'] ) ) {
1599 // Sanitizing variable
1600 $preview = sanitize_text_field( wp_unslash( $_REQUEST['wcmp-preview'] ) );
1601
1602 // Remove every shortcode that is not in the plugin
1603 remove_all_shortcodes();
1604 add_shortcode( 'wcmp-playlist', array( &$this, 'replace_playlist_shortcode' ) );
1605
1606 if ( has_shortcode( $preview, 'wcmp-playlist' ) ) {
1607 print '<!DOCTYPE html>';
1608 $if_empty = __( 'There are no products that satisfy the block\'s settings', 'music-player-for-woocommerce' );
1609 wp_enqueue_script( 'jquery' );
1610 $output = do_shortcode( $preview );
1611 if ( preg_match( '/^\s*$/', $output ) ) {
1612 $output = '<div>' . $if_empty . '</div>';
1613 }
1614
1615 // Deregister all scripts and styles for loading only the plugin styles.
1616 global $wp_styles, $wp_scripts;
1617 if ( ! empty( $wp_scripts ) ) {
1618 $wp_scripts->reset();
1619 }
1620 $this->enqueue_resources();
1621 if ( ! empty( $wp_styles ) ) {
1622 $wp_styles->do_items();
1623 }
1624 if ( ! empty( $wp_scripts ) ) {
1625 $wp_scripts->do_items();
1626 }
1627
1628 print '<div class="wcmp-preview-container">' . $output . '</div>'; // phpcs:ignore WordPress.Security.EscapeOutput
1629 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>';
1630 exit;
1631 }
1632 }
1633 }
1634 } // End _preview
1635
1636 private function _createDir() {
1637 // Generate upload dir
1638 $_files_directory = wp_upload_dir();
1639 $this->_files_directory_path = rtrim( $_files_directory['basedir'], '/' ) . '/wcmp/';
1640 $this->_files_directory_url = rtrim( $_files_directory['baseurl'], '/' ) . '/wcmp/';
1641 $this->_files_directory_url = preg_replace( '/^http(s)?:\/\//', '//', $this->_files_directory_url );
1642 if ( ! file_exists( $this->_files_directory_path ) ) {
1643 @mkdir( $this->_files_directory_path, 0755 );
1644 }
1645 } // End _createDir
1646
1647 private function _clearDir( $dirPath ) {
1648 try {
1649 if ( empty( $dirPath ) || ! file_exists( $dirPath ) || ! is_dir( $dirPath ) ) {
1650 return;
1651 }
1652 $dirPath = rtrim( $dirPath, '\\/' ) . '/';
1653 $files = glob( $dirPath . '*', GLOB_MARK );
1654 foreach ( $files as $file ) {
1655 if ( is_dir( $file ) ) {
1656 $this->_clearDir( $file );
1657 } else {
1658 unlink( $file );
1659 }
1660 }
1661 } catch ( Exception $err ) {
1662 return;
1663 }
1664 } // End _clearDir
1665
1666 private function _get_duration_by_url( $url ) {
1667 global $wpdb;
1668 try {
1669 $attachment = $wpdb->get_col( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE guid RLIKE %s;", $url ) );
1670 if ( empty( $attachment ) ) {
1671 $uploads_dir = wp_upload_dir();
1672 $uploads_url = $uploads_dir['baseurl'];
1673 $parsed_url = explode( parse_url( $uploads_url, PHP_URL_PATH ), $url );
1674 $this_host = str_ireplace( 'www.', '', parse_url( home_url(), PHP_URL_HOST ) );
1675 $file_host = str_ireplace( 'www.', '', parse_url( $url, PHP_URL_HOST ) );
1676 if ( ! isset( $parsed_url[1] ) || empty( $parsed_url[1] ) || ( $this_host != $file_host ) ) {
1677 return false;
1678 }
1679 $file = trim( $parsed_url[1], '/' );
1680 $attachment = $wpdb->get_col( $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key='_wp_attached_file' AND meta_value RLIKE %s;", $file ) );
1681 }
1682 if ( ! empty( $attachment ) && ! empty( $attachment[0] ) ) {
1683 $metadata = wp_get_attachment_metadata( $attachment[0] );
1684 if ( false !== $metadata && ! empty( $metadata['length_formatted'] ) ) {
1685 return $metadata['length_formatted'];
1686 }
1687 }
1688 } catch ( Exception $err ) {
1689 error_log( $err->getMessage() );
1690 }
1691 return false;
1692 } // End _get_duration_by_url
1693
1694 private function _generate_audio_url( $product_id, $file_index, $file_data = array() ) {
1695 if ( ! empty( $file_data['file'] ) ) {
1696 $file_url = $file_data['file'];
1697 if ( ! empty( $file_data['play_src'] ) || $this->_is_playlist( $file_url ) ) {
1698 return $file_url; // Play src audio file, without copying or truncate it.
1699 }
1700
1701 // If the playback of music are tracked with Google Analytics, should not be loaded directly the audio files.
1702 $_wcmp_analytics_property = trim( $this->get_global_attr( '_wcmp_analytics_property', '' ) );
1703 if ( '' == $_wcmp_analytics_property ) {
1704 $file_name = $this->_demo_file_name( $file_url );
1705
1706 $file_path = $this->_files_directory_path . $file_name;
1707
1708 if ( $this->_valid_demo( $file_path ) ) {
1709 return 'http' . ( ( is_ssl() ) ? 's:' : ':' ) . $this->_files_directory_url . $file_name;
1710 }
1711 }
1712 }
1713 $url = WCMP_WEBSITE_URL; //isset( $_SERVER['REQUEST_URI'] ) ? esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '';
1714 $url .= ( ( strpos( $url, '?' ) === false ) ? '?' : '&' ) . 'wcmp-action=play&wcmp-product=' . $product_id . '&wcmp-file=' . $file_index;
1715 return $url;
1716 } // End _generate_audio_url
1717
1718 private function _delete_truncated_files( $product_id ) {
1719 $files_arr = get_post_meta( $product_id, '_downloadable_files', true );
1720 if ( ! empty( $files_arr ) && is_array( $files_arr ) ) {
1721 foreach ( $files_arr as $file ) {
1722 if ( is_array( $file ) && ! empty( $file['file'] ) ) {
1723 $ext = pathinfo( $file['file'], PATHINFO_EXTENSION );
1724 $file_name = md5( $file['file'] ) . ( ( ! empty( $ext ) ) ? '.' . $ext : '' );
1725 if ( file_exists( $this->_files_directory_path . $file_name ) ) {
1726 @unlink( $this->_files_directory_path . $file_name );
1727 }
1728 }
1729 }
1730 }
1731
1732 } // End _delete_truncated_files
1733
1734 /**
1735 * Check if the file is an m3u or m3u8 playlist
1736 */
1737 private function _is_playlist( $file_path ) {
1738 return preg_match( '/\.(m3u|m3u8)$/i', $file_path );
1739 } // End _is_playlist
1740
1741 /**
1742 * Check if the file is an audio file and return its type or false
1743 */
1744 private function _is_audio( $file_path ) {
1745 $aux = function ( $file_path ) {
1746 if ( preg_match( '/\.(mp3|ogg|oga|wav|wma|mp4)$/i', $file_path, $match ) ) {
1747 return $match[1];
1748 }
1749 if ( preg_match( '/\.m4a$/i', $file_path ) ) {
1750 return 'mp4';
1751 }
1752 if ( $this->_is_playlist( $file_path ) ) {
1753 return 'hls';
1754 }
1755 return false;
1756 };
1757
1758 $file_name = $this->_demo_file_name( $file_path );
1759 $demo_file_path = $this->_files_directory_path . $file_name;
1760 if ( $this->_valid_demo( $demo_file_path ) ) return $aux( $demo_file_path );
1761
1762 $ext = $aux( $file_path );
1763 if ( $ext ) return $ext;
1764
1765 $file_path = WooCommerceMusicPlayerTools::get_google_drive_file_name( $file_path );
1766
1767 $ext = $aux( $file_path );
1768 if ( $ext ) return $ext;
1769
1770 // From troubleshoot
1771 $extension = pathinfo( $file_path, PATHINFO_EXTENSION );
1772 $troubleshoot_default_extension = $GLOBALS['WooCommerceMusicPlayer']->get_global_attr( '_wcmp_default_extension', false );
1773 if ( ( empty( $extension ) || ! preg_match( '/^[a-z\d]{3,4}$/i', $extension ) ) && $troubleshoot_default_extension ) {
1774 return 'mp3';
1775 }
1776
1777 return false;
1778 } // End _is_audio
1779
1780 private function _sort_list( $product_a, $product_b ) {
1781 if (
1782 ! is_object( $product_a ) || ! method_exists( $product_a, 'get_menu_order' ) ||
1783 ! is_object( $product_b ) || ! method_exists( $product_b, 'get_menu_order' )
1784 ) {
1785 return 0;
1786 }
1787
1788 $menu_order_a = $product_a->get_menu_order();
1789 $menu_order_b = $product_b->get_menu_order();
1790 if ( $menu_order_a == $menu_order_b ) {
1791 if (
1792 ! method_exists( $product_a, 'get_name' ) ||
1793 ! method_exists( $product_b, 'get_name' )
1794 ) {
1795 return 0;
1796 }
1797
1798 $name_a = $product_a->get_name();
1799 $name_b = $product_b->get_name();
1800 if ( $name_a == $name_b ) {
1801 return 0;
1802 }
1803 return ( $name_a < $name_b ) ? -1 : 1;
1804 }
1805 return ( $menu_order_a < $menu_order_b ) ? -1 : 1;
1806 } // End _sort_list
1807
1808 private function _edit_files_array( $product_id, $files, $play_src = 0 ) {
1809 $p_files = array();
1810 foreach ( $files as $key => $file ) {
1811 $p_key = $key . '_' . $product_id;
1812 if ( gettype( $file ) == 'object' ) {
1813 $file = (array) $file->get_data();
1814 }
1815 $file['product'] = $product_id;
1816 $file['play_src'] = $play_src;
1817 $p_files[ $p_key ] = $file;
1818 }
1819 return $p_files;
1820 } // end _edit_files_array
1821
1822 private function _get_recursive_product_files( $product, $files_arr ) {
1823 if ( ! is_object( $product ) || ! method_exists( $product, 'get_type' ) ) {
1824 return $files_arr;
1825 }
1826
1827 $product_type = $product->get_type();
1828 $id = $product->get_id();
1829
1830 if ( 'variation' == $product_type ) {
1831 // $_files = $product->get_files();
1832 $_files = $product->get_downloads();
1833 $_files = $this->_edit_files_array( $id, $_files );
1834 $files_arr = array_merge( $files_arr, $_files );
1835 } else {
1836
1837 if ( ! $this->get_product_attr( $id, '_wcmp_enable_player', false ) ) {
1838 return $files_arr;
1839 }
1840
1841 switch ( $product_type ) {
1842 case 'variable':
1843 case 'grouped':
1844 $children = $product->get_children();
1845
1846 foreach ( $children as $key => $child_id ) {
1847 $children[ $key ] = wc_get_product( $child_id );
1848 }
1849
1850 uasort( $children, array( &$this, '_sort_list' ) );
1851
1852 foreach ( $children as $child_obj ) {
1853 $files_arr = $this->_get_recursive_product_files( $child_obj, $files_arr );
1854 }
1855 break;
1856 default:
1857 $_files = $product->get_downloads();
1858 $_files = $this->_edit_files_array( $id, $_files );
1859 $files_arr = array_merge( $files_arr, $_files );
1860 break;
1861 }
1862 }
1863 return $files_arr;
1864 } // End _get_recursive_product_files
1865
1866 private function _get_product_files( $args ) {
1867 if ( empty( $args['product'] ) ) {
1868 return false;
1869 }
1870
1871 $product = $args['product'];
1872 $files = $this->_get_recursive_product_files( $product, array() );
1873
1874 if ( empty( $files ) ) {
1875 return false;
1876 }
1877
1878 $audio_files = array();
1879 foreach ( $files as $index => $file ) {
1880 if ( ! empty( $file['file'] ) && false !== ( $media_type = $this->_is_audio( $file['file'] ) ) ) { // phpcs:ignore Squiz.PHP.DisallowMultipleAssignments
1881 $file['media_type'] = $media_type;
1882
1883 if ( ! empty( $args['file_id'] ) ) {
1884 if ( $args['file_id'] == $index ) {
1885 $audio_files[ $index ] = $file;
1886 return $audio_files;
1887 }
1888 } elseif ( ! empty( $args['first'] ) ) {
1889 $audio_files[ $index ] = $file;
1890 return $audio_files;
1891 } elseif ( ! empty( $args['all'] ) ) {
1892 $audio_files[ $index ] = $file;
1893 }
1894 }
1895 }
1896
1897 return $audio_files;
1898 } // End _get_product_files
1899
1900 private function _demo_file_name( $url ) {
1901 $file_extension = pathinfo( $url, PATHINFO_EXTENSION );
1902 $file_name = md5( $url ) . ( ( ! empty( $file_extension ) && preg_match( '/^[a-z\d]{3,4}$/i', $file_extension ) ) ? '.' . $file_extension : '.mp3' );
1903 return $file_name;
1904 } // End _demo_file_name
1905
1906 private function _valid_demo( $file_path ) {
1907 if ( ! file_exists( $file_path ) || filesize( $file_path ) == 0 ) {
1908 return false;
1909 }
1910 if ( function_exists( 'finfo_open' ) ) {
1911 $finfo = finfo_open( FILEINFO_MIME );
1912 return substr( finfo_file( $finfo, $file_path ), 0, 4 ) !== 'text';
1913 }
1914 return true;
1915 } // End _valid_demo
1916
1917 /**
1918 * Create a temporal file and redirect to the new file
1919 */
1920 private function _output_file( $args ) {
1921 if ( empty( $args['url'] ) ) {
1922 return;
1923 }
1924
1925 $url = $args['url'];
1926 $original_url = $url;
1927
1928 $url = WooCommerceMusicPlayerTools::get_google_drive_download_url( $url );
1929
1930 $url = do_shortcode( $url );
1931
1932 if ( file_exists( $url ) ) {
1933 $url_fixed = $url;
1934 } elseif ( strpos( $url, '//' ) === 0 ) {
1935 $url_fixed = 'http' . ( is_ssl() ? 's:' : ':' ) . $url;
1936 } elseif ( strpos( $url, '/' ) === 0 ) {
1937 $url_fixed = rtrim( WCMP_WEBSITE_URL, '/' ) . $url;
1938 } else {
1939 $url_fixed = $url;
1940 }
1941
1942 $file_name = $this->_demo_file_name( $original_url );
1943 $text = 'The requested URL was not found on this server';
1944 $file_path = $this->_files_directory_path . $file_name;
1945
1946 if ( $this->_valid_demo( $file_path ) ) {
1947 header( 'location: http' . ( ( is_ssl() ) ? 's:' : ':' ) . $this->_files_directory_url . $file_name );
1948 exit;
1949 } else {
1950 try {
1951 $c = false;
1952 if ( ( $path = $this->_is_local( $url_fixed ) ) !== false ) { // phpcs:ignore Squiz.PHP.DisallowMultipleAssignments
1953 $c = copy( $path, $file_path );
1954 } else {
1955 $response = wp_remote_get(
1956 $url_fixed,
1957 array(
1958 'timeout' => WCMP_REMOTE_TIMEOUT,
1959 'stream' => true,
1960 'filename' => $file_path,
1961 )
1962 );
1963 if ( ! is_wp_error( $response ) && 200 == $response['response']['code'] ) {
1964 $c = true;
1965 }
1966 }
1967
1968 if ( true === $c ) {
1969
1970 if ( ! function_exists( 'mime_content_type' ) || false === ( $mime_type = mime_content_type( $file_path ) ) ) $mime_type = 'audio/mpeg';
1971
1972 if ( ! headers_sent() ) {
1973 if ( ! $this->get_global_attr( '_wcmp_disable_302', 0 ) ) {
1974 header( "location: " . $this->_files_directory_url . $file_name, true, 302 );
1975 exit;
1976 }
1977
1978 header( "Content-Type: " . $mime_type );
1979 header( "Content-length: " . filesize( $file_path ) );
1980 header( 'Content-Disposition: filename="' . $file_name . '"' );
1981 header( "Accept-Ranges: " . ( stripos( $mime_type, 'wav' ) ? 'none' : 'bytes' ) );
1982 header( "Content-Transfer-Encoding: binary" );
1983 }
1984
1985 readfile($file_path);
1986 exit;
1987 }
1988 } catch ( Exception $err ) {
1989 error_log( $err->getMessage() );
1990 }
1991 $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.';
1992 }
1993 $this->_print_page_not_found( $text );
1994 } // End _output_file
1995
1996 /**
1997 * Add the class name: product-<product id> to cover images associated to the products.
1998 *
1999 * @param $html, a html piece of code that includes the <img> tag.
2000 * @param $product, the product object.
2001 */
2002 private function _add_class( $html, $product ) {
2003 if ( preg_match( '/<img\b[^>]*>/i', $html, $image ) ) {
2004 $id = $product->get_id();
2005 if ( $GLOBALS['WooCommerceMusicPlayer']->get_product_attr( $id, '_wcmp_on_cover', 0 ) ) {
2006 if ( preg_match( '/\bclass\s*=/i', $image[0] ) ) {
2007 $tmp_image = preg_replace( '/\bclass\s*=\s*[\'"]/i', "$0product-$id ", $image[0] );
2008 } else {
2009 $tmp_image = preg_replace( '/<img\b/i', "<img $0 class=\"product-$id\" ", $image[0] );
2010 }
2011
2012 $html = str_replace( $image[0], $tmp_image, $html );
2013 }
2014 }
2015
2016 return $html;
2017 } // End _add_class
2018
2019 /**
2020 * Print not found page if file it is not accessible
2021 */
2022 private function _print_page_not_found( $text = 'The requested URL was not found on this server' ) {
2023 header( 'Status: 404 Not Found' );
2024 echo '<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
2025 <HTML><HEAD>
2026 <TITLE>404 Not Found</TITLE>
2027 </HEAD><BODY>
2028 <H1>Not Found</H1>
2029 <P>' . esc_html( $text ) . '</P>
2030 </BODY></HTML>
2031 ';
2032 } // End _print_page_not_found
2033
2034 private function _is_local( $url ) {
2035 $file_path = false;
2036 if ( file_exists( $url ) ) {
2037 $file_path = $url;
2038 }
2039
2040 if ( false === $file_path ) {
2041 $attachment_id = attachment_url_to_postid( $url );
2042 if ( $attachment_id ) {
2043 $attachment_path = get_attached_file( $attachment_id );
2044 if ( $attachment_path && file_exists( $attachment_path ) ) {
2045 $file_path = $attachment_path;
2046 }
2047 }
2048 }
2049
2050 if ( false === $file_path && defined( 'ABSPATH' ) ) {
2051 $path_component = parse_url( $url, PHP_URL_PATH );
2052 $path = rtrim( ABSPATH, '/' ) . '/' . ltrim( $path_component, '/' );
2053 if ( file_exists( $path ) ) {
2054 $file_path = $path;
2055 }
2056
2057 if ( false === $file_path ) {
2058 $site_url = get_site_url( get_current_blog_id() );
2059 $file_path = str_ireplace( $site_url . '/', ABSPATH, $url );
2060 if ( ! file_exists( $file_path ) ) {
2061 $file_path = false;
2062 }
2063 }
2064 }
2065
2066 return apply_filters( 'wcmp_is_local', $file_path, $url );
2067 } // End _is_local
2068
2069 private function _tracking_play_event( $product_id, $file_url ) {
2070 $_wcmp_analytics_integration = $this->get_global_attr( '_wcmp_analytics_integration', 'ua' );
2071 $_wcmp_analytics_property = trim( $this->get_global_attr( '_wcmp_analytics_property', '' ) );
2072 $_wcmp_analytics_api_secret = trim( $this->get_global_attr( '_wcmp_analytics_api_secret', '' ) );
2073 if ( ! empty( $_wcmp_analytics_property ) ) {
2074 $cid = isset( $_SERVER['REMOTE_ADDR'] ) ? sanitize_text_field( wp_unslash( $_SERVER['REMOTE_ADDR'] ) ) : 555;
2075 try {
2076 if ( isset( $_COOKIE['_ga'] ) ) {
2077 $cid_parts = explode( '.', sanitize_text_field( wp_unslash( $_COOKIE['_ga'] ) ), 3 );
2078 $cid = $cid_parts[2];
2079 }
2080 } catch ( Exception $err ) {
2081 error_log( $err->getMessage() );
2082 }
2083
2084 if ( 'ua' == $_wcmp_analytics_integration ) {
2085 $_response = wp_remote_post(
2086 'http://www.google-analytics.com/collect',
2087 array(
2088 'body' => array(
2089 'v' => 1,
2090 'tid' => $_wcmp_analytics_property,
2091 'cid' => $cid,
2092 't' => 'event',
2093 'ec' => 'Music Player for WooCommerce',
2094 'ea' => 'play',
2095 'el' => $file_url,
2096 'ev' => $product_id,
2097 ),
2098 )
2099 );
2100 } else {
2101 $_response = wp_remote_post(
2102 'https://www.google-analytics.com/mp/collect?api_secret=' . $_wcmp_analytics_api_secret . '&measurement_id=' . $_wcmp_analytics_property,
2103 array(
2104 'sslverify' => true,
2105 'headers' => array(
2106 'Content-Type' => 'application/json',
2107 ),
2108 'body' => json_encode(
2109 array(
2110 'client_id' => $cid,
2111 'events' => array(
2112 array(
2113 'name' => 'play',
2114 'params' => array(
2115 'event_category' => 'Music Player for WooCommerce',
2116 'event_label' => $file_url,
2117 'event_value' => $product_id,
2118 ),
2119 ),
2120 ),
2121 )
2122 ),
2123 )
2124 );
2125 }
2126
2127 if ( is_wp_error( $_response ) ) {
2128 error_log( $_response->get_error_message() );
2129 }
2130 }
2131 } // _tracking_play_event
2132
2133 public static function troubleshoot( $option ) {
2134 if ( ! is_admin() ) {
2135 // Solves a conflict caused by the "Speed Booster Pack" plugin
2136 if ( is_array( $option ) && isset( $option['jquery_to_footer'] ) ) {
2137 unset( $option['jquery_to_footer'] );
2138 }
2139 }
2140 return $option;
2141 } // End troubleshoot
2142 } // End Class WooCommerceMusicPlayer
2143
2144 $GLOBALS['WooCommerceMusicPlayer'] = new WooCommerceMusicPlayer();
2145 }
2146