/includes/class.yith-woocompare-frontend.php

  1. <?php 
  2. /** 
  3. * Main class 
  4. * 
  5. * @author Your Inspiration Themes 
  6. * @package YITH Woocommerce Compare 
  7. * @version 1.1.4 
  8. */ 
  9.  
  10. if ( !defined( 'YITH_WOOCOMPARE' ) ) { exit; } // Exit if accessed directly 
  11.  
  12. if( !class_exists( 'YITH_Woocompare_Frontend' ) ) { 
  13. /** 
  14. * YITH Custom Login Frontend 
  15. * 
  16. * @since 1.0.0 
  17. */ 
  18. class YITH_Woocompare_Frontend { 
  19. /** 
  20. * Plugin version 
  21. * 
  22. * @var string 
  23. * @since 1.0.0 
  24. */ 
  25. public $version = YITH_WOOCOMPARE_VERSION; 
  26.  
  27. /** 
  28. * The list of products inside the comparison table 
  29. * 
  30. * @var array 
  31. * @since 1.0.0 
  32. */ 
  33. public $products_list = array(); 
  34.  
  35. /** 
  36. * Plugin version 
  37. * 
  38. * @var string 
  39. * @since 1.0.0 
  40. */ 
  41. public $template_file = 'compare.php'; 
  42.  
  43. /** 
  44. * Stylesheet file 
  45. *  
  46. * @var string 
  47. * @since 2.1.0 
  48. */ 
  49. public $stylesheet_file = 'compare.css'; 
  50.  
  51. /** 
  52. * The name of cookie name 
  53. * 
  54. * @var string 
  55. * @since 1.0.0 
  56. */ 
  57. public $cookie_name = 'yith_woocompare_list'; 
  58.  
  59. /** 
  60. * The action used to view the table comparison 
  61. * 
  62. * @var string 
  63. * @since 1.0.0 
  64. */ 
  65. public $action_view = 'yith-woocompare-view-table'; 
  66.  
  67. /** 
  68. * The action used to add the product to compare list 
  69. * 
  70. * @var string 
  71. * @since 1.0.0 
  72. */ 
  73. public $action_add = 'yith-woocompare-add-product'; 
  74.  
  75. /** 
  76. * The action used to add the product to compare list 
  77. * 
  78. * @var string 
  79. * @since 1.0.0 
  80. */ 
  81. public $action_remove = 'yith-woocompare-remove-product'; 
  82.  
  83. /** 
  84. * The action used to reload the compare list widget 
  85. * 
  86. * @var string 
  87. * @since 1.0.0 
  88. */ 
  89. public $action_reload = 'yith-woocompare-reload-product'; 
  90.  
  91. /** 
  92. * The standard fields 
  93. * 
  94. * @var array 
  95. * @since 1.0.0 
  96. */ 
  97. public $default_fields = array(); 
  98.  
  99. /** 
  100. * Constructor 
  101. * 
  102. * @return YITH_Woocompare_Frontend 
  103. * @since 1.0.0 
  104. */ 
  105. public function __construct() { 
  106.  
  107. // set coookiename 
  108. if ( is_multisite() ) $this->cookie_name .= '_' . get_current_blog_id(); 
  109.  
  110. add_action( 'init', array( $this, 'populate_products_list' ), 10 ); 
  111.  
  112. // populate default fields for the comparison table 
  113. $this->default_fields = YITH_Woocompare_Helper::standard_fields(); 
  114.  
  115. // Add link or button in the products list or 
  116. if ( get_option('yith_woocompare_compare_button_in_product_page') == 'yes' ) add_action( 'woocommerce_single_product_summary', array( $this, 'add_compare_link' ), 35 ); 
  117. if ( get_option('yith_woocompare_compare_button_in_products_list') == 'yes' ) add_action( 'woocommerce_after_shop_loop_item', array( $this, 'add_compare_link' ), 20 ); 
  118. add_action( 'init', array( $this, 'add_product_to_compare_action' ), 15 ); 
  119. add_action( 'init', array( $this, 'remove_product_from_compare_action' ), 15 ); 
  120. add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) ); 
  121. add_action( 'template_redirect', array( $this, 'compare_table_html' ) ); 
  122.  
  123. // add the shortcode 
  124. add_shortcode( 'yith_compare_button', array( $this, 'compare_button_sc' ) ); 
  125.  
  126. // AJAX 
  127. if( version_compare( WC()->version, '2.4', '>=' ) ) { 
  128. add_action( 'wc_ajax_' . $this->action_add, array( $this, 'add_product_to_compare_ajax' ) ); 
  129. add_action( 'wc_ajax_' . $this->action_remove, array( $this, 'remove_product_from_compare_ajax' ) ); 
  130. add_action( 'wc_ajax_' . $this->action_reload, array( $this, 'reload_widget_list_ajax' ) ); 
  131. else { 
  132. add_action( 'wp_ajax_' . $this->action_add, array( $this, 'add_product_to_compare_ajax' ) ); 
  133. add_action( 'wp_ajax_' . $this->action_remove, array( $this, 'remove_product_from_compare_ajax' ) ); 
  134. add_action( 'wp_ajax_' . $this->action_reload, array( $this, 'reload_widget_list_ajax' ) ); 
  135. // no priv 
  136. add_action( 'wp_ajax_nopriv_' . $this->action_add, array( $this, 'add_product_to_compare_ajax' ) ); 
  137. add_action( 'wp_ajax_nopriv_' . $this->action_remove, array( $this, 'remove_product_from_compare_ajax' ) ); 
  138. add_action( 'wp_ajax_nopriv_' . $this->action_reload, array( $this, 'reload_widget_list_ajax' ) ); 
  139.  
  140. return $this; 
  141.  
  142. /** 
  143. * Populate the compare product list 
  144. */ 
  145. public function populate_products_list() { 
  146.  
  147. global $sitepress; 
  148.  
  149. /** 
  150. * WPML Support 
  151. */ 
  152. $lang = isset( $_REQUEST['lang'] ) ? $_REQUEST['lang'] : false; 
  153.  
  154. // get cookie val 
  155. $the_list = isset( $_COOKIE[ $this->cookie_name ] ) ? json_decode( $_COOKIE[ $this->cookie_name ] ) : array(); 
  156.  
  157. // switch lang for WPML 
  158. if( defined( 'ICL_LANGUAGE_CODE' ) && $lang && isset( $sitepress ) ) { 
  159. $sitepress->switch_lang( $lang, true ); 
  160.  
  161. foreach( $the_list as $product_id ) { 
  162. if( function_exists( 'wpml_object_id_filter' ) ) { 
  163. $product_id_translated = wpml_object_id_filter( $product_id, 'product', false ); 
  164. // get all product of current lang 
  165. if ( $product_id_translated !== $product_id ) { 
  166. continue; 
  167.  
  168. // check for deleted|private products 
  169. $product = wc_get_product( $product_id ); 
  170. if( ! $product || yit_get_prop( $product, 'post_status' ) !== 'publish' ) { 
  171. continue; 
  172.  
  173. $this->products_list[] = $product_id; 
  174.  
  175. do_action( 'yith_woocompare_after_populate_product_list', $this->products_list ); 
  176.  
  177. /** 
  178. * Enqueue the scripts and styles in the page 
  179. */ 
  180. public function enqueue_scripts() { 
  181.  
  182. // scripts 
  183. $min = ! ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '.min' : ''; 
  184. wp_register_script( 'yith-woocompare-main', YITH_WOOCOMPARE_ASSETS_URL . '/js/woocompare' . $min .'.js', array('jquery'), $this->version, true ); 
  185.  
  186. // enqueue and add localize 
  187. wp_enqueue_script( 'yith-woocompare-main' ); 
  188.  
  189. // localize script args 
  190. $args = apply_filters( 'yith_woocompare_main_script_localize_array', array( 
  191. 'ajaxurl' => version_compare( WC()->version, '2.4', '>=' ) ? WC_AJAX::get_endpoint( "%%endpoint%%" ) : admin_url( 'admin-ajax.php', 'relative' ),  
  192. 'actionadd' => $this->action_add,  
  193. 'actionremove' => $this->action_remove,  
  194. 'actionview' => $this->action_view,  
  195. 'actionreload' => $this->action_reload,  
  196. 'added_label' => apply_filters( 'yith_woocompare_compare_added_label', __( 'Added', 'yith-woocommerce-compare' ) ),  
  197. 'table_title' => apply_filters( 'yith_woocompare_compare_table_title', __( 'Product Comparison', 'yith-woocommerce-compare' ) ),  
  198. 'auto_open' => get_option( 'yith_woocompare_auto_open', 'yes' ),  
  199. 'loader' => YITH_WOOCOMPARE_ASSETS_URL . '/images/loader.gif',  
  200. 'button_text' => get_option('yith_woocompare_button_text'),  
  201. 'cookie_name' => $this->cookie_name 
  202. )); 
  203.  
  204. wp_localize_script( 'yith-woocompare-main', 'yith_woocompare', $args ); 
  205.  
  206. // colorbox 
  207. wp_enqueue_style( 'jquery-colorbox', YITH_WOOCOMPARE_ASSETS_URL . '/css/colorbox.css' ); 
  208. wp_enqueue_script( 'jquery-colorbox', YITH_WOOCOMPARE_ASSETS_URL . '/js/jquery.colorbox-min.js', array('jquery'), '1.4.21', true ); 
  209.  
  210. // widget 
  211. if ( is_active_widget( false, false, 'yith-woocompare-widget', true ) && ! is_admin() ) { 
  212. wp_enqueue_style( 'yith-woocompare-widget', YITH_WOOCOMPARE_ASSETS_URL . '/css/widget.css' ); 
  213.  
  214. /** 
  215. * The fields to show in the table 
  216. * 
  217. * @param array $products 
  218. * @return mixed|void 
  219. * @since 1.0.0 
  220. */ 
  221. public function fields( $products = array() ) { 
  222.  
  223. $fields = get_option( 'yith_woocompare_fields', array() ); 
  224.  
  225. foreach ( $fields as $field => $show ) { 
  226. if ( $show ) { 
  227. if ( isset( $this->default_fields[$field] ) ) { 
  228. $fields[$field] = $this->default_fields[$field]; 
  229. else { 
  230. if ( taxonomy_exists( $field ) ) { 
  231. $fields[$field] = wc_attribute_label( $field ); 
  232. else { 
  233. unset( $fields[$field] ); 
  234.  
  235. return apply_filters( 'yith_woocompare_filter_table_fields', $fields, $products ); 
  236.  
  237. /** 
  238. * Render the maintenance page 
  239. * 
  240. */ 
  241. public function compare_table_html() { 
  242.  
  243. if ( ( ! defined('DOING_AJAX') || ! DOING_AJAX ) && ( ! isset( $_REQUEST['action'] ) || $_REQUEST['action'] != $this->action_view ) ) return; 
  244.  
  245. // check if is add to cart 
  246. if( isset( $_REQUEST['add-to-cart'] ) ) { 
  247. $product_id = intval( $_REQUEST['add-to-cart'] ); 
  248.  
  249. wp_redirect( get_permalink( $product_id ) ); 
  250. exit; 
  251.  
  252. global $woocommerce, $sitepress; 
  253.  
  254. /** 
  255. * WPML Suppot: Localize Ajax Call 
  256. */ 
  257. $lang = isset( $_REQUEST['lang'] ) ? $_REQUEST['lang'] : false; 
  258.  
  259. if( defined( 'ICL_LANGUAGE_CODE' ) && $lang && isset( $sitepress ) ) { 
  260. $sitepress->switch_lang( $lang, true ); 
  261.  
  262. extract( $this->_vars() ); 
  263.  
  264. // remove all styles from compare template 
  265. add_action('wp_print_styles', array( $this, 'remove_all_styles' ), 100); 
  266.  
  267. // remove admin bar 
  268. remove_action( 'wp_footer', 'wp_admin_bar_render', 1000 ); 
  269. remove_action( 'wp_head', '_admin_bar_bump_cb' ); 
  270.  
  271. $plugin_path = YITH_WOOCOMPARE_TEMPLATE_PATH . '/' . $this->template_file; 
  272.  
  273. if ( defined('WC_TEMPLATE_PATH') ) { 
  274.  
  275. $template_path = get_template_directory() . '/' . WC_TEMPLATE_PATH . $this->template_file; 
  276. $child_path = get_stylesheet_directory() . '/' . WC_TEMPLATE_PATH . $this->template_file; 
  277. else { 
  278. $template_path = get_template_directory() . '/' . $woocommerce->template_url . $this->template_file; 
  279. $child_path = get_stylesheet_directory() . '/' . $woocommerce->template_url . $this->template_file; 
  280.  
  281. foreach ( array( 'child_path', 'template_path', 'plugin_path' ) as $var ) { 
  282. if ( file_exists( ${$var} ) ) { 
  283. include ${$var}; 
  284. exit(); 
  285.  
  286. /** 
  287. * Return the array with all products and all attributes values 
  288. * 
  289. * @param mixed $products 
  290. * @return array The complete list of products with all attributes value 
  291. */ 
  292. public function get_products_list( $products = array() ) { 
  293. $list = array(); 
  294.  
  295. empty( $products ) && $products = $this->products_list; 
  296. $products = apply_filters( 'yith_woocompare_exclude_products_from_list', $products ); 
  297.  
  298. $fields = $this->fields( $products ); 
  299.  
  300. foreach ( $products as $product_id ) { 
  301.  
  302. /** 
  303. * @type object $product /WC_Product 
  304. */ 
  305. $product = $this->wc_get_product( $product_id ); 
  306.  
  307. if ( ! $product ) 
  308. continue; 
  309.  
  310. $product->fields = array(); 
  311.  
  312. // custom attributes 
  313. foreach ( $fields as $field => $name ) { 
  314.  
  315. switch( $field ) { 
  316. case 'title': 
  317. $product->fields[$field] = $product->get_title(); 
  318. break; 
  319. case 'price': 
  320. $product->fields[$field] = $product->get_price_html(); 
  321. break; 
  322. case 'image': 
  323. $product->fields[$field] = intval( get_post_thumbnail_id( $product_id ) ); 
  324. break; 
  325. case 'description': 
  326. $description = apply_filters( 'woocommerce_short_description', yit_get_prop( $product, 'post_excerpt' ) ); 
  327. $product->fields[$field] = apply_filters( 'yith_woocompare_products_description', $description ); 
  328. break; 
  329. case 'stock': 
  330. $availability = $product->get_availability(); 
  331. if ( empty( $availability['availability'] ) ) { 
  332. $availability['availability'] = __( 'In stock', 'yith-woocommerce-compare' ); 
  333. $product->fields[$field] = sprintf( '<span>%s</span>', esc_html( $availability['availability'] ) ); 
  334. break; 
  335. case 'weight': 
  336. if( $weight = $product->get_weight() ) { 
  337. $weight = wc_format_localized_decimal( $weight ) . ' ' . esc_attr( get_option( 'woocommerce_weight_unit' ) ); 
  338. else { 
  339. $weight = '-'; 
  340. $product->fields[$field] = sprintf( '<span>%s</span>', esc_html( $weight ) ); 
  341. break; 
  342. case 'dimensions': 
  343. $dimensions = function_exists( 'wc_format_dimensions' ) ? wc_format_dimensions( $product->get_dimensions(false) ) : $product->get_dimensions(); 
  344. ! $dimensions && $dimensions = '-'; 
  345.  
  346. $product->fields[$field] = sprintf( '<span>%s</span>', esc_html( $dimensions ) ); 
  347. break; 
  348. default: 
  349. if ( taxonomy_exists( $field ) ) { 
  350. $product->fields[$field] = array(); 
  351. $terms = get_the_terms( $product_id, $field ); 
  352. if ( ! empty( $terms ) ) { 
  353. foreach ( $terms as $term ) { 
  354. $term = sanitize_term( $term, $field ); 
  355. $product->fields[$field][] = $term->name; 
  356. $product->fields[$field] = implode( ', ', $product->fields[$field] ); 
  357. else { 
  358. do_action_ref_array( 'yith_woocompare_field_' . $field, array( $product, &$product->fields ) ); 
  359. break; 
  360.  
  361. $list[ $product_id ] = $product; 
  362.  
  363. return $list; 
  364.  
  365. /** 
  366. * The URL of product comparison table 
  367. * 
  368. * @param bool | int $product_id 
  369. * @return string The url to add the product in the comparison table 
  370. */ 
  371. public function view_table_url( $product_id = false ) { 
  372. $url_args = array( 
  373. 'action' => $this->action_view,  
  374. 'iframe' => true 
  375. ); 
  376.  
  377. $lang = defined( 'ICL_LANGUAGE_CODE' ) ? ICL_LANGUAGE_CODE : false; 
  378. if( $lang ) { 
  379. $url_args['lang'] = $lang; 
  380.  
  381. return apply_filters( 'yith_woocompare_view_table_url', esc_url_raw( add_query_arg( $url_args, site_url() ) ), $product_id ); 
  382.  
  383. /** 
  384. * The URL to add the product into the comparison table 
  385. * 
  386. * @param int $product_id ID of the product to add 
  387. * @return string The url to add the product in the comparison table 
  388. */ 
  389. public function add_product_url( $product_id ) { 
  390. $url_args = array( 
  391. 'action' => $this->action_add,  
  392. 'id' => $product_id 
  393. ); 
  394.  
  395. $lang = defined( 'ICL_LANGUAGE_CODE' ) ? ICL_LANGUAGE_CODE : false; 
  396. if( $lang ) { 
  397. $url_args['lang'] = $lang; 
  398.  
  399. return apply_filters( 'yith_woocompare_add_product_url', esc_url_raw( add_query_arg( $url_args, site_url() ) ), $this->action_add ); 
  400.  
  401. /** 
  402. * The URL to remove the product into the comparison table 
  403. * 
  404. * @param string $product_id The ID of the product to remove 
  405. * @return string The url to remove the product in the comparison table 
  406. */ 
  407. public function remove_product_url( $product_id ) { 
  408. $url_args = array( 
  409. 'action' => $this->action_remove,  
  410. 'id' => $product_id 
  411. ); 
  412. return apply_filters( 'yith_woocompare_remove_product_url', esc_url_raw( add_query_arg( $url_args, site_url() ) ), $this->action_remove ); 
  413.  
  414. /** 
  415. * Add the link to compare 
  416. */ 
  417. public function add_compare_link( $product_id = false, $args = array() ) { 
  418. extract( $args ); 
  419.  
  420. if ( ! $product_id ) { 
  421. global $product; 
  422. $product_id = ! is_null( $product ) ? yit_get_prop( $product, 'id', true ) : 0; 
  423.  
  424. // return if product doesn't exist 
  425. if ( empty( $product_id ) || apply_filters( 'yith_woocompare_remove_compare_link_by_cat', false, $product_id ) ) 
  426. return; 
  427.  
  428. $is_button = ! isset( $button_or_link ) || ! $button_or_link ? get_option( 'yith_woocompare_is_button' ) : $button_or_link; 
  429.  
  430. if ( ! isset( $button_text ) || $button_text == 'default' ) { 
  431. $button_text = get_option( 'yith_woocompare_button_text', __( 'Compare', 'yith-woocommerce-compare' ) ); 
  432. do_action ( 'wpml_register_single_string', 'Plugins', 'plugin_yit_compare_button_text', $button_text ); 
  433. $button_text = apply_filters( 'wpml_translate_single_string', $button_text, 'Plugins', 'plugin_yit_compare_button_text' ); 
  434.  
  435. printf( '<a href="%s" class="%s" data-product_id="%d" rel="nofollow">%s</a>', $this->add_product_url( $product_id ), 'compare' . ( $is_button == 'button' ? ' button' : '' ), $product_id, $button_text ); 
  436.  
  437. /** 
  438. * Return the url of stylesheet position 
  439. */ 
  440. public function stylesheet_url() { 
  441. global $woocommerce; 
  442.  
  443. $filename = $this->stylesheet_file; 
  444.  
  445. $plugin_path = array( 'path' => YITH_WOOCOMPARE_DIR . '/assets/css/style.css', 'url' => YITH_WOOCOMPARE_ASSETS_URL . '/css/style.css' ); 
  446.  
  447. if ( defined('WC_TEMPLATE_PATH') ) { 
  448. $template_path = array( 'path' => get_template_directory() . '/' . WC_TEMPLATE_PATH . $filename, 'url' => get_template_directory_uri() . '/' . WC_TEMPLATE_PATH . $filename ); 
  449. $child_path = array( 'path' => get_stylesheet_directory() . '/' . WC_TEMPLATE_PATH . $filename, 'url' => get_stylesheet_directory_uri() . '/' . WC_TEMPLATE_PATH . $filename ); 
  450. else { 
  451. $template_path = array( 'path' => get_template_directory() . '/' . $woocommerce->template_url . $filename, 'url' => get_template_directory_uri() . '/' . $woocommerce->template_url . $filename ); 
  452. $child_path = array( 'path' => get_stylesheet_directory() . '/' . $woocommerce->template_url . $filename, 'url' => get_stylesheet_directory_uri() . '/' . $woocommerce->template_url . $filename ); 
  453.  
  454. foreach ( array( 'child_path', 'template_path', 'plugin_path' ) as $var ) { 
  455. if ( file_exists( ${$var}['path'] ) ) { 
  456. return ${$var}['url']; 
  457.  
  458.  
  459. /** 
  460. * Generate template vars 
  461. * 
  462. * @return array 
  463. * @since 1.0.0 
  464. * @access protected 
  465. */ 
  466. protected function _vars() { 
  467. $vars = array( 
  468. 'products' => $this->get_products_list(),  
  469. 'fields' => $this->fields(),  
  470. 'repeat_price' => get_option( 'yith_woocompare_price_end' ),  
  471. 'repeat_add_to_cart' => get_option( 'yith_woocompare_add_to_cart_end' ),  
  472. ); 
  473.  
  474. return $vars; 
  475.  
  476. /** 
  477. * The action called by the query string 
  478. */ 
  479. public function add_product_to_compare_action() { 
  480. if ( defined( 'DOING_AJAX' ) && DOING_AJAX || ! isset( $_REQUEST['id'] ) || ! isset( $_REQUEST['action'] ) || $_REQUEST['action'] != $this->action_add ) { 
  481. return; 
  482.  
  483. $product_id = intval( $_REQUEST['id'] ); 
  484. $product = $this->wc_get_product( $product_id ); 
  485.  
  486. // don't add the product if doesn't exist 
  487. if ( isset( $product->id ) && ! in_array( $product_id, $this->products_list ) ) { 
  488. $this->add_product_to_compare( $product_id ); 
  489.  
  490. wp_redirect( esc_url( remove_query_arg( array( 'id', 'action' ) ) ) ); 
  491. exit(); 
  492.  
  493. /** 
  494. * The action called by AJAX 
  495. */ 
  496. public function add_product_to_compare_ajax() { 
  497.  
  498. if( ! isset( $_REQUEST['id'] ) || ! isset( $_REQUEST['action'] ) || $_REQUEST['action'] != $this->action_add ) { 
  499. die(); 
  500.  
  501. $product_id = intval( $_REQUEST['id'] ); 
  502. $product = $this->wc_get_product( $product_id ); 
  503.  
  504. // don't add the product if doesn't exist 
  505. if ( isset( $product->id ) && ! in_array( $product_id, $this->products_list ) ) { 
  506. $this->add_product_to_compare( $product_id ); 
  507.  
  508. do_action( 'yith_woocompare_add_product_action_ajax' ); 
  509.  
  510. $json = apply_filters( 'yith_woocompare_add_product_action_json', array( 
  511. 'table_url' => $this->view_table_url( $product_id ),  
  512. 'widget_table' => $this->list_products_html(),  
  513. ) ); 
  514.  
  515. echo json_encode( $json ); 
  516. die(); 
  517.  
  518. /** 
  519. * Add a product in the products comparison table 
  520. * 
  521. * @param int $product_id product ID to add in the comparison table 
  522. */ 
  523. public function add_product_to_compare( $product_id ) { 
  524.  
  525. $this->products_list[] = $product_id; 
  526. setcookie( $this->cookie_name, json_encode( $this->products_list ), 0, COOKIEPATH, COOKIE_DOMAIN, false, false ); 
  527.  
  528. do_action( 'yith_woocompare_after_add_product', $product_id ); 
  529.  
  530. /** 
  531. * The action called by the query string 
  532. */ 
  533. public function remove_product_from_compare_action() { 
  534. if ( defined( 'DOING_AJAX' ) && DOING_AJAX || ! isset( $_REQUEST['action'] ) || $_REQUEST['action'] != $this->action_remove ) { 
  535. return; 
  536.  
  537. $this->remove_product_from_compare( $_REQUEST['id'] ); 
  538.  
  539. // redirect 
  540. $redirect = esc_url( remove_query_arg( array( 'id', 'action' ) ) ); 
  541.  
  542. if ( isset( $_REQUEST['redirect'] ) && $_REQUEST['redirect'] == 'view' ) 
  543. $redirect = esc_url( remove_query_arg( 'redirect', add_query_arg( 'action', $this->action_view, $redirect ) ) ); 
  544.  
  545. wp_redirect( $redirect ); 
  546. exit(); 
  547.  
  548. /** 
  549. * The action called by AJAX 
  550. */ 
  551. public function remove_product_from_compare_ajax() { 
  552.  
  553. if ( ! isset( $_REQUEST['id'] ) || ! isset( $_REQUEST['action'] ) || $_REQUEST['action'] != $this->action_remove ) { 
  554. die(); 
  555.  
  556. $lang = isset( $_REQUEST['lang'] ) ? $_REQUEST['lang'] : false; 
  557.  
  558. $this->remove_product_from_compare( $_REQUEST['id'] ); 
  559.  
  560. do_action( 'yith_woocompare_remove_product_action_ajax' ); 
  561.  
  562. header('Content-Type: text/html; charset=utf-8'); 
  563.  
  564. if ( isset( $_REQUEST['responseType'] ) && $_REQUEST['responseType'] == 'product_list' ) { 
  565. echo $this->list_products_html( $lang ); 
  566. } else { 
  567. $this->compare_table_html(); 
  568.  
  569. die(); 
  570.  
  571. /** 
  572. * Return the list of widget table, used in AJAX 
  573. */ 
  574. public function reload_widget_list_ajax() { 
  575.  
  576. if ( ! isset( $_REQUEST['action'] ) || $_REQUEST['action'] != $this->action_reload ) { 
  577. die(); 
  578.  
  579. $lang = isset( $_REQUEST['lang'] ) ? $_REQUEST['lang'] : false; 
  580.  
  581. echo $this->list_products_html( $lang ); 
  582. die(); 
  583.  
  584. /** 
  585. * The list of products as HTML list 
  586. */ 
  587. public function list_products_html( $lang = false ) { 
  588. ob_start(); 
  589.  
  590. /** 
  591. * WPML Suppot: Localize Ajax Call 
  592. */ 
  593. global $sitepress; 
  594.  
  595. if( defined( 'ICL_LANGUAGE_CODE' ) && $lang && isset( $sitepress )) { 
  596. $sitepress->switch_lang( $lang, true ); 
  597.  
  598. if ( empty( $this->products_list ) ) { 
  599. echo '<li class="list_empty">' . __( 'No products to compare', 'yith-woocommerce-compare' ) . '</li>'; 
  600. return ob_get_clean(); 
  601.  
  602. foreach ( $this->products_list as $product_id ) { 
  603. /** 
  604. * @type object $product /WC_Product 
  605. */ 
  606. $product = $this->wc_get_product( $product_id ); 
  607. if ( ! $product ) 
  608. continue; 
  609. ?> 
  610. <li> 
  611. <a href="<?php echo $this->remove_product_url( $product_id ) ?>" data-product_id="<?php echo $product_id; ?>" class="remove" title="<?php _e( 'Remove', 'yith-woocommerce-compare' ) ?>">x</a> 
  612. <a class="title" href="<?php echo get_permalink( $product_id ) ?>"><?php echo $product->get_title() ?></a> 
  613. </li> 
  614. <?php 
  615.  
  616. $return = ob_get_clean(); 
  617.  
  618. return apply_filters( 'yith_woocompare_widget_products_html', $return, $this->products_list, $this ); 
  619.  
  620. /** 
  621. * Remove a product from the comparison table 
  622. * 
  623. * @param $product_id The product ID to remove from the comparison table 
  624. */ 
  625. public function remove_product_from_compare( $product_id ) { 
  626.  
  627. if( $product_id == 'all' ) { 
  628. $this->products_list = array(); 
  629. else { 
  630. foreach ( $this->products_list as $k => $id ) { 
  631. if ( intval( $product_id ) == $id ) { 
  632. unset( $this->products_list[ $k ] ); 
  633.  
  634. setcookie( $this->cookie_name, json_encode( array_values( $this->products_list ) ), 0, COOKIEPATH, COOKIE_DOMAIN, false, false ); 
  635.  
  636. do_action( 'yith_woocompare_after_remove_product', $product_id ); 
  637.  
  638. /** 
  639. * Remove all styles from the compare template 
  640. */ 
  641. public function remove_all_styles() { 
  642. global $wp_styles; 
  643. $wp_styles->queue = array(); 
  644.  
  645. /** 
  646. * Show the html for the shortcode 
  647. */ 
  648. public function compare_button_sc( $atts, $content = null ) { 
  649. $atts = shortcode_atts(array( 
  650. 'product' => false,  
  651. 'type' => 'default',  
  652. 'container' => 'yes' 
  653. ), $atts); 
  654.  
  655. $product_id = 0; 
  656.  
  657. /** 
  658. * Retrieve the product ID in these steps: 
  659. * - If "product" attribute is not set, get the product ID of current product loop 
  660. * - If "product" contains ID, post slug or post title 
  661. */ 
  662. if ( ! $atts['product'] ) { 
  663. global $product; 
  664. $product_id = ! is_null( $product ) ? yit_get_prop( $product, 'id', true ) : 0; 
  665. } else { 
  666. global $wpdb; 
  667. $product = $wpdb->get_row( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE ID = %d OR post_name = %s OR post_title = %s LIMIT 1", $atts['product'], $atts['product'], $atts['product'] ) ); 
  668. if ( ! empty( $product ) ) { 
  669. $product_id = $product->ID; 
  670.  
  671. // if product ID is 0, maybe the product doesn't exists or is wrong.. in this case, doesn't show the button 
  672. if ( empty( $product_id ) ) 
  673. return ''; 
  674.  
  675. ob_start(); 
  676. if ( $atts['container'] == 'yes' ) echo '<div class="woocommerce product compare-button">'; 
  677. $this->add_compare_link( $product_id, array( 
  678. 'button_or_link' => ( $atts['type'] == 'default' ? false : $atts['type'] ),  
  679. 'button_text' => empty( $content ) ? 'default' : $content 
  680. ) ); 
  681. if ( $atts['container'] == 'yes' ) echo '</div>'; 
  682. return ob_get_clean(); 
  683.  
  684. public function wc_get_product( $product_id ) { 
  685. $wc_get_product = function_exists( 'wc_get_product' ) ? 'wc_get_product' : 'get_product'; 
  686. return $wc_get_product( $product_id ); 
.