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