1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
|
<?php namespace Automattic\WooCommerce\Blocks\Shipping;
use WC_Shipping_Method;
/** * Local Pickup Shipping Method. */ class PickupLocation extends WC_Shipping_Method {
/** * Pickup locations. * * @var array */ protected $pickup_locations = [];
/** * Cost * * @var string */ protected $cost = '';
/** * Constructor. */ public function __construct() { $this->id = 'pickup_location'; $this->method_title = __( 'Local pickup', 'woocommerce' ); $this->method_description = __( 'Allow customers to choose a local pickup location during checkout.', 'woocommerce' ); $this->init(); }
/** * Init function. */ public function init() { $this->enabled = $this->get_option( 'enabled' ); $this->title = $this->get_option( 'title' ); $this->tax_status = $this->get_option( 'tax_status' ); $this->cost = $this->get_option( 'cost' ); $this->supports = [ 'settings', 'local-pickup' ]; $this->pickup_locations = get_option( $this->id . '_pickup_locations', [] ); add_filter( 'woocommerce_attribute_label', array( $this, 'translate_meta_data' ), 10, 3 ); }
/** * Checks if a given address is complete. * * @param array $address Address. * @return bool */ protected function has_valid_pickup_location( $address ) { // Normalize address. $address_fields = wp_parse_args( (array) $address, array( 'city' => '', 'postcode' => '', 'state' => '', 'country' => '', ) );
// Country is always required. if ( empty( $address_fields['country'] ) ) { return false; }
// If all fields are provided, we can skip further checks. if ( ! empty( $address_fields['city'] ) && ! empty( $address_fields['postcode'] ) && ! empty( $address_fields['state'] ) ) { return true; }
// Check validity based on requirements for the country. $country_address_fields = wc()->countries->get_address_fields( $address_fields['country'], 'shipping_' );
foreach ( $country_address_fields as $field_name => $field ) { $key = str_replace( 'shipping_', '', $field_name );
if ( isset( $address_fields[ $key ] ) && true === $field['required'] && empty( $address_fields[ $key ] ) ) { return false; } }
return true; }
/** * Calculate shipping. * * @param array $package Package information. */ public function calculate_shipping( $package = array() ) { if ( $this->pickup_locations ) { foreach ( $this->pickup_locations as $index => $location ) { if ( ! $location['enabled'] ) { continue; } $this->add_rate( array( 'id' => $this->id . ':' . $index, // This is the label shown in shipping rate/method context e.g. London (Local Pickup). 'label' => wp_kses_post( $this->title . ' (' . $location['name'] . ')' ), 'package' => $package, 'cost' => $this->cost, 'meta_data' => array( 'pickup_location' => wp_kses_post( $location['name'] ), 'pickup_address' => $this->has_valid_pickup_location( $location['address'] ) ? wc()->countries->get_formatted_address( $location['address'], ', ' ) : '', 'pickup_details' => wp_kses_post( $location['details'] ), ), ) ); } } }
/** * See if the method is available. * * @param array $package Package information. * @return bool */ public function is_available( $package ) { // phpcs:ignore WooCommerce.Commenting.CommentHooks.MissingHookComment return apply_filters( 'woocommerce_shipping_' . $this->id . '_is_available', 'yes' === $this->enabled, $package, $this ); }
/** * Translates meta data for the shipping method. * * @param string $label Meta label. * @param string $name Meta key. * @param mixed $product Product if applicable. * @return string */ public function translate_meta_data( $label, $name, $product ) { if ( $product ) { return $label; } switch ( $name ) { case 'pickup_location': return __( 'Pickup location', 'woocommerce' ); case 'pickup_address': return __( 'Pickup address', 'woocommerce' ); } return $label; }
/** * Admin options screen. * * See also WC_Shipping_Method::admin_options(). */ public function admin_options() { global $hide_save_button; $hide_save_button = true;
wp_enqueue_script( 'wc-shipping-method-pickup-location' );
echo '<h2>' . esc_html__( 'Local pickup', 'woocommerce' ) . '</h2>'; echo '<div class="wrap"><div id="wc-shipping-method-pickup-location-settings-container"></div></div>'; } }
|