class-wc-product-grouped.php 5.2 KB

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