WC_Shipping_Flat_Rate

Flat Rate Shipping Method.

Defined (1)

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

/includes/shipping/flat-rate/class-wc-shipping-flat-rate.php  
  1. class WC_Shipping_Flat_Rate extends WC_Shipping_Method { 
  2.  
  3. /** @var string cost passed to [fee] shortcode */ 
  4. protected $fee_cost = ''; 
  5.  
  6. /** 
  7. * Constructor. 
  8. */ 
  9. public function __construct( $instance_id = 0 ) { 
  10. $this->id = 'flat_rate'; 
  11. $this->instance_id = absint( $instance_id ); 
  12. $this->method_title = __( 'Flat rate', 'woocommerce' ); 
  13. $this->method_description = __( 'Lets you charge a fixed rate for shipping.', 'woocommerce' ); 
  14. $this->supports = array( 
  15. 'shipping-zones',  
  16. 'instance-settings',  
  17. 'instance-settings-modal',  
  18. ); 
  19. $this->init(); 
  20.  
  21. add_action( 'woocommerce_update_options_shipping_' . $this->id, array( $this, 'process_admin_options' ) ); 
  22.  
  23. /** 
  24. * init user set variables. 
  25. */ 
  26. public function init() { 
  27. $this->instance_form_fields = include( 'includes/settings-flat-rate.php' ); 
  28. $this->title = $this->get_option( 'title' ); 
  29. $this->tax_status = $this->get_option( 'tax_status' ); 
  30. $this->cost = $this->get_option( 'cost' ); 
  31. $this->type = $this->get_option( 'type', 'class' ); 
  32.  
  33. /** 
  34. * Evaluate a cost from a sum/string. 
  35. * @param string $sum 
  36. * @param array $args 
  37. * @return string 
  38. */ 
  39. protected function evaluate_cost( $sum, $args = array() ) { 
  40. include_once( WC()->plugin_path() . '/includes/libraries/class-wc-eval-math.php' ); 
  41.  
  42. // Allow 3rd parties to process shipping cost arguments 
  43. $args = apply_filters( 'woocommerce_evaluate_shipping_cost_args', $args, $sum, $this ); 
  44. $locale = localeconv(); 
  45. $decimals = array( wc_get_price_decimal_separator(), $locale['decimal_point'], $locale['mon_decimal_point'], ', ' ); 
  46. $this->fee_cost = $args['cost']; 
  47.  
  48. // Expand shortcodes 
  49. add_shortcode( 'fee', array( $this, 'fee' ) ); 
  50.  
  51. $sum = do_shortcode( str_replace( 
  52. array( 
  53. '[qty]',  
  54. '[cost]',  
  55. ),  
  56. array( 
  57. $args['qty'],  
  58. $args['cost'],  
  59. ),  
  60. $sum 
  61. ) ); 
  62.  
  63. remove_shortcode( 'fee', array( $this, 'fee' ) ); 
  64.  
  65. // Remove whitespace from string 
  66. $sum = preg_replace( '/\s+/', '', $sum ); 
  67.  
  68. // Remove locale from string 
  69. $sum = str_replace( $decimals, '.', $sum ); 
  70.  
  71. // Trim invalid start/end characters 
  72. $sum = rtrim( ltrim( $sum, "\t\n\r\0\x0B+*/" ), "\t\n\r\0\x0B+-*/" ); 
  73.  
  74. // Do the math 
  75. return $sum ? WC_Eval_Math::evaluate( $sum ) : 0; 
  76.  
  77. /** 
  78. * Work out fee (shortcode). 
  79. * @param array $atts 
  80. * @return string 
  81. */ 
  82. public function fee( $atts ) { 
  83. $atts = shortcode_atts( array( 
  84. 'percent' => '',  
  85. 'min_fee' => '',  
  86. 'max_fee' => '',  
  87. ), $atts, 'fee' ); 
  88.  
  89. $calculated_fee = 0; 
  90.  
  91. if ( $atts['percent'] ) { 
  92. $calculated_fee = $this->fee_cost * ( floatval( $atts['percent'] ) / 100 ); 
  93.  
  94. if ( $atts['min_fee'] && $calculated_fee < $atts['min_fee'] ) { 
  95. $calculated_fee = $atts['min_fee']; 
  96.  
  97. if ( $atts['max_fee'] && $calculated_fee > $atts['max_fee'] ) { 
  98. $calculated_fee = $atts['max_fee']; 
  99.  
  100. return $calculated_fee; 
  101.  
  102. /** 
  103. * calculate_shipping function. 
  104. * @param array $package (default: array()) 
  105. */ 
  106. public function calculate_shipping( $package = array() ) { 
  107. $rate = array( 
  108. 'id' => $this->get_rate_id(),  
  109. 'label' => $this->title,  
  110. 'cost' => 0,  
  111. 'package' => $package,  
  112. ); 
  113.  
  114. // Calculate the costs 
  115. $has_costs = false; // True when a cost is set. False if all costs are blank strings. 
  116. $cost = $this->get_option( 'cost' ); 
  117.  
  118. if ( '' !== $cost ) { 
  119. $has_costs = true; 
  120. $rate['cost'] = $this->evaluate_cost( $cost, array( 
  121. 'qty' => $this->get_package_item_qty( $package ),  
  122. 'cost' => $package['contents_cost'],  
  123. ) ); 
  124.  
  125. // Add shipping class costs. 
  126. $shipping_classes = WC()->shipping->get_shipping_classes(); 
  127.  
  128. if ( ! empty( $shipping_classes ) ) { 
  129. $found_shipping_classes = $this->find_shipping_classes( $package ); 
  130. $highest_class_cost = 0; 
  131.  
  132. foreach ( $found_shipping_classes as $shipping_class => $products ) { 
  133. // Also handles BW compatibility when slugs were used instead of ids 
  134. $shipping_class_term = get_term_by( 'slug', $shipping_class, 'product_shipping_class' ); 
  135. $class_cost_string = $shipping_class_term && $shipping_class_term->term_id ? $this->get_option( 'class_cost_' . $shipping_class_term->term_id, $this->get_option( 'class_cost_' . $shipping_class, '' ) ) : $this->get_option( 'no_class_cost', '' ); 
  136.  
  137. if ( '' === $class_cost_string ) { 
  138. continue; 
  139.  
  140. $has_costs = true; 
  141. $class_cost = $this->evaluate_cost( $class_cost_string, array( 
  142. 'qty' => array_sum( wp_list_pluck( $products, 'quantity' ) ),  
  143. 'cost' => array_sum( wp_list_pluck( $products, 'line_total' ) ),  
  144. ) ); 
  145.  
  146. if ( 'class' === $this->type ) { 
  147. $rate['cost'] += $class_cost; 
  148. } else { 
  149. $highest_class_cost = $class_cost > $highest_class_cost ? $class_cost : $highest_class_cost; 
  150.  
  151. if ( 'order' === $this->type && $highest_class_cost ) { 
  152. $rate['cost'] += $highest_class_cost; 
  153.  
  154. // Add the rate 
  155. if ( $has_costs ) { 
  156. $this->add_rate( $rate ); 
  157.  
  158. /** 
  159. * Developers can add additional flat rates based on this one via this action since @version 2.4. 
  160. * Previously there were (overly complex) options to add additional rates however this was not user. 
  161. * friendly and goes against what Flat Rate Shipping was originally intended for. 
  162. * This example shows how you can add an extra rate based on this flat rate via custom function: 
  163. * add_action( 'woocommerce_flat_rate_shipping_add_rate', 'add_another_custom_flat_rate', 10, 2 ); 
  164. * function add_another_custom_flat_rate( $method, $rate ) { 
  165. * $new_rate = $rate; 
  166. * $new_rate['id'] .= ':' . 'custom_rate_name'; // Append a custom ID. 
  167. * $new_rate['label'] = 'Rushed Shipping'; // Rename to 'Rushed Shipping'. 
  168. * $new_rate['cost'] += 2; // Add $2 to the cost. 
  169. * // Add it to WC. 
  170. * $method->add_rate( $new_rate ); 
  171. * }. 
  172. */ 
  173. do_action( 'woocommerce_' . $this->id . '_shipping_add_rate', $this, $rate ); 
  174.  
  175. /** 
  176. * Get items in package. 
  177. * @param array $package 
  178. * @return int 
  179. */ 
  180. public function get_package_item_qty( $package ) { 
  181. $total_quantity = 0; 
  182. foreach ( $package['contents'] as $item_id => $values ) { 
  183. if ( $values['quantity'] > 0 && $values['data']->needs_shipping() ) { 
  184. $total_quantity += $values['quantity']; 
  185. return $total_quantity; 
  186.  
  187. /** 
  188. * Finds and returns shipping classes and the products with said class. 
  189. * @param mixed $package 
  190. * @return array 
  191. */ 
  192. public function find_shipping_classes( $package ) { 
  193. $found_shipping_classes = array(); 
  194.  
  195. foreach ( $package['contents'] as $item_id => $values ) { 
  196. if ( $values['data']->needs_shipping() ) { 
  197. $found_class = $values['data']->get_shipping_class(); 
  198.  
  199. if ( ! isset( $found_shipping_classes[ $found_class ] ) ) { 
  200. $found_shipping_classes[ $found_class ] = array(); 
  201.  
  202. $found_shipping_classes[ $found_class ][ $item_id ] = $values; 
  203.  
  204. return $found_shipping_classes;