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