class-wc-cart-fees.php 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. <?php
  2. /**
  3. * Cart fees API.
  4. *
  5. * Developers can add fees to the cart via WC()->cart->fees_api() which will reference this class.
  6. *
  7. * We suggest using the action woocommerce_cart_calculate_fees hook for adding fees.
  8. *
  9. * @package WooCommerce/Classes
  10. * @version 3.2.0
  11. */
  12. defined( 'ABSPATH' ) || exit;
  13. /**
  14. * WC_Cart_Fees class.
  15. *
  16. * @since 3.2.0
  17. */
  18. final class WC_Cart_Fees {
  19. /**
  20. * An array of fee objects.
  21. *
  22. * @var object[]
  23. */
  24. private $fees = array();
  25. /**
  26. * Reference to cart object.
  27. *
  28. * @since 3.2.0
  29. * @var WC_Cart
  30. */
  31. private $cart;
  32. /**
  33. * New fees are made out of these props.
  34. *
  35. * @var array
  36. */
  37. private $default_fee_props = array(
  38. 'id' => '',
  39. 'name' => '',
  40. 'tax_class' => '',
  41. 'taxable' => false,
  42. 'amount' => 0,
  43. 'total' => 0,
  44. );
  45. /**
  46. * Constructor. Reference to the cart.
  47. *
  48. * @since 3.2.0
  49. * @throws Exception If missing WC_Cart object.
  50. * @param WC_Cart $cart Cart object.
  51. */
  52. public function __construct( &$cart ) {
  53. if ( ! is_a( $cart, 'WC_Cart' ) ) {
  54. throw new Exception( 'A valid WC_Cart object is required' );
  55. }
  56. $this->cart = $cart;
  57. }
  58. /**
  59. * Register methods for this object on the appropriate WordPress hooks.
  60. */
  61. public function init() {}
  62. /**
  63. * Add a fee. Fee IDs must be unique.
  64. *
  65. * @since 3.2.0
  66. * @param array $args Array of fee properties.
  67. * @return object Either a fee object if added, or a WP_Error if it failed.
  68. */
  69. public function add_fee( $args = array() ) {
  70. $fee_props = (object) wp_parse_args( $args, $this->default_fee_props );
  71. $fee_props->name = $fee_props->name ? $fee_props->name : __( 'Fee', 'woocommerce' );
  72. $fee_props->tax_class = in_array( $fee_props->tax_class, array_merge( WC_Tax::get_tax_classes(), WC_Tax::get_tax_class_slugs() ), true ) ? $fee_props->tax_class : '';
  73. $fee_props->taxable = wc_string_to_bool( $fee_props->taxable );
  74. $fee_props->amount = wc_format_decimal( $fee_props->amount );
  75. if ( empty( $fee_props->id ) ) {
  76. $fee_props->id = $this->generate_id( $fee_props );
  77. }
  78. if ( array_key_exists( $fee_props->id, $this->fees ) ) {
  79. return new WP_Error( 'fee_exists', __( 'Fee has already been added.', 'woocommerce' ) );
  80. }
  81. $this->fees[ $fee_props->id ] = $fee_props;
  82. return $this->fees[ $fee_props->id ];
  83. }
  84. /**
  85. * Get fees.
  86. *
  87. * @return array
  88. */
  89. public function get_fees() {
  90. uasort( $this->fees, array( $this, 'sort_fees_callback' ) );
  91. return $this->fees;
  92. }
  93. /**
  94. * Set fees.
  95. *
  96. * @param object[] $raw_fees Array of fees.
  97. */
  98. public function set_fees( $raw_fees = array() ) {
  99. $this->fees = array();
  100. foreach ( $raw_fees as $raw_fee ) {
  101. $this->add_fee( $raw_fee );
  102. }
  103. }
  104. /**
  105. * Remove all fees.
  106. *
  107. * @since 3.2.0
  108. */
  109. public function remove_all_fees() {
  110. $this->set_fees();
  111. }
  112. /**
  113. * Sort fees by amount.
  114. *
  115. * @param WC_Coupon $a Coupon object.
  116. * @param WC_Coupon $b Coupon object.
  117. * @return int
  118. */
  119. protected function sort_fees_callback( $a, $b ) {
  120. return ( $a->amount > $b->amount ) ? -1 : 1;
  121. }
  122. /**
  123. * Generate a unique ID for the fee being added.
  124. *
  125. * @param string $fee Fee object.
  126. * @return string fee key.
  127. */
  128. private function generate_id( $fee ) {
  129. return sanitize_title( $fee->name );
  130. }
  131. }