WCPBC_Product_Price

WCPBC_Product_Price class.

Defined (1)

The class is defined in the following location(s).

/includes/class-wcpbc-product-price.php  
  1. class WCPBC_Product_Price { 
  2.  
  3. private static $current_product_id; 
  4.  
  5. /** 
  6. * Hook actions and filters 
  7. */ 
  8. public static function init() { 
  9. global $wp_version; 
  10.  
  11. /** Currency */ 
  12. add_filter( 'woocommerce_currency', array( __CLASS__ , 'currency' ) ); 
  13.  
  14. /** WC_Product */ 
  15. add_filter( 'woocommerce_get_price', array( __CLASS__ , 'get_price' ), 10, 2 ); 
  16.  
  17. add_filter( 'woocommerce_get_regular_price', array( __CLASS__ , 'get_regular_price') , 10, 2 ); 
  18.  
  19. add_filter( 'woocommerce_get_sale_price', array( __CLASS__ , 'get_sale_price') , 10, 2 );  
  20.  
  21. add_filter( 'woocommerce_adjust_non_base_location_prices', array( __CLASS__, 'adjust_non_base_location_prices' ) ); 
  22.  
  23. /** WC_Product_Variable */ 
  24. add_filter( 'woocommerce_get_variation_prices_hash', array( __CLASS__ , 'get_variation_prices_hash' ), 10, 3 ); 
  25.  
  26. add_filter( 'woocommerce_variation_prices_price', array( __CLASS__ , 'get_price' ), 10, 3 ); 
  27.  
  28. add_filter( 'woocommerce_variation_prices_regular_price', array( __CLASS__ , 'get_regular_price' ), 10, 3 ); 
  29.  
  30. add_filter( 'woocommerce_variation_prices_sale_price', array( __CLASS__ , 'get_sale_price' ), 10, 3 ); 
  31.  
  32. /** WC_Product_Variation */  
  33. add_filter( 'woocommerce_get_variation_price', array( __CLASS__ , 'get_variation_price' ), 10, 4 );  
  34.  
  35. add_filter( 'woocommerce_get_variation_regular_price', array( __CLASS__ , 'get_variation_regular_price' ), 10, 4 );  
  36.  
  37. add_filter( 'woocommerce_get_variation_sale_price', array( __CLASS__ , 'get_variation_sale_price' ), 10, 4 );  
  38.  
  39. /** WC_Product_Grouped */ 
  40. add_filter( 'woocommerce_get_price_html', array( __CLASS__ , 'get_grouped_price_html' ), 10, 2 ); 
  41.  
  42. /** Flat rate shipping */ 
  43. add_filter( 'woocommerce_flat_rate_shipping_add_rate', array( __CLASS__ , 'flat_rate_shipping_conversion' ), 30, 3 ); 
  44.  
  45. /** Widget Price Filter */ 
  46. add_filter( 'woocommerce_price_filter_results', array( __CLASS__ , 'price_filter_results' ), 10, 3 ); 
  47.  
  48. add_filter( 'woocommerce_price_filter_widget_min_amount', array( __CLASS__ , 'price_filter_widget_min_amount' ) ); 
  49.  
  50. add_filter( 'woocommerce_price_filter_widget_max_amount', array( __CLASS__ , 'price_filter_widget_max_amount' ) );  
  51.  
  52. /** Products on sale */ 
  53. add_filter( 'pre_transient_wc_products_onsale', array( __CLASS__ , 'product_ids_on_sale' ), 10, ( version_compare( $wp_version, '4.4', '<' ) ? 1 : 2 ) ); 
  54.  
  55. /** 
  56. * Return currency 
  57. * @return string currency 
  58. */ 
  59. public static function currency( $currency ) { 
  60.  
  61. $_currency = $currency; 
  62.  
  63. if ( WCPBC()->customer->currency ) { 
  64. $_currency = WCPBC()->customer->currency; 
  65.  
  66. return $_currency; 
  67. }  
  68.  
  69. /** 
  70. * Returns WCPBC price. 
  71. * @return string price 
  72. */ 
  73. protected static function wcpbc_get_price( $meta_key_preffix, $price_type, $post_id, $price ) { 
  74.  
  75. $wcpbc_price = $price; 
  76.  
  77. $price_method = get_post_meta( $post_id, $meta_key_preffix . '_price_method', true );  
  78.  
  79. if ( $price_method === 'manual') { 
  80.  
  81. $wcpbc_price = get_post_meta( $post_id, $meta_key_preffix . $price_type, true ); 
  82.  
  83. } elseif ( WCPBC()->customer->exchange_rate && !empty( $price ) ) { 
  84.  
  85. $wcpbc_price = ( $price * WCPBC()->customer->exchange_rate );  
  86.  
  87. return $wcpbc_price; 
  88.  
  89. /** 
  90. * Returns the product price. 
  91. * @param decimal $price 
  92. * @param WC_Product $product 
  93. * @param string $price_type 
  94. * @return string 
  95. */ 
  96. public static function get_product_price( $price, $product, $price_type ) {  
  97.  
  98. $wcpbc_price = $price;  
  99.  
  100. if ( WCPBC()->customer->group_key && apply_filters( 'wc_price_based_country_get_product_price', true, $product ) ) { 
  101.  
  102. $meta_key_preffix = '_' . WCPBC()->customer->group_key; 
  103.  
  104. if ( isset( $product->variation_id ) ) { 
  105.  
  106. $post_id = $product->variation_id;  
  107.  
  108. $meta_key_preffix .= '_variable'; 
  109.  
  110. } else { 
  111. $post_id = $product->id;  
  112.  
  113. $wcpbc_price = self::wcpbc_get_price( $meta_key_preffix, $price_type, $post_id, $price );  
  114.  
  115. return $wcpbc_price; 
  116.  
  117. /** 
  118. * Returns the product's price. 
  119. * @return string price 
  120. */ 
  121. public static function get_price( $price, $product, $parent = NULL) {  
  122. /** 
  123. * Store product Id for later use in filter "woocommerce_adjust_non_base_location_prices",  
  124. * $product must be a parameter in this filter 
  125. */  
  126. self::$current_product_id = $product->id; 
  127.  
  128. return self::get_product_price( $price, $product, '_price'); 
  129.  
  130. /** 
  131. * Returns the product's regular price. 
  132. * @return string price 
  133. */ 
  134. public static function get_regular_price($price, $product, $parent = NULL) {  
  135. return self::get_product_price( $price, $product, '_regular_price'); 
  136. }  
  137.  
  138. /** 
  139. * Returns the product's sale price 
  140. * @return string price 
  141. */ 
  142. public static function get_sale_price( $price, $product, $parent = NULL ) {  
  143. return self::get_product_price( $price, $product, '_sale_price'); 
  144.  
  145. /** 
  146. * Stop base taxes being taken off when dealing with out of base locations 
  147. * @param bool $adjust  
  148. * @return bool 
  149. */  
  150. public static function adjust_non_base_location_prices( $adjust ) {  
  151. if ( $meta_key_preffix = WCPBC()->customer->group_key ) {  
  152. $adjust = ( get_post_meta( self::$current_product_id , '_' . $meta_key_preffix . '_price_method', true ) !== 'manual' ); 
  153. }  
  154. return $adjust; 
  155.  
  156. /** 
  157. * Returns unique cache key to store variation child prices 
  158. * @param array $hash 
  159. * @param WC_Product $product 
  160. * @param bool $display 
  161. * @return array 
  162. */ 
  163. public static function get_variation_prices_hash( $hash, $product, $display ) {  
  164.  
  165. if ( WCPBC()->customer->group_key ) { 
  166.  
  167. $hash[] = 'wcpbc_region_key_' . WCPBC()->customer->group_key; 
  168. $hash[] = 'wcpbc_exchange_rate_' . WCPBC()->customer->exchange_rate; 
  169.  
  170. return $hash; 
  171.  
  172. /** 
  173. * Get the min or max variation active price. 
  174. * @param string $min_or_max - min or max 
  175. * @param boolean $display Whether the value is going to be displayed 
  176. * @return string price 
  177. */  
  178. public static function get_variation_price( $price, $product, $min_or_max, $display, $price_type = '_price' ) {  
  179.  
  180. $wcpbc_price = $price;  
  181.  
  182. if ( WCPBC()->customer->group_key ) { 
  183.  
  184. $variation_id = get_post_meta( $product->id, '_' . WCPBC()->customer->group_key . '_' . $min_or_max . $price_type . '_variation_id', true ); 
  185.  
  186. if ( $variation_id ) { 
  187.  
  188. $variation = $product->get_child( $variation_id ); 
  189.  
  190. if ( $variation) { 
  191.  
  192. $price_function = 'get' . $price_type; 
  193.  
  194. $wcpbc_price = $variation->$price_function(); 
  195.  
  196. if ( $display ) { 
  197. $tax_display_mode = get_option( 'woocommerce_tax_display_shop' ); 
  198. $wcpbc_price = $tax_display_mode == 'incl' ? $variation->get_price_including_tax( 1, $wcpbc_price ) : $variation->get_price_excluding_tax( 1, $wcpbc_price ); 
  199.  
  200. } elseif( $wcpbc_price && WCPBC()->customer->exchange_rate && $price_type !== '_price') { 
  201.  
  202. $wcpbc_price = $wcpbc_price * WCPBC()->customer->exchange_rate; 
  203. }  
  204.  
  205. return $wcpbc_price; 
  206. }  
  207.  
  208. /** 
  209. * Get the min or max variation regular price. 
  210. * @param string $min_or_max - min or max 
  211. * @param boolean $display Whether the value is going to be displayed 
  212. * @return string price 
  213. */ 
  214. public static function get_variation_regular_price( $price, $product, $min_or_max, $display ) {  
  215.  
  216. return self::get_variation_price( $price, $product, $min_or_max, $display, '_regular_price' ); 
  217. }  
  218.  
  219. /** 
  220. * Get the min or max variation sale price. 
  221. * @param string $min_or_max - min or max 
  222. * @param boolean $display Whether the value is going to be displayed 
  223. * @return string price 
  224. */ 
  225. public static function get_variation_sale_price( $price, $product, $min_or_max, $display ) {  
  226.  
  227. return self::get_variation_price( $price, $product, $min_or_max, $display, '_sale_price' ); 
  228. }  
  229.  
  230. /** 
  231. * Returns the price in html format for product grouped  
  232. * @param string $price 
  233. * @param WC_Product_Grouped $product 
  234. * @return string 
  235. */ 
  236. public static function get_grouped_price_html( $price, $product ) { 
  237.  
  238. if ( get_class( $product ) == 'WC_Product_Grouped' && WCPBC()->customer->group_key ) {  
  239.  
  240. $price = ''; 
  241. $tax_display_mode = get_option( 'woocommerce_tax_display_shop' ); 
  242. $child_prices = array(); 
  243. $meta_key_preffix = '_' . WCPBC()->customer->group_key; 
  244.  
  245. foreach ( $product->get_children() as $child_id ) {  
  246. $child_prices[] = self::wcpbc_get_price( $meta_key_preffix, '_price', $child_id, get_post_meta( $child_id, '_price', true ) ); 
  247. }  
  248.  
  249. $child_prices = array_unique( $child_prices ); 
  250. $get_price_method = 'get_price_' . $tax_display_mode . 'uding_tax'; 
  251.  
  252. if ( ! empty( $child_prices ) ) { 
  253. $min_price = min( $child_prices ); 
  254. $max_price = max( $child_prices ); 
  255. } else { 
  256. $min_price = ''; 
  257. $max_price = ''; 
  258.  
  259. if ( $min_price ) { 
  260. if ( $min_price == $max_price ) { 
  261. $display_price = wc_price( $product->$get_price_method( 1, $min_price ) ); 
  262. } else { 
  263. $from = wc_price( $product->$get_price_method( 1, $min_price ) ); 
  264. $to = wc_price( $product->$get_price_method( 1, $max_price ) ); 
  265. $display_price = sprintf( _x( '%1$s–%2$s', 'Price range: from-to', 'woocommerce' ), $from, $to ); 
  266.  
  267. $price .= $display_price . $product->get_price_suffix();  
  268.  
  269. return $price;  
  270.  
  271. /** 
  272. * Apply currency conversion to flat rate shipping method 
  273. * @param WC_Shipping_Flat_Rate $method 
  274. * @param array $rate  
  275. * @param array $packages  
  276. */ 
  277. public static function flat_rate_shipping_conversion( $method, $rate, $packages ) {  
  278.  
  279. if ( WCPBC()->customer->exchange_rate && WCPBC()->customer->exchange_rate != '1' && get_option('wc_price_based_shipping_conversion') === 'yes' ) {  
  280. for( $i=0; $i< count($method->rates); $i++ ) { 
  281. if ( in_array( $method->rates[$i]->method_id, array( 'flat_rate', 'international_delivery' ) ) ) { 
  282. $method->rates[$i]->cost = $method->rates[$i]->cost * WCPBC()->customer->exchange_rate;  
  283. }  
  284. }  
  285.  
  286. /** 
  287. * Return matched produts where price between min and max 
  288. * @param array $matched_products_query 
  289. * @param int $min  
  290. * @param int $max 
  291. * @return array 
  292. */ 
  293. public static function price_filter_results( $matched_products_query, $min, $max ) {  
  294.  
  295. if ( WCPBC()->customer->group_key && WCPBC()->customer->exchange_rate ) { 
  296.  
  297. global $wpdb; 
  298.  
  299. $_price_method = '_' . WCPBC()->customer->group_key . '_price_method'; 
  300. $_price = '_' . WCPBC()->customer->group_key . '_price'; 
  301.  
  302. $sql = $wpdb->prepare('SELECT DISTINCT ID, post_parent, post_type FROM %1$s  
  303. INNER JOIN %2$s wc_price ON ID = wc_price.post_id and wc_price.meta_key = "_price" AND wc_price.meta_value != "" 
  304. LEFT JOIN %2$s price_method ON ID = price_method.post_id and price_method.meta_key = "%3$s" 
  305. LEFT JOIN %2$s price ON ID = price.post_id and price.meta_key = "%4$s" AND price.meta_value != "" 
  306. WHERE post_type IN ( "product", "product_variation" ) 
  307. AND post_status = "publish"  
  308. AND IF(IFNULL(price_method.meta_value, "exchange_rate") = "exchange_rate", wc_price.meta_value * %5$s, price.meta_value + 0) BETWEEN %6$d AND %7$d' 
  309. , $wpdb->posts, $wpdb->postmeta, $_price_method, $_price, WCPBC()->customer->exchange_rate, $min, $max); 
  310.  
  311. $matched_products_query = $wpdb->get_results( $sql, OBJECT_K );  
  312.  
  313. return $matched_products_query; 
  314.  
  315. /** 
  316. * Return de min and max value of product prices 
  317. * @param string $min_or_max 
  318. * @param double $amount 
  319. * @return double 
  320. */  
  321. private static function _price_min_amount( $amount, $min_or_max = 'min' ) {  
  322.  
  323. global $wpdb; 
  324.  
  325. if ( WCPBC()->customer->group_key && WCPBC()->customer->exchange_rate ) {  
  326.  
  327. $cache_key = md5( json_encode( array(  
  328. 'wcpbc_amount',  
  329. $min_or_max,  
  330. WCPBC()->customer->group_key,  
  331. WCPBC()->customer->exchange_rate,  
  332. implode( ', ', array_map( 'absint', WC()->query->layered_nav_product_ids ) ),  
  333. ) ) ) . WC_Cache_Helper::get_transient_version( 'product' );  
  334.  
  335. if ( false === ( $amount = get_transient( $cache_key ) ) ) {  
  336.  
  337. $_price_method = '_' . WCPBC()->customer->group_key . '_price_method'; 
  338. $_price = '_' . WCPBC()->customer->group_key . '_price'; 
  339.  
  340. $sql = 'SELECT ' . $min_or_max .'( IF(IFNULL(price_method.meta_value, "exchange_rate") = "exchange_rate", wc_price.meta_value * %1$s, price.meta_value + 0) ) as amount 
  341. FROM %2$s posts 
  342. INNER JOIN %3$s wc_price ON ID = wc_price.post_id and wc_price.meta_key = "_price" AND wc_price.meta_value != "" 
  343. LEFT JOIN %3$s price_method ON ID = price_method.post_id and price_method.meta_key = "%4$s" 
  344. LEFT JOIN %3$s price ON ID = price.post_id and price.meta_key = "%5$s" AND price.meta_value != "" 
  345. WHERE post_type IN ( "product", "product_variation" ) AND post_status = "publish"'; 
  346.  
  347. if ( count( WC()->query->layered_nav_product_ids )!== 0 ) { 
  348.  
  349. $sql .= ' AND ( '; 
  350. $sql .= ' posts.ID IN (' . implode( ', ', array_map( 'absint', WC()->query->layered_nav_product_ids ) ) . ')'; 
  351. $sql .= ' OR ( posts.post_parent IN (' . implode( ', ', array_map( 'absint', WC()->query->layered_nav_product_ids ) ) . ')'; 
  352. $sql .= ' AND posts.post_parent != 0 )'; 
  353. $sql .= ' )'; 
  354.  
  355. $sql = $wpdb->prepare( $sql, WCPBC()->customer->exchange_rate, $wpdb->posts, $wpdb->postmeta, $_price_method, $_price);  
  356.  
  357. $amount = $wpdb->get_var( $sql); 
  358.  
  359. set_transient( $cache_key, $amount, HOUR_IN_SECONDS ); 
  360.  
  361. return $amount; 
  362.  
  363. /**  
  364. * Filter for price_filter_widget_min_amount 
  365. * @param $amount Min amount 
  366. */ 
  367. public static function price_filter_widget_min_amount( $amount ) {  
  368. return floor( self::_price_min_amount( $amount ) );  
  369.  
  370. /**  
  371. * Filter for price_filter_widget_max_amount 
  372. * @param $amount Max amount 
  373. */ 
  374. public static function price_filter_widget_max_amount( $amount ) {  
  375. return ceil( self::_price_min_amount( $amount, 'max' ) ); 
  376. }  
  377.  
  378. /** 
  379. * Returns an array containing the IDs of the products that are on sale. Filter through get_transient 
  380. * @return array 
  381. */ 
  382. public static function product_ids_on_sale( $value, $transient = false ) { 
  383. global $wpdb; 
  384.  
  385. if ( WCPBC()->customer->group_key ) { 
  386.  
  387. $cache_key = 'wcpbc_products_onsale_' . WCPBC()->customer->group_key; 
  388.  
  389. // Load from cache 
  390. $product_ids_on_sale = get_transient( $cache_key ); 
  391.  
  392. // Valid cache found 
  393. if ( false !== $product_ids_on_sale ) {  
  394. return $product_ids_on_sale; 
  395.  
  396. $_price_method = '_' . WCPBC()->customer->group_key . '_price_method'; 
  397. $_variable_price_method = '_' . WCPBC()->customer->group_key . '_variable_price_method'; 
  398. $_price = '_' . WCPBC()->customer->group_key . '_price';  
  399. $_variable_price = '_' . WCPBC()->customer->group_key . '_variable_price'; 
  400. $_sale_price = '_' . WCPBC()->customer->group_key . '_sale_price'; 
  401. $_variable_sale_price = '_' . WCPBC()->customer->group_key . '_variable_sale_price'; 
  402.  
  403.  
  404. $sql = $wpdb->prepare( ' 
  405. SELECT posts.ID, posts.post_parent FROM %1$s AS posts  
  406. LEFT JOIN %2$s AS wc_price ON wc_price.post_id = posts.ID AND wc_price.meta_key = "_price" 
  407. LEFT JOIN %2$s AS wc_sale_price ON wc_sale_price.post_id = posts.ID AND wc_sale_price.meta_key = "_sale_price" 
  408. LEFT JOIN %2$s AS price_method ON price_method.post_id = posts.ID AND price_method.meta_key in ("%3$s" , "%4$s") 
  409. LEFT JOIN %2$s AS price ON price.post_id = posts.ID AND price.meta_key in ("%5$s" , "%6$s") 
  410. LEFT JOIN %2$s AS sale_price ON sale_price.post_id = posts.ID AND sale_price.meta_key in ("%7$s" , "%8$s") 
  411. WHERE posts.post_type IN ( "product", "product_variation" ) AND posts.post_status = "publish" 
  412. AND ( IF(IFNULL(price_method.meta_value, "exchange_rate") = "exchange_rate", (IFNULL(wc_price.meta_value, 0) + 0) * %9$s, IFNULL(price.meta_value, 0) + 0) ) != 0 
  413. AND ( IF(IFNULL(price_method.meta_value, "exchange_rate") = "exchange_rate", (IFNULL(wc_price.meta_value, 0) + 0) * %9$s, IFNULL(price.meta_value, 0) + 0) ) =  
  414. ( IF(IFNULL(price_method.meta_value, "exchange_rate") = "exchange_rate", (IFNULL(wc_sale_price.meta_value, 0) + 0) * %9$s, IFNULL(sale_price.meta_value, 0) + 0) ) 
  415. ', $wpdb->posts, $wpdb->postmeta, $_price_method, $_variable_price_method, $_price, $_variable_price, $_sale_price, $_variable_sale_price, WCPBC()->customer->exchange_rate ) ; 
  416.  
  417. $on_sale_posts = $wpdb->get_results( $sql ); 
  418.  
  419. $product_ids_on_sale = array_unique( array_map( 'absint', array_merge( wp_list_pluck( $on_sale_posts, 'ID' ), array_diff( wp_list_pluck( $on_sale_posts, 'post_parent' ), array( 0 ) ) ) ) ); 
  420.  
  421. set_transient( $cache_key, $product_ids_on_sale, DAY_IN_SECONDS * 30 ); 
  422.  
  423. return $product_ids_on_sale; 
  424.  
  425. } else { 
  426. return false; 
  427. }