PluginProbe ʕ •ᴥ•ʔ
Music Player for WooCommerce / 1.0.184
Music Player for WooCommerce v1.0.184
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
1681 lines
1 <?php
2 /*
3 Plugin Name: Music Player for WooCommerce
4 Plugin URI: https://wcmp.dwbooster.com
5 Version: 1.0.184
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.184' );
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 $player = '';
850 ob_start();
851 $this->include_main_player( $product );
852 $player .= ob_get_contents();
853 ob_end_clean();
854 return $player . $title;
855 } // End woocommerce_product_title
856
857 /**
858 * Load the additional attributes to select the player layout
859 */
860 public function woocommerce_player_settings() {
861 include_once 'views/player_options.php';
862 } // End woocommerce_player_settings
863
864 public function get_player(
865 $audio_url,
866 $args = array()
867 ) {
868 $default_args = array(
869 'media_type' => 'mp3',
870 'player_style' => WCMP_DEFAULT_PLAYER_LAYOUT,
871 'player_controls' => WCMP_DEFAULT_PLAYER_CONTROLS,
872 'duration' => false,
873 'volume' => 1,
874 );
875
876 $args = array_merge( $default_args, $args );
877 $id = ( ! empty( $args['id'] ) ) ? 'id="' . esc_attr( $args['id'] ) . '"' : '';
878
879 $preload = ( ! empty( $args['preload'] ) ) ? $args['preload'] : $GLOBALS['WooCommerceMusicPlayer']->get_global_attr(
880 '_wcmp_preload',
881 // This option is only for compatibility with versions previous to 1.0.28
882 $GLOBALS['WooCommerceMusicPlayer']->get_global_attr( 'preload', 'none' )
883 );
884 $preload = apply_filters( 'wcmp_preload', $preload, $audio_url );
885
886 return '<audio ' . (
887 (
888 isset( $args['volume'] ) &&
889 is_numeric( $args['volume'] ) &&
890 0 <= $args['volume'] * 1 &&
891 $args['volume'] * 1 <= 1
892 ) ? 'volume="' . esc_attr( $args['volume'] ) . '"' : ''
893 ) . ' ' . $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>';
894
895 } // End get_player
896
897 public function get_product_files( $id ) {
898 $product = wc_get_product( $id );
899 if ( ! empty( $product ) ) {
900 return $this->_get_product_files(
901 array(
902 'product' => $product,
903 'all' => 1,
904 )
905 );
906 }
907 return array();
908 }
909
910 public function generate_audio_url( $product_id, $file_id, $file_data = array() ) {
911 return $this->_generate_audio_url( $product_id, $file_id, $file_data );
912 }
913
914 public function include_main_player_filter( $value, $id ) {
915 if ( $this->_force_hook_title ) {
916 try {
917 if ( ( wp_doing_ajax() || ! is_admin() ) && ( ! function_exists( 'is_product' ) || ! is_product() ) && ! is_cart() && ! is_page( 'cart' ) && ! is_checkout() && is_int( $id ) ) {
918 $p = wc_get_product( $id );
919 if ( ! empty( $p ) ) {
920 add_filter( 'esc_html', array( &$this, 'esc_html' ), 10, 2 );
921
922 $player = '';
923 ob_start();
924 $this->include_main_player( $p );
925 $player = ob_get_contents();
926 ob_end_clean();
927 $value = $player . $value;
928 }
929 }
930 } catch ( Exception $err ) {
931 error_log( $err->getMessage() );
932 }
933 }
934 return $value;
935 }
936
937 public function include_main_player( $product = '', $_echo = true ) {
938 $output = '';
939 if ( ! $this->_insert_player ) {
940 return $output;
941 }
942 if ( is_numeric( $product ) ) {
943 $product = wc_get_product( $product );
944 }
945 if ( ! is_object( $product ) ) {
946 $product = wc_get_product();
947 }
948 $files = $this->_get_product_files(
949 array(
950 'product' => $product,
951 'first' => true,
952 )
953 );
954 if ( ! empty( $files ) ) {
955 $id = $product->get_id();
956
957 $show_in = $this->get_product_attr( $id, '_wcmp_show_in', 'all' );
958 if (
959 ( 'single' == $show_in && ( ! function_exists( 'is_product' ) || ! is_product() ) ) ||
960 ( 'multiple' == $show_in && ( function_exists( 'is_product' ) && is_product() ) && get_queried_object_id() == $id )
961 ) {
962 return $output;
963 }
964 $preload = $this->get_product_attr( $id, '_wcmp_preload', '' );
965 $this->enqueue_resources();
966
967 $player_style = $this->get_product_attr( $id, '_wcmp_player_layout', WCMP_DEFAULT_PLAYER_LAYOUT );
968 $player_controls = ( $this->get_product_attr( $id, '_wcmp_player_controls', WCMP_DEFAULT_PLAYER_CONTROLS ) != 'all' ) ? 'track' : '';
969 $volume = @floatval( $this->get_product_attr( $id, '_wcmp_player_volume', WCMP_DEFAULT_PLAYER_VOLUME ) );
970
971 $file = reset( $files );
972 $index = key( $files );
973 $audio_url = $this->_generate_audio_url( $id, $index, $file );
974 $duration = $this->_get_duration_by_url( $file['file'] );
975 $audio_tag = apply_filters(
976 'wcmp_audio_tag',
977 $this->get_player(
978 $audio_url,
979 array(
980 'player_controls' => $player_controls,
981 'player_style' => $player_style,
982 'media_type' => $file['media_type'],
983 'duration' => $duration,
984 'preload' => $preload,
985 'volume' => $volume,
986 )
987 ),
988 $id,
989 $index,
990 $audio_url
991 );
992
993 do_action( 'wcmp_before_player_shop_page', $id );
994
995 $output = '<div class="wcmp-player-container product-' . esc_attr( $file['product'] ) . '">' . $audio_tag . '</div>';
996 if ( $_echo ) {
997 print $output; // phpcs:ignore WordPress.Security.EscapeOutput
998 }
999
1000 do_action( 'wcmp_after_player_shop_page', $id );
1001
1002 return $output; // phpcs:ignore WordPress.Security.EscapeOutput
1003 }
1004 } // End include_main_player
1005
1006 public function include_all_players( $product = '' ) {
1007 if ( ! $this->_insert_player ) {
1008 return;
1009 }
1010 if ( ! is_object( $product ) ) {
1011 $product = wc_get_product();
1012 }
1013 $files = $this->_get_product_files(
1014 array(
1015 'product' => $product,
1016 'all' => true,
1017 )
1018 );
1019 if ( ! empty( $files ) ) {
1020 $id = $product->get_id();
1021
1022 $show_in = $this->get_product_attr( $id, '_wcmp_show_in', 'all' );
1023 if (
1024 ( 'single' == $show_in && ! is_singular() ) ||
1025 ( 'multiple' == $show_in && is_singular() )
1026 ) {
1027 return;
1028 }
1029 $preload = $this->get_product_attr( $id, '_wcmp_preload', '' );
1030 $this->enqueue_resources();
1031 $player_style = $this->get_product_attr( $id, '_wcmp_player_layout', WCMP_DEFAULT_PLAYER_LAYOUT );
1032 $volume = @floatval( $this->get_product_attr( $id, '_wcmp_player_volume', WCMP_DEFAULT_PLAYER_VOLUME ) );
1033 $player_controls = $this->get_product_attr( $id, '_wcmp_player_controls', WCMP_DEFAULT_PLAYER_CONTROLS );
1034 $player_title = intval( $this->get_product_attr( $id, '_wcmp_player_title', WCMP_DEFAULT_PlAYER_TITLE ) );
1035 $merge_grouped = intval( $this->get_product_attr( $id, '_wcmp_merge_in_grouped', 0 ) );
1036 $merge_grouped_clss = ( $merge_grouped ) ? 'merge_in_grouped_products' : '';
1037
1038 $counter = count( $files );
1039
1040 do_action( 'wcmp_before_players_product_page', $id );
1041 if ( 1 == $counter ) {
1042 $player_controls = ( 'button' == $player_controls ) ? 'track' : '';
1043 $file = reset( $files );
1044 $index = key( $files );
1045 $audio_url = $this->_generate_audio_url( $id, $index, $file );
1046 $duration = $this->_get_duration_by_url( $file['file'] );
1047 $audio_tag = apply_filters(
1048 'wcmp_audio_tag',
1049 $this->get_player(
1050 $audio_url,
1051 array(
1052 'player_controls' => $player_controls,
1053 'player_style' => $player_style,
1054 'media_type' => $file['media_type'],
1055 'duration' => $duration,
1056 'preload' => $preload,
1057 'volume' => $volume,
1058 )
1059 ),
1060 $id,
1061 $index,
1062 $audio_url
1063 );
1064 $title = esc_html( ( $player_title ) ? apply_filters( 'wcmp_file_name', $file['name'], $id, $index ) : '' );
1065 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
1066 } elseif ( $counter > 1 ) {
1067 $before = '<table class="wcmp-player-list ' . $merge_grouped_clss . '">';
1068 $after = '';
1069 foreach ( $files as $index => $file ) {
1070 $evenOdd = ( 1 == $counter % 2 ) ? 'wcmp-odd-row' : 'wcmp-even-row';
1071 $counter--;
1072 $audio_url = $this->_generate_audio_url( $id, $index, $file );
1073 $duration = $this->_get_duration_by_url( $file['file'] );
1074 $audio_tag = apply_filters(
1075 'wcmp_audio_tag',
1076 $this->get_player(
1077 $audio_url,
1078 array(
1079 'player_style' => $player_style,
1080 'player_controls' => ( 'all' != $player_controls ) ? 'track' : '',
1081 'media_type' => $file['media_type'],
1082 'duration' => $duration,
1083 'preload' => $preload,
1084 'volume' => $volume,
1085 )
1086 ),
1087 $id,
1088 $index,
1089 $audio_url
1090 );
1091 $title = esc_html( ( $player_title ) ? apply_filters( 'wcmp_file_name', $file['name'], $id, $index ) : '' );
1092
1093 print $before; // phpcs:ignore WordPress.Security.EscapeOutput
1094 $before = '';
1095 $after = '</table>';
1096 if ( 'all' != $player_controls ) {
1097 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
1098 } else {
1099 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
1100 }
1101 }
1102 print $after; // phpcs:ignore WordPress.Security.EscapeOutput
1103 }
1104 do_action( 'wcmp_after_players_product_page', $id );
1105 }
1106 } // End include_all_players
1107
1108 public function player_in_cart( $cart_item, $cart_item_key ) {
1109 $product = wc_get_product( $cart_item['product_id'] );
1110 $this->include_all_players( $product );
1111 } // player_in_cart
1112
1113 // Integration with woocommerce-product-table by barn2media
1114 public function product_table_data_name( $name, $product ) {
1115 ob_start();
1116 $this->include_main_player( $product );
1117 $player = ob_get_contents();
1118 ob_end_clean();
1119 $player = str_replace( '<div ', '<div style="display:inline-block" ', $player );
1120 return $player . $name;
1121 } // product_table_data_name
1122
1123 public function add_data_product( $player, $product_id, $index, $url ) {
1124 $player = preg_replace( '/<audio\b/i', '<audio controlslist="nodownload" data-product="' . esc_attr( $product_id ) . '" ', $player );
1125 return $player;
1126 } // End add_data_product
1127
1128 public function add_class_attachment( $html, $product, $size, $attr, $placeholder, $image ) {
1129 $id = $product->get_id();
1130 $html = $this->_add_class( $html, $product );
1131 return $html;
1132 } // End add_class_attachment
1133
1134 public function add_class_single_product_image( $html, $post_thumbnail_id ) {
1135 global $product;
1136
1137 if ( ! empty( $product ) ) {
1138 $html = $this->_add_class( $html, $product );
1139 }
1140 return $html;
1141 } // add_class_single_product_image
1142
1143 // ******************** PRIVATE METHODS ************************
1144
1145 private function _init_force_in_title() {
1146 $this->_force_hook_title = $this->get_global_attr( '_wcmp_main_player_hook_title', 1 );
1147
1148 // Integration with "WOOF – Products Filter for WooCommerce" by realmag777
1149 if ( isset( $_REQUEST['action'] ) && 'woof_draw_products' == $_REQUEST['action'] ) {
1150 $this->_force_hook_title = 1;
1151 }
1152
1153 } // End _init_force_in_title
1154
1155 private function _get_post_types( $mysql_in = false ) {
1156 $post_types = array( 'product' );
1157 if ( ! empty( $GLOBALS['wcmp_post_types'] ) && is_array( $GLOBALS['wcmp_post_types'] ) ) {
1158 $post_types = $GLOBALS['wcmp_post_types'];
1159 }
1160 if ( $mysql_in ) {
1161 return '"' . implode( '","', $post_types ) . '"';
1162 }
1163 return $post_types;
1164 } // End _get_post_types
1165
1166 private function _load_addons() {
1167 $path = __DIR__ . '/addons';
1168 $wcmp = $this;
1169
1170 if ( file_exists( $path ) ) {
1171 $addons = dir( $path );
1172 while ( false !== ( $entry = $addons->read() ) ) {
1173 if ( strlen( $entry ) > 3 && strtolower( pathinfo( $entry, PATHINFO_EXTENSION ) ) == 'php' ) {
1174 include_once $addons->path . '/' . $entry;
1175 }
1176 }
1177 }
1178 } // End _load_addons
1179
1180 private function _preview() {
1181 $user = wp_get_current_user();
1182 $allowed_roles = array( 'editor', 'administrator', 'author' );
1183
1184 if ( array_intersect( $allowed_roles, $user->roles ) ) {
1185 if ( ! empty( $_REQUEST['wcmp-preview'] ) ) {
1186 // Sanitizing variable
1187 $preview = sanitize_text_field( wp_unslash( $_REQUEST['wcmp-preview'] ) );
1188
1189 // Remove every shortcode that is not in the plugin
1190 remove_all_shortcodes();
1191 add_shortcode( 'wcmp-playlist', array( &$this, 'replace_playlist_shortcode' ) );
1192
1193 if ( has_shortcode( $preview, 'wcmp-playlist' ) ) {
1194 print '<!DOCTYPE html>';
1195 $if_empty = __( 'There are no products that satisfy the block\'s settings', 'music-player-for-woocommerce' );
1196 wp_enqueue_script( 'jquery' );
1197 $output = do_shortcode( $preview );
1198 if ( preg_match( '/^\s*$/', $output ) ) {
1199 $output = '<div>' . $if_empty . '</div>';
1200 }
1201
1202 // Deregister all scripts and styles for loading only the plugin styles.
1203 global $wp_styles, $wp_scripts;
1204 if ( ! empty( $wp_scripts ) ) {
1205 $wp_scripts->reset();
1206 }
1207 $this->enqueue_resources();
1208 if ( ! empty( $wp_styles ) ) {
1209 $wp_styles->do_items();
1210 }
1211 if ( ! empty( $wp_scripts ) ) {
1212 $wp_scripts->do_items();
1213 }
1214
1215 print '<div class="wcmp-preview-container">' . $output . '</div>'; // phpcs:ignore WordPress.Security.EscapeOutput
1216 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>';
1217 exit;
1218 }
1219 }
1220 }
1221 } // End _preview
1222
1223 private function _createDir() {
1224 // Generate upload dir
1225 $_files_directory = wp_upload_dir();
1226 $this->_files_directory_path = rtrim( $_files_directory['basedir'], '/' ) . '/wcmp/';
1227 $this->_files_directory_url = rtrim( $_files_directory['baseurl'], '/' ) . '/wcmp/';
1228 $this->_files_directory_url = preg_replace( '/^http(s)?:\/\//', '//', $this->_files_directory_url );
1229 if ( ! file_exists( $this->_files_directory_path ) ) {
1230 @mkdir( $this->_files_directory_path, 0755 );
1231 }
1232 } // End _createDir
1233
1234 private function _deleteDir( $dirPath ) {
1235 try {
1236 if ( ! is_dir( $dirPath ) ) {
1237 return;
1238 }
1239 if ( substr( $dirPath, strlen( $dirPath ) - 1, 1 ) != '/' ) {
1240 $dirPath .= '/';
1241 }
1242 $files = glob( $dirPath . '*', GLOB_MARK );
1243 foreach ( $files as $file ) {
1244 if ( is_dir( $file ) ) {
1245 $this->_deleteDir( $file );
1246 } else {
1247 unlink( $file );
1248 }
1249 }
1250 rmdir( $dirPath );
1251 } catch ( Exception $err ) {
1252 return;
1253 }
1254 } // End _deleteDir
1255
1256 private function _get_duration_by_url( $url ) {
1257 global $wpdb;
1258 try {
1259 $attachment = $wpdb->get_col( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE guid RLIKE %s;", $url ) );
1260 if ( empty( $attachment ) ) {
1261 $uploads_dir = wp_upload_dir();
1262 $uploads_url = $uploads_dir['baseurl'];
1263 $parsed_url = explode( parse_url( $uploads_url, PHP_URL_PATH ), $url );
1264 $this_host = str_ireplace( 'www.', '', parse_url( home_url(), PHP_URL_HOST ) );
1265 $file_host = str_ireplace( 'www.', '', parse_url( $url, PHP_URL_HOST ) );
1266 if ( ! isset( $parsed_url[1] ) || empty( $parsed_url[1] ) || ( $this_host != $file_host ) ) {
1267 return false;
1268 }
1269 $file = trim( $parsed_url[1], '/' );
1270 $attachment = $wpdb->get_col( $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key='_wp_attached_file' AND meta_value RLIKE %s;", $file ) );
1271 }
1272 if ( ! empty( $attachment ) ) {
1273 $metadata = wp_get_attachment_metadata( $attachment[0] );
1274 if ( false !== $metadata && ! empty( $metadata['length_formatted'] ) ) {
1275 return $metadata['length_formatted'];
1276 }
1277 }
1278 } catch ( Exception $err ) {
1279 error_log( $err->getMessage() );
1280 }
1281 return false;
1282 } // End _get_duration_by_url
1283
1284 private function _generate_audio_url( $product_id, $file_index, $file_data = array() ) {
1285 if ( ! empty( $file_data['file'] ) ) {
1286 $file_url = $file_data['file'];
1287 if ( ! empty( $file_data['play_src'] ) || $this->_is_playlist( $file_url ) ) {
1288 return $file_url; // Play src audio file, without copying or truncate it.
1289 }
1290
1291 // If the playback of music are tracked with Google Analytics, should not be loaded directly the audio files.
1292 $_wcmp_analytics_property = trim( $this->get_global_attr( '_wcmp_analytics_property', '' ) );
1293 if ( '' == $_wcmp_analytics_property ) {
1294 $file_name = $this->_demo_file_name( $file_url );
1295
1296 $file_path = $this->_files_directory_path . $file_name;
1297
1298 if ( $this->_valid_demo( $file_path ) ) {
1299 return 'http' . ( ( is_ssl() ) ? 's:' : ':' ) . $this->_files_directory_url . $file_name;
1300 }
1301 }
1302 }
1303 $url = isset( $_SERVER['REQUEST_URI'] ) ? esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '';
1304 $url .= ( ( strpos( $url, '?' ) === false ) ? '?' : '&' ) . 'wcmp-action=play&wcmp-product=' . $product_id . '&wcmp-file=' . $file_index;
1305 return $url;
1306 } // End _generate_audio_url
1307
1308 private function _delete_truncated_files( $product_id ) {
1309 $files_arr = get_post_meta( $product_id, '_downloadable_files', true );
1310 if ( ! empty( $files_arr ) && is_array( $files_arr ) ) {
1311 foreach ( $files_arr as $file ) {
1312 if ( is_array( $file ) && ! empty( $file['file'] ) ) {
1313 $ext = pathinfo( $file['file'], PATHINFO_EXTENSION );
1314 $file_name = md5( $file['file'] ) . ( ( ! empty( $ext ) ) ? '.' . $ext : '' );
1315 @unlink( $this->_files_directory_path . $file_name );
1316 }
1317 }
1318 }
1319
1320 } // End _delete_truncated_files
1321
1322 /**
1323 * Check if the file is an m3u or m3u8 playlist
1324 */
1325 private function _is_playlist( $file_path ) {
1326 return preg_match( '/\.(m3u|m3u8)$/i', $file_path );
1327 } // End _is_playlist
1328
1329 /**
1330 * Check if the file is an audio file and return its type or false
1331 */
1332 private function _is_audio( $file_path ) {
1333 if ( preg_match( '/\.(mp3|ogg|oga|wav|wma|mp4)$/i', $file_path, $match ) ) {
1334 return $match[1];
1335 }
1336 if ( preg_match( '/\.m4a$/i', $file_path ) ) {
1337 return 'mp4';
1338 }
1339 if ( $this->_is_playlist( $file_path ) ) {
1340 return 'hls';
1341 }
1342
1343 // From troubleshoot
1344 $extension = pathinfo( $file_path, PATHINFO_EXTENSION );
1345 $troubleshoot_default_extension = $GLOBALS['WooCommerceMusicPlayer']->get_global_attr( '_wcmp_default_extension', false );
1346 if ( ( empty( $extension ) || ! preg_match( '/^[a-z\d]{3,4}$/i', $extension ) ) && $troubleshoot_default_extension ) {
1347 return 'mp3';
1348 }
1349
1350 return false;
1351 } // End _is_audio
1352
1353 private function _sort_list( $product_a, $product_b ) {
1354 if (
1355 ! is_object( $product_a ) || ! method_exists( $product_a, 'get_menu_order' ) ||
1356 ! is_object( $product_b ) || ! method_exists( $product_b, 'get_menu_order' )
1357 ) {
1358 return 0;
1359 }
1360
1361 $menu_order_a = $product_a->get_menu_order();
1362 $menu_order_b = $product_b->get_menu_order();
1363 if ( $menu_order_a == $menu_order_b ) {
1364 if (
1365 ! method_exists( $product_a, 'get_name' ) ||
1366 ! method_exists( $product_b, 'get_name' )
1367 ) {
1368 return 0;
1369 }
1370
1371 $name_a = $product_a->get_name();
1372 $name_b = $product_b->get_name();
1373 if ( $name_a == $name_b ) {
1374 return 0;
1375 }
1376 return ( $name_a < $name_b ) ? -1 : 1;
1377 }
1378 return ( $menu_order_a < $menu_order_b ) ? -1 : 1;
1379 } // End _sort_list
1380
1381 private function _edit_files_array( $product_id, $files, $play_src = 0 ) {
1382 $p_files = array();
1383 foreach ( $files as $key => $file ) {
1384 $p_key = $key . '_' . $product_id;
1385 if ( gettype( $file ) == 'object' ) {
1386 $file = (array) $file->get_data();
1387 }
1388 $file['product'] = $product_id;
1389 $file['play_src'] = $play_src;
1390 $p_files[ $p_key ] = $file;
1391 }
1392 return $p_files;
1393 } // end _edit_files_array
1394
1395 private function _get_recursive_product_files( $product, $files_arr ) {
1396 if ( ! is_object( $product ) || ! method_exists( $product, 'get_type' ) ) {
1397 return $files_arr;
1398 }
1399
1400 $product_type = $product->get_type();
1401 $id = $product->get_id();
1402
1403 if ( 'variation' == $product_type ) {
1404 // $_files = $product->get_files();
1405 $_files = $product->get_downloads();
1406 $_files = $this->_edit_files_array( $id, $_files );
1407 $files_arr = array_merge( $files_arr, $_files );
1408 } else {
1409
1410 if ( ! $this->get_product_attr( $id, '_wcmp_enable_player', false ) ) {
1411 return $files_arr;
1412 }
1413
1414 switch ( $product_type ) {
1415 case 'variable':
1416 case 'grouped':
1417 $children = $product->get_children();
1418
1419 foreach ( $children as $key => $child_id ) {
1420 $children[ $key ] = wc_get_product( $child_id );
1421 }
1422
1423 uasort( $children, array( &$this, '_sort_list' ) );
1424
1425 foreach ( $children as $child_obj ) {
1426 $files_arr = $this->_get_recursive_product_files( $child_obj, $files_arr );
1427 }
1428 break;
1429 default:
1430 $_files = $product->get_downloads();
1431 $_files = $this->_edit_files_array( $id, $_files );
1432 $files_arr = array_merge( $files_arr, $_files );
1433 break;
1434 }
1435 }
1436 return $files_arr;
1437 } // End _get_recursive_product_files
1438
1439 private function _get_product_files( $args ) {
1440 if ( empty( $args['product'] ) ) {
1441 return false;
1442 }
1443
1444 $product = $args['product'];
1445 $files = $this->_get_recursive_product_files( $product, array() );
1446
1447 if ( empty( $files ) ) {
1448 return false;
1449 }
1450
1451 $audio_files = array();
1452 foreach ( $files as $index => $file ) {
1453 if ( ! empty( $file['file'] ) && false !== ( $media_type = $this->_is_audio( $file['file'] ) ) ) { // phpcs:ignore Squiz.PHP.DisallowMultipleAssignments
1454 $file['media_type'] = $media_type;
1455
1456 if ( ! empty( $args['file_id'] ) ) {
1457 if ( $args['file_id'] == $index ) {
1458 $audio_files[ $index ] = $file;
1459 return $audio_files;
1460 }
1461 } elseif ( ! empty( $args['first'] ) ) {
1462 $audio_files[ $index ] = $file;
1463 return $audio_files;
1464 } elseif ( ! empty( $args['all'] ) ) {
1465 $audio_files[ $index ] = $file;
1466 }
1467 }
1468 }
1469
1470 return $audio_files;
1471 } // End _get_product_files
1472
1473 private function _demo_file_name( $url ) {
1474 $file_extension = pathinfo( $url, PATHINFO_EXTENSION );
1475 $file_name = md5( $url ) . ( ( ! empty( $file_extension ) && preg_match( '/^[a-z\d]{3,4}$/i', $file_extension ) ) ? '.' . $file_extension : '.mp3' );
1476 return $file_name;
1477 } // End _demo_file_name
1478
1479 private function _valid_demo( $file_path ) {
1480 if ( ! file_exists( $file_path ) || filesize( $file_path ) == 0 ) {
1481 return false;
1482 }
1483 if ( function_exists( 'finfo_open' ) ) {
1484 $finfo = finfo_open( FILEINFO_MIME );
1485 return substr( finfo_file( $finfo, $file_path ), 0, 4 ) !== 'text';
1486 }
1487 return true;
1488 } // End _valid_demo
1489
1490 /**
1491 * Create a temporal file and redirect to the new file
1492 */
1493 private function _output_file( $args ) {
1494 if ( empty( $args['url'] ) ) {
1495 return;
1496 }
1497 $url = $args['url'];
1498 $url = do_shortcode( $url );
1499
1500 if ( file_exists( $url ) ) {
1501 $url_fixed = $url;
1502 } elseif ( strpos( $url, '//' ) === 0 ) {
1503 $url_fixed = 'http' . ( is_ssl() ? 's:' : ':' ) . $url;
1504 } elseif ( strpos( $url, '/' ) === 0 ) {
1505 $url_fixed = rtrim( WCMP_WEBSITE_URL, '/' ) . $url;
1506 } else {
1507 $url_fixed = $url;
1508 }
1509
1510 $file_name = $this->_demo_file_name( $url );
1511 $text = 'The requested URL was not found on this server';
1512 $file_path = $this->_files_directory_path . $file_name;
1513
1514 if ( $this->_valid_demo( $file_path ) ) {
1515 header( 'location: http' . ( ( is_ssl() ) ? 's:' : ':' ) . $this->_files_directory_url . $file_name );
1516 exit;
1517 } else {
1518 try {
1519 $c = false;
1520 if ( ( $path = $this->_is_local( $url_fixed ) ) !== false ) { // phpcs:ignore Squiz.PHP.DisallowMultipleAssignments
1521 $c = copy( $path, $file_path );
1522 } else {
1523 $response = wp_remote_get(
1524 $url_fixed,
1525 array(
1526 'timeout' => WCMP_REMOTE_TIMEOUT,
1527 'stream' => true,
1528 'filename' => $file_path,
1529 )
1530 );
1531 if ( ! is_wp_error( $response ) && 200 == $response['response']['code'] ) {
1532 $c = true;
1533 }
1534 }
1535
1536 if ( true === $c ) {
1537 header( 'Content-Type: audio/mpeg' );
1538 readfile($file_path);
1539 // header( 'location: http' . ( ( is_ssl() ) ? 's:' : ':' ) . $this->_files_directory_url . $file_name );
1540 exit;
1541 }
1542 } catch ( Exception $err ) {
1543 error_log( $err->getMessage() );
1544 }
1545 $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.';
1546 }
1547 $this->_print_page_not_found( $text );
1548 } // End _output_file
1549
1550 /**
1551 * Add the class name: product-<product id> to cover images associated to the products.
1552 *
1553 * @param $html, a html piece of code that includes the <img> tag.
1554 * @param $product, the product object.
1555 */
1556 private function _add_class( $html, $product ) {
1557 if ( preg_match( '/<img\b[^>]*>/i', $html, $image ) ) {
1558 $id = $product->get_id();
1559 if ( $GLOBALS['WooCommerceMusicPlayer']->get_product_attr( $id, '_wcmp_on_cover', 0 ) ) {
1560 if ( preg_match( '/\bclass\s*=/i', $image[0] ) ) {
1561 $tmp_image = preg_replace( '/\bclass\s*=\s*[\'"]/i', "$0product-$id ", $image[0] );
1562 } else {
1563 $tmp_image = preg_replace( '/<img\b/i', "<img $0 class=\"product-$id\" ", $image[0] );
1564 }
1565
1566 $html = str_replace( $image[0], $tmp_image, $html );
1567 }
1568 }
1569
1570 return $html;
1571 } // End _add_class
1572
1573 /**
1574 * Print not found page if file it is not accessible
1575 */
1576 private function _print_page_not_found( $text = 'The requested URL was not found on this server' ) {
1577 header( 'Status: 404 Not Found' );
1578 echo '<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
1579 <HTML><HEAD>
1580 <TITLE>404 Not Found</TITLE>
1581 </HEAD><BODY>
1582 <H1>Not Found</H1>
1583 <P>' . esc_html( $text ) . '</P>
1584 </BODY></HTML>
1585 ';
1586 } // End _print_page_not_found
1587
1588 private function _is_local( $url ) {
1589 $file_path = false;
1590 if ( file_exists( $url ) ) {
1591 $file_path = $url;
1592 } else {
1593 $attachment_id = attachment_url_to_postid( $url );
1594 if ( $attachment_id ) {
1595 $attachment_path = get_attached_file( $attachment_id );
1596 if ( $attachment_path && file_exists( $attachment_path ) ) {
1597 $file_path = $attachment_path;
1598 }
1599 }
1600 }
1601 return apply_filters( 'wcmp_is_local', $file_path, $url );
1602 } // End _is_local
1603
1604 private function _tracking_play_event( $product_id, $file_url ) {
1605 $_wcmp_analytics_integration = $this->get_global_attr( '_wcmp_analytics_integration', 'ua' );
1606 $_wcmp_analytics_property = trim( $this->get_global_attr( '_wcmp_analytics_property', '' ) );
1607 $_wcmp_analytics_api_secret = trim( $this->get_global_attr( '_wcmp_analytics_api_secret', '' ) );
1608 if ( ! empty( $_wcmp_analytics_property ) ) {
1609 $cid = isset( $_SERVER['REMOTE_ADDR'] ) ? sanitize_text_field( wp_unslash( $_SERVER['REMOTE_ADDR'] ) ) : 555;
1610 try {
1611 if ( isset( $_COOKIE['_ga'] ) ) {
1612 $cid_parts = explode( '.', sanitize_text_field( wp_unslash( $_COOKIE['_ga'] ) ), 3 );
1613 $cid = $cid_parts[2];
1614 }
1615 } catch ( Exception $err ) {
1616 error_log( $err->getMessage() );
1617 }
1618
1619 if ( 'ua' == $_wcmp_analytics_integration ) {
1620 $_response = wp_remote_post(
1621 'http://www.google-analytics.com/collect',
1622 array(
1623 'body' => array(
1624 'v' => 1,
1625 'tid' => $_wcmp_analytics_property,
1626 'cid' => $cid,
1627 't' => 'event',
1628 'ec' => 'Music Player for WooCommerce',
1629 'ea' => 'play',
1630 'el' => $file_url,
1631 'ev' => $product_id,
1632 ),
1633 )
1634 );
1635 } else {
1636 $_response = wp_remote_post(
1637 'https://www.google-analytics.com/mp/collect?api_secret=' . $_wcmp_analytics_api_secret . '&measurement_id=' . $_wcmp_analytics_property,
1638 array(
1639 'sslverify' => true,
1640 'headers' => array(
1641 'Content-Type' => 'application/json',
1642 ),
1643 'body' => json_encode(
1644 array(
1645 'client_id' => $cid,
1646 'events' => array(
1647 array(
1648 'name' => 'play',
1649 'params' => array(
1650 'event_category' => 'Music Player for WooCommerce',
1651 'event_label' => $file_url,
1652 'event_value' => $product_id,
1653 ),
1654 ),
1655 ),
1656 )
1657 ),
1658 )
1659 );
1660 }
1661
1662 if ( is_wp_error( $_response ) ) {
1663 error_log( $_response->get_error_message() );
1664 }
1665 }
1666 } // _tracking_play_event
1667
1668 public static function troubleshoot( $option ) {
1669 if ( ! is_admin() ) {
1670 // Solves a conflict caused by the "Speed Booster Pack" plugin
1671 if ( is_array( $option ) && isset( $option['jquery_to_footer'] ) ) {
1672 unset( $option['jquery_to_footer'] );
1673 }
1674 }
1675 return $option;
1676 } // End troubleshoot
1677 } // End Class WooCommerceMusicPlayer
1678
1679 $GLOBALS['WooCommerceMusicPlayer'] = new WooCommerceMusicPlayer();
1680 }
1681