/includes/class-wc-product-grouped.php

  1. <?php 
  2. if ( ! defined( 'ABSPATH' ) ) { 
  3. exit; 
  4.  
  5. /** 
  6. * Grouped Product Class. 
  7. * 
  8. * Grouped products cannot be purchased - they are wrappers for other products. 
  9. * 
  10. * @class WC_Product_Grouped 
  11. * @version 3.0.0 
  12. * @package WooCommerce/Classes/Products 
  13. * @category Class 
  14. * @author WooThemes 
  15. */ 
  16. class WC_Product_Grouped extends WC_Product { 
  17.  
  18. /** 
  19. * Stores product data. 
  20. * 
  21. * @var array 
  22. */ 
  23. protected $extra_data = array( 
  24. 'children' => array(),  
  25. ); 
  26.  
  27. /** 
  28. * Get internal type. 
  29. * @return string 
  30. */ 
  31. public function get_type() { 
  32. return 'grouped'; 
  33.  
  34. /** 
  35. * Get the add to cart button text. 
  36. * 
  37. * @access public 
  38. * @return string 
  39. */ 
  40. public function add_to_cart_text() { 
  41. return apply_filters( 'woocommerce_product_add_to_cart_text', __( 'View products', 'woocommerce' ), $this ); 
  42.  
  43. /** 
  44. * Returns whether or not the product is on sale. 
  45. * 
  46. * @param string $context What the value is for. Valid values are view and edit. 
  47. * @return bool 
  48. */ 
  49. public function is_on_sale( $context = 'view' ) { 
  50. global $wpdb; 
  51.  
  52. $on_sale = $this->get_children() && null !== $wpdb->get_var( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = '_sale_price' AND meta_value > 0 AND post_id IN (" . implode( ', ', array_map( 'esc_sql', $this->get_children() ) ) . ");" ); 
  53.  
  54. return 'view' === $context ? apply_filters( 'woocommerce_product_is_on_sale', $on_sale, $this ) : $on_sale; 
  55.  
  56. /** 
  57. * Returns false if the product cannot be bought. 
  58. * 
  59. * @return bool 
  60. */ 
  61. public function is_purchasable() { 
  62. return apply_filters( 'woocommerce_is_purchasable', false, $this ); 
  63.  
  64. /** 
  65. * Returns the price in html format. 
  66. * 
  67. * @access public 
  68. * @param string $price (default: '') 
  69. * @return string 
  70. */ 
  71. public function get_price_html( $price = '' ) { 
  72. $tax_display_mode = get_option( 'woocommerce_tax_display_shop' ); 
  73. $child_prices = array(); 
  74.  
  75. foreach ( $this->get_children() as $child_id ) { 
  76. $child = wc_get_product( $child_id ); 
  77. if ( '' !== $child->get_price() ) { 
  78. $child_prices[] = 'incl' === $tax_display_mode ? wc_get_price_including_tax( $child ) : wc_get_price_excluding_tax( $child ); 
  79.  
  80. if ( ! empty( $child_prices ) ) { 
  81. $min_price = min( $child_prices ); 
  82. $max_price = max( $child_prices ); 
  83. } else { 
  84. $min_price = ''; 
  85. $max_price = ''; 
  86.  
  87. if ( '' !== $min_price ) { 
  88. $price = $min_price !== $max_price ? sprintf( _x( '%1$s–%2$s', 'Price range: from-to', 'woocommerce' ), wc_price( $min_price ), wc_price( $max_price ) ) : wc_price( $min_price ); 
  89. $is_free = ( 0 == $min_price && 0 == $max_price ); 
  90.  
  91. if ( $is_free ) { 
  92. $price = apply_filters( 'woocommerce_grouped_free_price_html', __( 'Free!', 'woocommerce' ), $this ); 
  93. } else { 
  94. $price = apply_filters( 'woocommerce_grouped_price_html', $price . $this->get_price_suffix(), $this, $child_prices ); 
  95. } else { 
  96. $price = apply_filters( 'woocommerce_grouped_empty_price_html', '', $this ); 
  97.  
  98. return apply_filters( 'woocommerce_get_price_html', $price, $this ); 
  99.  
  100. /** 
  101. |-------------------------------------------------------------------------- 
  102. | Getters 
  103. |-------------------------------------------------------------------------- 
  104. | 
  105. | Methods for getting data from the product object. 
  106. */ 
  107.  
  108. /** 
  109. * Return the children of this product. 
  110. * 
  111. * @param string $context 
  112. * @return array 
  113. */ 
  114. public function get_children( $context = 'view' ) { 
  115. return $this->get_prop( 'children', $context ); 
  116.  
  117. /** 
  118. |-------------------------------------------------------------------------- 
  119. | Setters 
  120. |-------------------------------------------------------------------------- 
  121. | 
  122. | Methods for getting data from the product object. 
  123. */ 
  124.  
  125. /** 
  126. * Return the children of this product. 
  127. * 
  128. * @param array $children 
  129. */ 
  130. public function set_children( $children ) { 
  131. $this->set_prop( 'children', array_filter( wp_parse_id_list( (array) $children ) ) ); 
  132.  
  133. /** 
  134. |-------------------------------------------------------------------------- 
  135. | Sync with children. 
  136. |-------------------------------------------------------------------------- 
  137. */ 
  138.  
  139. /** 
  140. * Sync a grouped product with it's children. These sync functions sync 
  141. * upwards (from child to parent) when the variation is saved. 
  142. * 
  143. * @param WC_Product|int $product Product object or ID for which you wish to sync. 
  144. * @param bool $save If true, the prouduct object will be saved to the DB before returning it. 
  145. * @return WC_Product Synced product object. 
  146. */ 
  147. public static function sync( $product, $save = true ) { 
  148. if ( ! is_a( $product, 'WC_Product' ) ) { 
  149. $product = wc_get_product( $product ); 
  150. if ( is_a( $product, 'WC_Product_Grouped' ) ) { 
  151. $data_store = WC_Data_Store::load( 'product-' . $product->get_type() ); 
  152. $data_store->sync_price( $product ); 
  153. if ( $save ) { 
  154. $product->save(); 
  155. return $product; 
.