PluginProbe
PayPlug for WooCommerce (Official) / 2.18.0
PayPlug for WooCommerce (Official) v2.18.0
3.0.0 2.18.0 1.0.17 1.0.18 1.0.19 1.0.20 1.0.21 1.0.22 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.0.8 1.1.0 1.10.0 1.10.1 1.2.1 1.2.10 1.2.11 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 All 101 releases
payplug / src / Gateway / PayplugAddressData.php

PayplugAddressData.php in PayPlug for WooCommerce (Official) 2.18.0, at src/Gateway/PayplugAddressData.php

313 lines 12.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Payplug\PayplugWoocommerce\Gateway;
4
5 // Exit if accessed directly
6 if (!defined('ABSPATH')) {
7 exit;
8 }
9
10 use libphonenumber\PhoneNumberFormat;
11 use libphonenumber\PhoneNumberType;
12 use libphonenumber\PhoneNumberUtil;
13 use Payplug\PayplugWoocommerce\PayplugWoocommerceHelper;
14
15 class PayplugAddressData
16 {
17 const DELIVERY_TYPE_BILLING = 'BILLING';
18 const DELIVERY_TYPE_VERIFIED = 'VERIFIED';
19 const DELIVERY_TYPE_NEW = 'NEW';
20 const DELIVERY_TYPE_SHIP_TO_STORE = 'SHIP_TO_STORE';
21 const DELIVERY_TYPE_DIGITAL_GOODS = 'DIGITAL_GOODS';
22 const DELIVERY_TYPE_TRAVEL_OR_EVENT = 'TRAVEL_OR_EVENT';
23 const DELIVERY_TYPE_OTHER = 'OTHER';
24
25 public static $address_fields = [
26 'address1',
27 'address2',
28 'postcode',
29 'city',
30 'state',
31 'country',
32 ];
33
34 /**
35 * @var array
36 */
37 protected $billing;
38
39 /**
40 * @var array
41 */
42 protected $shipping;
43
44 /**
45 * Get address data from order.
46 *
47 * @param $order
48 *
49 * @throws \InvalidArgumentException
50 *
51 * @return PayplugAddressData
52 */
53 public static function from_order($order)
54 {
55 if (!is_a($order, '\WC_Order')) {
56 throw new \InvalidArgumentException(
57 sprintf('Expected WC_Order object, got %s', get_class($order))
58 );
59 }
60
61 $address_data = new self();
62 $address_data->prepare_address_data($order);
63
64 return $address_data;
65 }
66
67 /**
68 * Check if an address has already been used by a customer
69 *
70 * @param int $customer
71 * @param string $hash
72 *
73 * @return bool
74 */
75 public static function address_already_used($customer, $hash)
76 {
77 $hash_list = self::get_customer_addresses_hash($customer);
78
79 return !empty($hash_list) && in_array($hash, $hash_list);
80 }
81
82 /**
83 * Get the list of hash of all addresses used by the customer
84 *
85 * @param int $customer
86 *
87 * @return array
88 */
89 public static function get_customer_addresses_hash($customer)
90 {
91 $hash_list = get_user_meta($customer, 'payplug_addresses_hash', true);
92
93 return is_array($hash_list) ? $hash_list : [];
94 }
95
96 /**
97 * Update the list of hash of all addresses used by the customer
98 *
99 * @param int $customer
100 * @param array $hash_list
101 *
102 * @return bool
103 */
104 public static function update_customer_addresses_hash($customer, $hash_list)
105 {
106 $result = update_user_meta($customer, 'payplug_addresses_hash', $hash_list);
107
108 return false !== $result;
109 }
110
111 /**
112 * Hash an address
113 *
114 * @param array $address
115 *
116 * @return string
117 */
118 public static function hash_address($address)
119 {
120 $to_hash = '';
121 foreach (self::$address_fields as $field) {
122 if (empty($address[$field])) {
123 continue;
124 }
125
126 $to_hash .= strtolower(remove_accents($address[$field]));
127 }
128
129 return md5($to_hash);
130 }
131
132 /**
133 * Get billing data.
134 *
135 * @return array|null
136 */
137 public function get_billing()
138 {
139 return (!empty($this->billing)) ? $this->billing : null;
140 }
141
142 /**
143 * Get shipping data.
144 *
145 * @return array|null
146 */
147 public function get_shipping()
148 {
149 return (!empty($this->shipping)) ? $this->shipping : null;
150 }
151
152 /**
153 * Prepare data for billing and shipping.
154 *
155 * @param \WC_Order $order
156 */
157 protected function prepare_address_data($order)
158 {
159 $customer = PayplugWoocommerceHelper::is_pre_30() ? $order->customer_user : $order->get_customer_id();
160
161 $billing_first_name = PayplugWoocommerceHelper::is_pre_30() ? $order->billing_first_name : $order->get_billing_first_name();
162 $billing_last_name = PayplugWoocommerceHelper::is_pre_30() ? $order->billing_last_name : $order->get_billing_last_name();
163 $billing_email = PayplugWoocommerceHelper::is_pre_30() ? $order->billing_email : $order->get_billing_email();
164 $billing_address1 = PayplugWoocommerceHelper::is_pre_30() ? $order->billing_address_1 : $order->get_billing_address_1();
165 $billing_address2 = PayplugWoocommerceHelper::is_pre_30() ? $order->billing_address_2 : $order->get_billing_address_2();
166 $billing_postcode = PayplugWoocommerceHelper::is_pre_30() ? $order->billing_postcode : $order->get_billing_postcode();
167 $billing_city = PayplugWoocommerceHelper::is_pre_30() ? $order->billing_city : $order->get_billing_city();
168 $billing_country = PayplugWoocommerceHelper::is_pre_30() ? $order->billing_country : $order->get_billing_country();
169 $billing_company = PayplugWoocommerceHelper::is_pre_30() ? $order->billing_company : $order->get_billing_company();
170 if (empty($billing_company)) {
171 $billing_company = $billing_first_name . ' ' . $billing_last_name;
172 }
173
174 if (!PayplugWoocommerceHelper::is_country_supported($billing_country)) {
175 $billing_country = PayplugWoocommerceHelper::get_default_country();
176 }
177
178 $this->billing = [
179 'first_name' => $this->limit_length($billing_first_name),
180 'last_name' => $this->limit_length($billing_last_name),
181 'email' => $this->limit_length($billing_email, 255),
182 'address1' => $this->limit_length($billing_address1, 255),
183 'postcode' => $this->limit_length($billing_postcode, 16),
184 'city' => $this->limit_length($billing_city),
185 'country' => $this->limit_length($billing_country, 2),
186 'company_name' => $this->limit_length($billing_company),
187 ];
188
189 if (!empty($billing_address2)) {
190 $this->billing['address2'] = $this->limit_length($billing_address2, 255);
191 }
192
193 // We need to know if current cart contain products we will be shipped to the customer
194 // to set the correct `delivery_type` value
195 if ($order->needs_shipping_address()) {
196 $has_shipping_address = PayplugWoocommerceHelper::is_pre_30()
197 ? $order->shipping_address_1
198 : $order->get_shipping_address_1();
199
200 if ($has_shipping_address && !wc_ship_to_billing_address_only()) {
201 $shipping_first_name = PayplugWoocommerceHelper::is_pre_30() ? $order->shipping_first_name : $order->get_shipping_first_name();
202 $shipping_last_name = PayplugWoocommerceHelper::is_pre_30() ? $order->shipping_last_name : $order->get_shipping_last_name();
203 // Using email from billing address since Woocommerce doesn't provide one for the shipping address by default.
204 $shipping_email = PayplugWoocommerceHelper::is_pre_30() ? $order->billing_email : $order->get_billing_email();
205 $shipping_address1 = PayplugWoocommerceHelper::is_pre_30() ? $order->shipping_address_1 : $order->get_shipping_address_1();
206 $shipping_address2 = PayplugWoocommerceHelper::is_pre_30() ? $order->shipping_address_2 : $order->get_shipping_address_2();
207 $shipping_postcode = PayplugWoocommerceHelper::is_pre_30() ? $order->shipping_postcode : $order->get_shipping_postcode();
208 $shipping_city = PayplugWoocommerceHelper::is_pre_30() ? $order->shipping_city : $order->get_shipping_city();
209 $shipping_country = PayplugWoocommerceHelper::is_pre_30() ? $order->shipping_country : $order->get_shipping_country();
210 $shipping_company = PayplugWoocommerceHelper::is_pre_30() ? $order->shipping_company : $order->get_shipping_company();
211
212 if (empty($shipping_company)) {
213 $shipping_company = $shipping_first_name . ' ' . $shipping_last_name;
214 }
215
216 if (!PayplugWoocommerceHelper::is_country_supported($shipping_country)) {
217 $shipping_country = PayplugWoocommerceHelper::get_default_country();
218 }
219
220 $this->shipping = [
221 'first_name' => $this->limit_length($shipping_first_name),
222 'last_name' => $this->limit_length($shipping_last_name),
223 'email' => $this->limit_length($shipping_email, 255),
224 'address1' => $this->limit_length($shipping_address1, 255),
225 'postcode' => $this->limit_length($shipping_postcode, 16),
226 'city' => $this->limit_length($shipping_city),
227 'country' => $this->limit_length($shipping_country, 2),
228 'company_name' => $this->limit_length($shipping_company),
229 ];
230
231 if (!empty($shipping_address2)) {
232 $this->shipping['address2'] = $this->limit_length($shipping_address2, 255);
233 }
234
235 if ($customer > 0) {
236 $address_hash = self::hash_address($this->shipping);
237 $address_already_used = self::address_already_used($customer, $address_hash);
238
239 // Set the delivery_type to `VERIFIED` if the customer has already used the address before
240 // otherwise set it to `NEW` since we have separate shipping address
241 $this->shipping['delivery_type'] = ($address_already_used)
242 ? self::DELIVERY_TYPE_VERIFIED
243 : self::DELIVERY_TYPE_NEW;
244 } else {
245 // Set the delivery_type to `NEW` since we have separate shipping address
246 $this->shipping['delivery_type'] = self::DELIVERY_TYPE_NEW;
247 }
248 } else {
249 $this->shipping = $this->billing;
250
251 if ($customer > 0) {
252 $address_hash = self::hash_address($this->shipping);
253 $address_already_used = self::address_already_used($customer, $address_hash);
254
255 // Set the delivery_type to `VERIFIED` if the customer has already used the address before
256 // otherwise set it to `BILLING` since we reuse the billing address for shipping
257 $this->shipping['delivery_type'] = ($address_already_used)
258 ? self::DELIVERY_TYPE_VERIFIED
259 : self::DELIVERY_TYPE_BILLING;
260 } else {
261 // Set the delivery_type to `BILLING` since we reuse the billing address for shipping
262 $this->shipping['delivery_type'] = self::DELIVERY_TYPE_BILLING;
263 }
264 }
265 } else {
266 // Set the delivery_type to `OTHER` since we dont't need to ship the products
267 $this->shipping = $this->billing;
268 $this->shipping['delivery_type'] = self::DELIVERY_TYPE_OTHER;
269 }
270
271 // Maybe set the phone field if available
272 $country = PayplugWoocommerceHelper::is_pre_30() ? $order->billing_country : $order->get_billing_country();
273 $phone = PayplugWoocommerceHelper::is_pre_30() ? $order->billing_phone : $order->get_billing_phone();
274 if (!empty($phone) && !empty($country)) {
275 try {
276 $phone_number_util = PhoneNumberUtil::getInstance();
277 $phone_number = $phone_number_util->parse($phone, $country);
278
279 if (!$phone_number_util->isValidNumber($phone_number)) {
280 throw new \Exception('Invalid phone number');
281 }
282
283 if (PhoneNumberType::MOBILE === $phone_number_util->getNumberType($phone_number)) {
284 $this->billing['mobile_phone_number'] = $phone_number_util->format($phone_number, PhoneNumberFormat::E164);
285 $this->shipping['mobile_phone_number'] = $phone_number_util->format($phone_number, PhoneNumberFormat::E164);
286 } else {
287 $this->billing['landline_phone_number'] = $phone_number_util->format($phone_number, PhoneNumberFormat::E164);
288 }
289 } catch (\Exception $e) {
290 // Fail to parse phone number.
291 // Could be an incorrect number or the number doesn't belong to the billing country.
292 }
293 }
294 }
295
296 /**
297 * Limit string length.
298 *
299 * @param string $value
300 * @param int $maxlength
301 *
302 * @return string
303 */
304 protected function limit_length($value, $maxlength = 100)
305 {
306 if (!empty($value)) {
307 $value = (strlen($value) > $maxlength) ? substr($value, 0, $maxlength) : $value;
308 }
309
310 return $value;
311 }
312 }
313