class-wc-cart.php 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. <?php
  2. // http://docs.woothemes.com/wc-apidocs/class-WC_Cart.html
  3. class Booked_WC_Cart {
  4. // doesn't work on INIT, => use template_redirect
  5. public static function add_appointment( $app_id=null ) {
  6. $app_id = intval($app_id);
  7. $appointment = Booked_WC_Appointment::get($app_id);
  8. if ( !$appointment->products ) {
  9. $message = sprintf(__('Appointment with ID %1$d does not have any products assigned to it.', 'booked-woocommerce-payments'), $post_id);
  10. throw new Exception($message);
  11. }
  12. $cart = WC()->cart;
  13. if ( !method_exists($cart, 'add_to_cart') ) {
  14. return;
  15. }
  16. $cart_appointments = self::get_cart_appointments();
  17. foreach ($appointment->products as $product) {
  18. $product_id = intval($product->product_id);
  19. if ( !isset($product->variation_id) || !intval($product->variation_id) ) {
  20. $variation_id = false;
  21. } else {
  22. $variation_id = intval($product->variation_id);
  23. }
  24. $check_key = "{$app_id}::{$product_id}::" . intval($variation_id);
  25. // check if the product is added to the cart and if it isn't, add it
  26. // we need that in case a specific appointment has more than one product and one of the is removed from the cart by accident
  27. if ( in_array($check_key, $cart_appointments['extended']) ) {
  28. continue;
  29. }
  30. $additional_item_data = array(
  31. BOOKED_WC_PLUGIN_PREFIX . 'appointment_id' => $app_id
  32. );
  33. // add calendar name as part of the item data
  34. if ( !empty($appointment->calendar->calendar_obj) ) {
  35. $additional_item_data[BOOKED_WC_PLUGIN_PREFIX . 'appointment_cal_name'] = $appointment->calendar->calendar_obj->name;
  36. }
  37. // <---
  38. // add calendar assignee
  39. if ( !empty($appointment->calendar->calendar_obj) ) {
  40. $term_meta = get_option( "taxonomy_{$appointment->calendar->calendar_obj->term_id}" );
  41. $assignee_email = $term_meta['notifications_user_id'];
  42. if ( $assignee_email && ($usr=get_user_by('email', $assignee_email)) ) {
  43. $additional_item_data[BOOKED_WC_PLUGIN_PREFIX . 'appointment_assignee_name'] = $usr->display_name;
  44. }
  45. }
  46. // <---
  47. // add timerange name as part of the item data
  48. $additional_item_data[BOOKED_WC_PLUGIN_PREFIX . 'appointment_timerange'] = $appointment->timeslot_text;
  49. // <---
  50. // add the custom field information as part of the item data
  51. $i = 0;
  52. $separator = '--SEP--';
  53. $meta_key = '_' . BOOKED_WC_PLUGIN_PREFIX . 'cfield_';
  54. $custom_fields = (array) $appointment->custom_fields;
  55. foreach ($custom_fields as $field_label => $field_value) {
  56. $key = $meta_key . strval($i);
  57. $value = $field_label . ': ' . $separator . $field_value;
  58. $additional_item_data[$key] = $value;
  59. $i++;
  60. }
  61. // <---
  62. $quantity = 1;
  63. $variation_attributes = array();
  64. // If WPML is installed, let's make sure it adds the correct Product ID to the cart.
  65. if ( function_exists( 'icl_object_id' ) ):
  66. $product_id = icl_object_id( $product_id, 'product', true );
  67. elseif ( function_exists( 'pll_get_post' ) ):
  68. $product_id = pll_get_post( $product_id, 'product', true );
  69. endif;
  70. $cart->add_to_cart(
  71. $product_id,
  72. $quantity,
  73. $variation_id,
  74. $variation_attributes,
  75. $additional_item_data
  76. );
  77. }
  78. return true;
  79. }
  80. public static function empty_cart( $clear_persistent_cart=true ) {
  81. // empty current cart session
  82. $cart = WC()->cart;
  83. if ( method_exists($cart, 'empty_cart') ) {
  84. $cart->empty_cart($clear_persistent_cart);
  85. }
  86. }
  87. public static function get_cart_appointments() {
  88. $cart = WC()->cart;
  89. if ( method_exists($cart, 'get_cart') ):
  90. $cart_items = $cart->get_cart();
  91. $cart_apps = array(
  92. 'extended' => array(), // app_id::product_id::variation_id
  93. 'ids' => array()
  94. );
  95. $app_id_key = BOOKED_WC_PLUGIN_PREFIX . 'appointment_id';
  96. foreach ($cart_items as $cart_item) {
  97. if ( !isset($cart_item[$app_id_key]) ) {
  98. continue;
  99. }
  100. $app_id = $cart_item[$app_id_key];
  101. $product_id = intval($cart_item['product_id']);
  102. $variation_id = intval($cart_item['variation_id']);
  103. $cart_apps['ids'][] = $app_id;
  104. $cart_apps['extended'][] = "{$app_id}::{$product_id}::{$variation_id}"; // app_id::product_id::variation_id
  105. }
  106. return $cart_apps;
  107. else:
  108. return false;
  109. endif;
  110. }
  111. }
  112. class Booked_WC_Cart_Hooks {
  113. // change the product title on the cart page if it is assigned to a appointment
  114. public static function woocommerce_cart_item_name( $product_title, $cart_item, $cart_item_key ) {
  115. $app_id_key = BOOKED_WC_PLUGIN_PREFIX . 'appointment_id';
  116. if ( !isset($cart_item[$app_id_key]) ) {
  117. return $product_title;
  118. }
  119. $appt_id = intval($cart_item[$app_id_key]);
  120. try {
  121. if ( isset($cart_item['variation_id']) && $cart_item['variation_id'] ):
  122. $variation = wc_get_product($cart_item['variation_id']);
  123. if ( function_exists( 'wc_get_formatted_variation' ) ):
  124. $variation_text = '<br>' . wc_get_formatted_variation( $variation );
  125. else:
  126. $variation_text = '<br>' . $variation->get_formatted_variation_attributes();
  127. endif;
  128. else:
  129. $variation_text = '';
  130. endif;
  131. $appointment = Booked_WC_Appointment::get( $appt_id );
  132. // remove product title link, so the visitors can't acess the product details page
  133. $product_title = '<b>' . preg_replace('~<a[^>]+>([^<]+)</a>~i', '$1', $product_title) . ' &times; ' . $cart_item['quantity'] . '</b>' . $variation_text;
  134. $product_title .= '<div class="booked-wc-checkout-section"><small>' . ucwords( $appointment->timeslot_text ) . '</small></div>';
  135. $product_title .= '<div class="booked-wc-checkout-section">';
  136. // Get the Date
  137. $date_format = get_option('date_format');
  138. $product_title .= '<small><b>' . __('Date', 'booked-woocommerce-payments') . ':</b>&nbsp;' . date_i18n( $date_format, $appointment->timestamp ) . '</small>';
  139. if ( !empty($appointment->calendar) && !empty($appointment->calendar->calendar_obj) ) {
  140. // Get the Calendar Name
  141. $product_title .= '<br><small><b>' . __('Calendar', 'booked-woocommerce-payments') . ':</b>&nbsp;' . $appointment->calendar->calendar_obj->name . '</small>';
  142. // Check for a Booking Agent
  143. $term_meta = get_option( "taxonomy_{$appointment->calendar->calendar_obj->term_id}" );
  144. $assignee_email = $term_meta['notifications_user_id'];
  145. if ( $assignee_email && ($usr=get_user_by('email', $assignee_email)) ) {
  146. $product_title .= '<br><small><b>' . __('Booking Agent', 'booked-woocommerce-payments') . ':</b>&nbsp;' . $usr->display_name . '</small>';
  147. }
  148. }
  149. $custom_fields = (array) $appointment->custom_fields;
  150. foreach ($custom_fields as $field_label => $field_value) {
  151. $product_title .= '<br><small><b>' . $field_label . ':</b>&nbsp;' . $field_value . '</small>';
  152. }
  153. $product_title .= '</div>';
  154. } catch (Exception $e) {
  155. echo '<pre>' . print_r( $e, true ) . '</pre>';
  156. return $product_title;
  157. }
  158. return $product_title;
  159. }
  160. public static function woocommerce_checkout_cart_item_quantity( $quantity , $cart_item , $cart_item_key ) {
  161. $app_id_key = BOOKED_WC_PLUGIN_PREFIX . 'appointment_id';
  162. if ( isset($cart_item[$app_id_key]) ) {
  163. return false;
  164. }
  165. return $quantity;
  166. }
  167. public static function woocommerce_cart_item_thumbnail( $thumbnail, $cart_item ) {
  168. $app_id_key = BOOKED_WC_PLUGIN_PREFIX . 'appointment_id';
  169. if ( isset($cart_item[$app_id_key]) ) {
  170. if ( Booked_WC_Settings::get_option('enable_thumbnails') === 'enable' ) {
  171. return $thumbnail;
  172. } else {
  173. return false;
  174. }
  175. } else {
  176. return $thumbnail;
  177. }
  178. }
  179. // removed the missing appointments from the cart
  180. public static function woocommerce_remove_missing_appointment_products() {
  181. $cart = WC()->cart;
  182. if ( !method_exists($cart, 'remove_cart_item') || !method_exists($cart, 'get_cart') ) {
  183. return;
  184. }
  185. $cart_items = $cart->get_cart();
  186. $app_id_key = BOOKED_WC_PLUGIN_PREFIX . 'appointment_id';
  187. foreach ($cart_items as $cart_item_key => $cart_item) {
  188. if ( !isset($cart_item[$app_id_key]) ) {
  189. continue;
  190. }
  191. $app_id = $cart_item[$app_id_key];
  192. if ( get_post($app_id) ) {
  193. continue;
  194. }
  195. $cart->remove_cart_item($cart_item_key);
  196. }
  197. }
  198. }