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