Music Player for WooCommerce - Version 1.0.173

Version Description

  • Improves the plugin's code and its security.
Download this release

Release Info

Developer codepeople
Plugin Icon 128x128 Music Player for WooCommerce
Version 1.0.173
Comparing to
See all releases

Code changes from version 1.0.171 to 1.0.173

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