PluginProbe ʕ •ᴥ•ʔ
Weight Based Shipping Table Rate for WooCommerce – Flexible Shipping / 6.10.0
Weight Based Shipping Table Rate for WooCommerce – Flexible Shipping v6.10.0
6.10.0 6.9.1 6.9.0 6.8.1 6.8.0 6.7.4 6.7.3 6.7.2 6.7.0 4.21.7 4.22.0 4.22.1 4.23.0 4.23.1 4.23.2 4.23.3 4.24.0 4.24.1 4.24.10 4.24.11 4.24.12 4.24.13 4.24.14 4.24.15 4.24.16 4.24.17 4.24.18 4.24.19 4.24.2 4.24.4 4.24.6 4.24.7 4.24.8 4.24.9 4.25.0 4.25.1 4.25.2 4.25.4 4.25.5 4.25.6 4.25.7 4.25.8 4.3.0 4.3.1 4.4.0 4.4.1 4.5.0 4.5.1 4.6.0 4.6.1 4.7.0 4.7.1 4.7.2 4.8.0 4.8.1 4.8.3 4.8.4 4.8.5 4.9.0 5.0.0 5.0.1 5.0.2 5.0.3 5.0.4 5.0.5 5.0.6 5.0.7 5.0.8 5.0.9 5.1.0 5.1.1 5.1.2 5.1.3 5.2.0 5.3.0 5.3.1 5.3.3 5.3.4 5.3.5 6.0.0 6.1.0 6.1.1 6.1.2 6.2.0 6.2.1 6.2.2 6.2.3 6.2.4 6.3.0 trunk 6.4.0 1.4 6.4.1 1.4.1 6.4.2 1.5 6.4.3 1.6 6.4.5 1.6.1 6.5.0 1.6.2 6.5.1 1.7 6.5.2 1.8 6.5.3 1.9 6.5.4 1.9.1 6.5.5 1.9.10 6.5.6 1.9.11 6.5.7 1.9.12 6.5.8 1.9.2 6.6.0 1.9.3 6.6.1 1.9.4 6.6.2 1.9.5 1.9.6 1.9.7 1.9.8 1.9.9 2.0 2.0.1 2.1 2.1.1 2.1.10 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.1.9 3.0.6 3.0.7 3.1 3.1.1 3.1.10 3.1.11 3.1.12 3.1.2 3.1.3 3.1.4 3.1.5 3.1.6 3.1.7 3.1.8 3.1.9 3.10.0 3.11.0 3.11.1 3.11.2 3.11.3 3.11.4 3.12.0 3.13.0 3.14.0 3.14.1 3.14.2 3.14.3 3.14.4 3.15.0 3.16.0 3.16.1 3.16.2 3.16.3 3.16.4 3.16.5 3.2.0 3.3.1 3.3.10 3.3.11 3.3.12 3.3.13 3.3.14 3.3.2 3.3.3 3.3.4 3.3.5 3.3.6 3.3.7 3.3.8 3.3.9 3.4.0 3.5.0 3.5.1 3.6.0 3.6.1 3.6.2 3.6.3 3.6.4 3.7.0 3.8.0 3.9.0 3.9.1 3.9.10 3.9.11 3.9.12 3.9.13 3.9.15 3.9.16 3.9.17 3.9.18 3.9.19 3.9.2 3.9.20 3.9.21 3.9.3 3.9.4 3.9.5 3.9.6 3.9.7 3.9.9 4.0.0 4.0.1 4.0.10 4.0.2 4.0.3 4.0.4 4.0.5 4.0.6 4.0.7 4.0.8 4.0.9 4.1.0 4.1.1 4.1.2 4.1.3 4.1.4 4.10.0 4.10.1 4.11.0 4.11.1 4.11.2 4.11.3 4.11.4 4.11.5 4.11.6 4.11.7 4.11.8 4.11.9 4.12.0 4.13.0 4.13.1 4.13.2 4.13.3 4.14.0 4.14.1 4.14.2 4.15.0 4.16.0 4.16.1 4.16.2 4.17.0 4.18.0 4.18.1 4.18.2 4.18.3 4.18.4 4.18.5 4.18.6 4.19.0 4.19.1 4.2.0 4.20.0 4.20.1 4.20.2 4.20.3 4.21.0 4.21.1 4.21.2 4.21.3 4.21.4 4.21.5
flexible-shipping / src / WPDesk / FS / TableRate / ShippingMethod / RateCalculator.php
flexible-shipping / src / WPDesk / FS / TableRate / ShippingMethod Last commit date
BlockEditing 3 days ago Convert 3 days ago Duplicate 3 days ago Management 3 days ago Timestamps 3 days ago Tracker 3 days ago views 3 days ago CommonMethodSettings.php 3 days ago FreeShippingCalculator.php 3 days ago FreeShippingThresholdRuleValidator.php 3 days ago MethodDescription.php 3 days ago MethodLogo.php 3 days ago MethodLogoCheckoutBlocksAssets.php 3 days ago MethodLogoSettingsField.php 3 days ago MethodSettings.php 3 days ago MethodTitle.php 3 days ago RateCalculator.php 3 days ago RateCalculatorFactory.php 3 days ago SettingsDisplayPreparer.php 3 days ago SettingsProcessor.php 3 days ago SingleMethodSettings.php 3 days ago
RateCalculator.php
395 lines
1 <?php
2 /**
3 * Class RateCalculator
4 *
5 * @package WPDesk\FS\TableRate\ShippingMethod
6 */
7
8 namespace WPDesk\FS\TableRate\ShippingMethod;
9
10 use FSVendor\WPDesk\Forms\Field;
11 use FSVendor\WPDesk\FS\TableRate\Settings\CartCalculationOptions;
12 use FSVendor\WPDesk\FS\TableRate\Settings\MethodSettingsImplementation;
13 use FSVendor\Psr\Log\LoggerInterface;
14 use FSVendor\Psr\Log\NullLogger;
15 use WC_Cart;
16 use WC_Shipping_Method;
17 use WPDesk\FS\TableRate\Rule\Condition\Condition;
18 use WPDesk\FS\TableRate\Rule\Cost\AdditionalCost;
19 use WPDesk\FS\TableRate\Rule\CostsCalculator;
20 use WPDesk\FS\TableRate\Rule\ShippingContents\DestinationAddressFactory;
21 use WPDesk\FS\TableRate\Rule\ShippingContents\ShippingContents;
22 use WPDesk\FS\TableRate\Rule\ShippingContents\ShippingContentsImplementation;
23 use WPDesk\FS\TableRate\Rule\SpecialAction\SpecialAction;
24 use WPDesk_Flexible_Shipping;
25
26 /**
27 * Can calculate single shipping rate.
28 */
29 class RateCalculator {
30
31 const FS_INTEGRATION = '_fs_integration';
32 const FS_METHOD = '_fs_method';
33 const DESCRIPTION = 'description';
34 const DESCRIPTION_BASE64ENCODED = 'description_base64encoded';
35 const METHOD_LOGO_URL = 'method_logo_url';
36 const METHOD_LOGO_ALT = 'method_logo_alt';
37
38 /**
39 * @var LoggerInterface
40 */
41 private $logger;
42
43 /**
44 * @var WC_Shipping_Method
45 */
46 private $shipping_method;
47
48 /**
49 * @var string
50 */
51 private $shop_currency;
52
53 /**
54 * @var string
55 */
56 private $cart_currency;
57
58 /**
59 * @var Condition[]
60 */
61 private $available_conditions;
62
63 /**
64 * @var Field[]
65 */
66 private $cost_fields;
67
68 /**
69 * @var AdditionalCost
70 */
71 private $available_additional_costs;
72
73 /**
74 * @var SpecialAction[]
75 */
76 private $available_special_actions;
77
78 /**
79 * @var int
80 */
81 private $cost_rounding_precision;
82
83 /**
84 * @var bool
85 */
86 private $prices_includes_tax;
87
88 /**
89 * @var WC_Cart
90 */
91 private $cart;
92
93 /**
94 * @var ShippingContents
95 */
96 private $cart_contents;
97
98 /**
99 * @var array
100 */
101 private $package;
102
103 /**
104 * @var FreeShippingCalculator
105 */
106 private $free_shipping_calculator;
107
108 /**
109 * RateCalculator constructor.
110 *
111 * @param WC_Shipping_Method $shipping_method .
112 * @param string $shop_currency .
113 * @param string $cart_currency .
114 * @param Condition[] $available_conditions .
115 * @param Field[] $cost_fields .
116 * @param AdditionalCost[] $available_additional_costs .
117 * @param SpecialAction[] $available_special_actions .
118 * @param int $cost_rounding_precision .
119 * @param bool $prices_includes_tax .
120 * @param WC_Cart $cart .
121 * @param ShippingContents $cart_contents .
122 * @param array $package .
123 * @param FreeShippingCalculator $free_shipping_calculator .
124 */
125 public function __construct(
126 WC_Shipping_Method $shipping_method,
127 $shop_currency,
128 $cart_currency,
129 array $available_conditions,
130 array $cost_fields,
131 array $available_additional_costs,
132 array $available_special_actions,
133 $cost_rounding_precision,
134 $prices_includes_tax,
135 WC_Cart $cart,
136 ShippingContents $cart_contents,
137 array $package,
138 FreeShippingCalculator $free_shipping_calculator
139 ) {
140 $this->shipping_method = $shipping_method;
141 $this->shop_currency = $shop_currency;
142 $this->cart_currency = $cart_currency;
143 $this->available_conditions = $available_conditions;
144 $this->cost_fields = $cost_fields;
145 $this->available_additional_costs = $available_additional_costs;
146 $this->available_special_actions = $available_special_actions;
147 $this->cost_rounding_precision = $cost_rounding_precision;
148 $this->prices_includes_tax = $prices_includes_tax;
149 $this->cart = $cart;
150 $this->cart_contents = $cart_contents;
151 $this->package = $package;
152 $this->free_shipping_calculator = $free_shipping_calculator;
153 }
154
155 /**
156 * @param LoggerInterface $logger .
157 */
158 public function set_logger( LoggerInterface $logger ) {
159 $this->logger = $logger;
160 }
161
162 /**
163 * @return LoggerInterface
164 */
165 public function get_logger() {
166 if ( null === $this->logger ) {
167 $this->logger = new NullLogger();
168 }
169
170 return $this->logger;
171 }
172
173 /**
174 * @param MethodSettingsImplementation $method_settings .
175 * @param string $rate_id .
176 * @param bool $user_logged_in .
177 *
178 * @return array
179 */
180 public function calculate_rate( MethodSettingsImplementation $method_settings, $rate_id, $user_logged_in ) {
181 $logger = $this->get_logger();
182
183 $logger->debug( $method_settings->format_for_log(), $logger->get_configuration_section_context() );
184
185 $add_method = true;
186 if ( 'yes' === $method_settings->get_visibility() && ! $user_logged_in ) {
187 $logger->debug( __( 'Method available only for logged in users, but user is not logged in.', 'flexible-shipping' ), $logger->get_results_context() );
188 $add_method = false;
189 }
190
191 if ( $add_method ) {
192 if ( $this->shop_currency !== $this->cart_currency ) {
193 // Translators: shop currency.
194 $logger->debug( sprintf( __( 'Shop currency: %1$s', 'flexible-shipping' ), $this->shop_currency ), $logger->get_input_data_context() );
195 // Translators: cart currency.
196 $logger->debug( sprintf( __( 'Cart currency: %1$s', 'flexible-shipping' ), $this->cart_currency ), $logger->get_input_data_context() );
197 }
198
199 if ( CartCalculationOptions::PACKAGE === $method_settings->get_cart_calculation() ) {
200 $shipping_contents = new ShippingContentsImplementation(
201 $this->package['contents'],
202 $this->prices_includes_tax,
203 $this->cost_rounding_precision,
204 DestinationAddressFactory::create_from_package_destination( $this->package['destination'] ),
205 get_woocommerce_currency()
206 );
207 } else {
208 $shipping_contents = $this->cart_contents;
209 }
210
211 /**
212 * @return ShippingContents
213 */
214 $shipping_contents = apply_filters( 'flexible_shipping_shipping_contents', $shipping_contents, $method_settings->get_raw_settings(), $this->cart, $this->package );
215
216 if ( ! $shipping_contents instanceof ShippingContents || empty( $shipping_contents->get_contents() ) ) {
217 $logger->debug( __( 'Empty contents', 'flexible-shipping' ) );
218
219 return [];
220 }
221
222 do_action( 'flexible-shipping/rate-calculator/before', $shipping_contents, $method_settings, $logger );
223
224 // Translators: contents value.
225 $logger->debug( sprintf( __( 'Contents value: %1$s %2$s', 'flexible-shipping' ), $shipping_contents->get_contents_cost(), $shipping_contents->get_currency() ), $logger->get_input_data_context() );
226 // Translators: contents weight.
227 $logger->debug( sprintf( __( 'Contents weight: %1$s', 'flexible-shipping' ), wc_format_weight( $shipping_contents->get_contents_weight() ) ), $logger->get_input_data_context() );
228
229 $rate = $this->calculate_rate_for_rates( $method_settings, $shipping_contents, $rate_id, $logger );
230
231 do_action( 'flexible-shipping/rate-calculator/log', $logger );
232 } else {
233 $rate = [];
234 }
235
236 return $rate;
237 }
238
239 /**
240 * @param MethodSettingsImplementation $method_settings .
241 * @param ShippingContents $shipping_contents .
242 * @param string $rate_id .
243 * @param LoggerInterface $logger .
244 *
245 * @return array
246 */
247 private function calculate_rate_for_rates( MethodSettingsImplementation $method_settings, ShippingContents $shipping_contents, $rate_id, LoggerInterface $logger ) {
248 $cost_calculator = new CostsCalculator(
249 $method_settings,
250 $shipping_contents,
251 $this->available_conditions,
252 $this->cost_fields,
253 $this->available_additional_costs,
254 $this->available_special_actions,
255 $this->cost_rounding_precision,
256 $this->shop_currency,
257 $logger
258 );
259
260 $cost_calculator->process_rules();
261 $add_method = $cost_calculator->is_triggered();
262
263 // Translators: add method.
264 $logger->debug( sprintf( __( 'Used and displayed in the cart/checkout: %1$s', 'flexible-shipping' ), $add_method ? __( 'yes', 'flexible-shipping' ) : __( 'no', 'flexible-shipping' ) ), $logger->get_results_context() );
265 $add_method_before_filters = $add_method;
266
267 $add_method = apply_filters( 'flexible_shipping_add_method', $add_method, $method_settings->get_raw_settings(), $this->package, $this->shipping_method );
268 if ( $add_method_before_filters !== $add_method ) {
269 // Translators: add method.
270 $logger->debug( sprintf( __( 'Used and displayed in the cart/checkout after filters: %1$s', 'flexible-shipping' ), $add_method ? __( 'yes', 'flexible-shipping' ) : __( 'no', 'flexible-shipping' ) ), $logger->get_results_context() );
271 }
272
273 if ( $add_method ) {
274 $cost = $this->set_zero_cost_if_negative( $cost_calculator->get_calculated_cost() );
275
276 // Translators: cost, currency.
277 $logger->debug( sprintf( __( 'Calculated shipping cost: %1$s %2$s', 'flexible-shipping' ), $cost, $this->shop_currency ), $logger->get_results_context() );
278
279 $is_free_shipping = $this->free_shipping_calculator->is_free_shipping( $method_settings, $this->cart_contents->get_contents_cost() );
280 // Translators: free shipping.
281 $logger->debug( sprintf( __( 'Free shipping: %1$s', 'flexible-shipping' ), $is_free_shipping ? __( 'yes', 'flexible-shipping' ) : __( 'no', 'flexible-shipping' ) ), $logger->get_results_context() );
282
283 if ( $is_free_shipping ) {
284 $cost = 0.0;
285 // Translators: shipping cost after free shipping.
286 $logger->debug( sprintf( __( 'Shipping cost after free shipping applied: %1$s', 'flexible-shipping' ), $cost ), $logger->get_results_context() );
287 }
288
289 // Translators: method id.
290 $logger->debug( sprintf( __( 'Shipping method ID: %1$s', 'flexible-shipping' ), $rate_id ), $logger->get_results_context() );
291
292 $method_title = $this->get_single_method_title( $method_settings->get_raw_settings(), $cost );
293 // Translators: method title.
294 $logger->debug( sprintf( __( 'Shipping method title: %1$s', 'flexible-shipping' ), $method_title ), $logger->get_results_context() );
295
296 $rate = [
297 'id' => $rate_id,
298 'label' => $method_title,
299 'cost' => $cost,
300 'package' => $this->package,
301 'meta_data' => $this->prepare_meta_data( $method_settings ),
302 ];
303 } else {
304 $rate = [];
305 }
306
307 return $rate;
308 }
309
310 /**
311 * @param float $cost .
312 *
313 * @return float
314 */
315 private function set_zero_cost_if_negative( $cost ) {
316 $allow_negative_costs = (bool) apply_filters( 'flexible-shipping/shipping-method/allow-negative-costs', false );
317
318 if ( ! $allow_negative_costs && 0.0 > (float) $cost ) {
319 $cost = 0.0;
320 }
321
322 return (float) $cost;
323 }
324
325 /**
326 * @param MethodSettingsImplementation $method_settings .
327 *
328 * @return array
329 */
330 private function prepare_meta_data( MethodSettingsImplementation $method_settings ) {
331 $description = $this->get_method_description( $method_settings );
332 $logo_data = MethodLogo::get_logo_data( $method_settings->get_raw_settings() );
333
334 $meta_data = [
335 WPDesk_Flexible_Shipping::META_DEFAULT => $method_settings->get_default(),
336 self::FS_METHOD => $method_settings->get_raw_settings(),
337 self::FS_INTEGRATION => $method_settings->get_integration(),
338 self::DESCRIPTION => $description,
339 ];
340
341 if ( ! apply_filters( 'flexible-shipping/order-meta-data/keep-method-rules', false, $meta_data ) ) {
342 unset( $meta_data[ self::FS_METHOD ][ CommonMethodSettings::METHOD_RULES ] );
343 }
344
345 if ( esc_html( $description ) !== $description ) {
346 $meta_data[ self::DESCRIPTION_BASE64ENCODED ] = base64_encode( $description );
347 }
348
349 if ( '' !== $logo_data['url'] ) {
350 $meta_data[ self::METHOD_LOGO_URL ] = $logo_data['url'];
351 $meta_data[ self::METHOD_LOGO_ALT ] = $logo_data['alt'];
352 }
353
354 /**
355 * Rate metadata.
356 *
357 * @param array $meta_data .
358 * @param array $method_settings .
359 *
360 * @return array
361 */
362 return apply_filters( 'flexible-shipping/rate/meta_data', $meta_data, $method_settings->get_raw_settings() );
363 }
364
365 /**
366 * @param MethodSettingsImplementation $method_settings .
367 *
368 * @return string
369 */
370 private function get_method_description( MethodSettingsImplementation $method_settings ) {
371 return wp_kses_post( wpdesk__( $method_settings->get_description(), 'flexible-shipping' ) );
372 }
373
374 /**
375 * @param array $shipping_method .
376 * @param float $cost .
377 *
378 * @return mixed|string|void
379 */
380 private function get_single_method_title( $shipping_method, $cost ) {
381 $method_title = wpdesk__( $shipping_method['method_title'], 'flexible-shipping' );
382
383 if ( 0.0 >= (float) $cost ) {
384 if ( ! isset( $shipping_method['method_free_shipping_label'] ) ) {
385 $shipping_method['method_free_shipping_label'] = __( 'Free', 'flexible-shipping' );
386 }
387 if ( '' !== $shipping_method['method_free_shipping_label'] ) {
388 $method_title .= ' (' . wpdesk__( $shipping_method['method_free_shipping_label'], 'flexible-shipping' ) . ')';
389 }
390 }
391
392 return $method_title;
393 }
394 }
395