PluginProbe
PostNL for WooCommerce / 3.1.7
PostNL for WooCommerce v3.1.7
5.9.12 5.9.11 5.9.10 5.9.9 5.9.8 5.9.7 5.9.6 trunk 2.5.0 2.5.1 2.5.2 2.5.3 2.5.4 2.5.5 3.1.4 3.1.5 3.1.6 3.1.7 4.0.0 4.0.1 4.0.2 4.3.2 4.3.3 4.4.0 4.4.1 All 72 releases
woo-postnl / includes / class-wcmp-nl-postcode-fields.php

class-wcmp-nl-postcode-fields.php in PostNL for WooCommerce 3.1.7, at includes/class-wcmp-nl-postcode-fields.php

1,018 lines 36.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 use WPO\WC\PostNL\Compatibility\WC_Core as WCX;
4 use WPO\WC\PostNL\Compatibility\Order as WCX_Order;
5
6 if ( ! defined('ABSPATH')) exit; // Exit if accessed directly
7
8 if ( ! class_exists('Woocommerce_PostNL_Postcode_Fields')) :
9
10 class Woocommerce_PostNL_Postcode_Fields {
11
12 /*
13 * Regular expression used to split street name from house number.
14 * This regex goes from right to left
15 * Contains php keys to store the data in an array
16 * Taken from https://github.com/postnl/sdk
17 */
18 const SPLIT_STREET_REGEX = '~(?P<street>.*?)\s?(?P<number>\d{1,4})[/\s\-]{0,2}(?P<number_suffix>[a-zA-Z]{1}\d{1,3}|-\d{1,4}|\d{2}\w{1,2}|[a-zA-Z]{1}[a-zA-Z\s]{0,3})?$~';
19 private $use_split_address_fields;
20
21 public function __construct() {
22 $this->use_split_address_fields = array_key_exists(
23 'use_split_address_fields',
24 get_option('woocommerce_postnl_checkout_settings')
25 ) ? get_option('woocommerce_postnl_checkout_settings')['use_split_address_fields'] === '1' : false;
26
27 // Load styles
28 add_action('wp_enqueue_scripts', array(&$this, 'add_styles_scripts'));
29 // Load scripts
30 add_action('admin_enqueue_scripts', array(&$this, 'admin_scripts_styles'));
31
32 if ($this->use_split_address_fields) {
33 // Add street name & house number checkout fields.
34 if (version_compare(WOOCOMMERCE_VERSION, '2.0') >= 0) {
35 // WC 2.0 or newer is used, the filter got a $country parameter, yay!
36 add_filter('woocommerce_billing_fields', [&$this, 'nl_billing_fields'], apply_filters('nl_checkout_fields_priority', 10, 'billing'), 2);
37 add_filter('woocommerce_shipping_fields', [&$this, 'nl_shipping_fields'], apply_filters('nl_checkout_fields_priority', 10, 'shipping'), 2);
38 } else {
39 // Backwards compatibility
40 add_filter('woocommerce_billing_fields', [&$this, 'nl_billing_fields']);
41 add_filter('woocommerce_shipping_fields', [&$this, 'nl_shipping_fields']);
42 }
43
44 // Localize checkout fields (limit custom checkout fields to NL and BE)
45 add_filter('woocommerce_country_locale_field_selectors', [&$this, 'country_locale_field_selectors']);
46 add_filter('woocommerce_default_address_fields', [&$this, 'default_address_fields']);
47 add_filter('woocommerce_get_country_locale', [&$this, 'woocommerce_locale_nl'], 1, 1); // !
48
49 // Load custom order data.
50 add_filter('woocommerce_load_order_data', [&$this, 'load_order_data']);
51
52 // Custom shop_order details.
53 add_filter('woocommerce_admin_billing_fields', [&$this, 'admin_billing_fields']);
54 add_filter('woocommerce_admin_shipping_fields', [&$this, 'admin_shipping_fields']);
55 add_filter('woocommerce_found_customer_details', [$this, 'customer_details_ajax']);
56 add_action('save_post', [&$this, 'save_custom_fields']);
57
58 // add to user profile page
59 add_filter('woocommerce_customer_meta_fields', [&$this, 'user_profile_fields']);
60
61 add_action('woocommerce_checkout_update_order_meta', array(&$this, 'merge_street_number_suffix'), 20, 2);
62 add_filter('woocommerce_process_checkout_field_billing_postcode', array(&$this, 'clean_billing_postcode'));
63 add_filter('woocommerce_process_checkout_field_shipping_postcode', array(&$this, 'clean_shipping_postcode'));
64
65 // Save the order data in WooCommerce 2.2 or later.
66 if (version_compare(WOOCOMMERCE_VERSION, '2.2') >= 0) {
67 add_action('woocommerce_checkout_update_order_meta', array(&$this, 'save_order_data'), 10, 2);
68 }
69
70 // Remove placeholder values (IE8 & 9)
71 add_action('woocommerce_checkout_update_order_meta', array(&$this, 'remove_placeholders'), 10, 2);
72
73 // Fix weird required field translations
74 add_filter('woocommerce_checkout_required_field_notice', array(&$this, 'required_field_notices'), 10, 2);
75
76 $this->load_woocommerce_filters();
77 } else { // if NOT using old fields
78 add_action('woocommerce_after_checkout_validation', array(&$this, 'validate_address_fields'), 10, 2);
79 }
80
81 // Processing checkout
82 add_filter('woocommerce_validate_postcode', array(&$this, 'validate_postcode'), 10, 3);
83
84 // set later priority for woocommerce_billing_fields / woocommerce_shipping_fields
85 // when Checkout Field Editor is active
86 if (function_exists('thwcfd_is_locale_field') || function_exists('wc_checkout_fields_modify_billing_fields')) {
87 add_filter('nl_checkout_fields_priority', 1001);
88 }
89
90 // Hide state field for countries without states (backwards compatible fix for bug #4223)
91 if (version_compare(WOOCOMMERCE_VERSION, '2.1', '<')) {
92 add_filter('woocommerce_countries_allowed_country_states', array(&$this, 'hide_states'));
93 }
94 }
95
96 public function load_woocommerce_filters() {
97 // Custom address format.
98 if (version_compare(WOOCOMMERCE_VERSION, '2.0.6', '>=')) {
99 add_filter('woocommerce_localisation_address_formats', array($this, 'localisation_address_formats'));
100 add_filter('woocommerce_formatted_address_replacements', array($this, 'formatted_address_replacements'), 1, 2);
101 add_filter('woocommerce_order_formatted_billing_address', array($this, 'order_formatted_billing_address'), 1, 2);
102 add_filter('woocommerce_order_formatted_shipping_address', array($this, 'order_formatted_shipping_address'), 1, 2);
103 add_filter('woocommerce_user_column_billing_address', array($this, 'user_column_billing_address'), 1, 2);
104 add_filter('woocommerce_user_column_shipping_address', array($this, 'user_column_shipping_address'), 1, 2);
105 add_filter('woocommerce_my_account_my_address_formatted_address', array($this, 'my_account_my_address_formatted_address'), 1, 3);
106 }
107 }
108
109 /**
110 * Load styles & scripts.
111 */
112 public function add_styles_scripts() {
113 if ( ! is_checkout() && ! is_account_page()) return;
114
115 // Enqueue styles for delivery options
116 wp_enqueue_style(
117 'nl-checkout',
118 WooCommerce_PostNL()->plugin_url() . '/assets/css/nl-checkout.css',
119 false,
120 WC_POSTNL_VERSION
121 );
122
123 if ( ! $this->use_split_address_fields) return;
124
125 if (version_compare(WOOCOMMERCE_VERSION, '2.1', '<=')) {
126 // Backwards compatibility for https://github.com/woothemes/woocommerce/issues/4239
127 wp_register_script(
128 'nl-checkout',
129 WooCommerce_PostNL()->plugin_url() . '/assets/js/nl-checkout.js',
130 array('wc-checkout'),
131 WC_POSTNL_VERSION
132 );
133 wp_enqueue_script('nl-checkout');
134 }
135
136 if (is_account_page()) {
137 // Disable regular address fields for NL on account page - Fixed in WC 2.1 but not on init...
138 wp_register_script(
139 'nl-account-page',
140 WooCommerce_PostNL()->plugin_url() . '/assets/js/nl-account-page.js',
141 array('jquery'),
142 WC_POSTNL_VERSION
143 );
144 wp_enqueue_script('nl-account-page');
145 }
146 }
147
148 /**
149 * Load admin styles & scripts.
150 */
151 public function admin_scripts_styles($hook) {
152 global $post_type;
153 if ($post_type == 'shop_order') {
154 wp_enqueue_style(
155 'nl-checkout-admin',
156 WooCommerce_PostNL()->plugin_url() . '/assets/css/nl-checkout-admin.css',
157 array(), // deps
158 WC_POSTNL_VERSION
159 );
160 }
161 }
162
163 /**
164 * Hide default Dutch address fields
165 *
166 * @param array $locale woocommerce country locale field settings
167 *
168 * @return array $locale
169 */
170 public function woocommerce_locale_nl($locale) {
171 $locale['NL']['address_1'] = array(
172 'required' => false,
173 'hidden' => true,
174 );
175
176 $locale['NL']['address_2'] = array(
177 'hidden' => true,
178 );
179
180 $locale['NL']['state'] = array(
181 'hidden' => true,
182 'required' => false,
183 );
184
185 $locale['NL']['street_name'] = array(
186 'required' => true,
187 'hidden' => false,
188 );
189
190 $locale['NL']['house_number'] = array(
191 'required' => true,
192 'hidden' => false,
193 );
194
195 $locale['NL']['house_number_suffix'] = array(
196 'required' => false,
197 'hidden' => false,
198 );
199
200 $locale['BE']['address_1'] = array(
201 'required' => false,
202 'hidden' => true,
203 );
204
205 $locale['BE']['address_2'] = array(
206 'hidden' => true,
207 );
208
209 $locale['BE']['state'] = array(
210 'hidden' => true,
211 'required' => false,
212 );
213
214 $locale['BE']['street_name'] = array(
215 'required' => true,
216 'hidden' => false,
217 );
218
219 $locale['BE']['house_number'] = array(
220 'required' => true,
221 'hidden' => false,
222 );
223
224 $locale['BE']['house_number_suffix'] = array(
225 'required' => false,
226 'hidden' => false,
227 );
228
229 return $locale;
230 }
231
232 public function nl_billing_fields($fields, $country = '') {
233 return $this->nl_checkout_fields($fields, $country, 'billing');
234 }
235
236 public function nl_shipping_fields($fields, $country = '') {
237 return $this->nl_checkout_fields($fields, $country, 'shipping');
238 }
239
240 /**
241 * New checkout billing/shipping fields
242 *
243 * @param array $fields Default fields.
244 *
245 * @return array $fields New fields.
246 */
247 public function nl_checkout_fields($fields, $country, $form) {
248 if (isset($fields['_country'])) {
249 // some weird bug on the my account page
250 $form = '';
251 }
252
253 // Set required to true if country is NL
254 $required = ($country == 'NL' || $country == 'BE') ? true : false;
255
256 // Add street name
257 $fields[$form . '_street_name'] = array(
258 'label' => __('Street name', 'woocommerce-postnl'),
259 'class' => apply_filters('nl_custom_address_field_class', array('form-row-third first')),
260 'required' => $required, // Only required for NL
261 'priority' => 60,
262 );
263
264 // Add house number
265 $fields[$form . '_house_number'] = array(
266 'label' => __('No.', 'woocommerce-postnl'),
267 'class' => apply_filters('nl_custom_address_field_class', array('form-row-third')),
268 'required' => $required, // Only required for NL
269 'type' => 'number',
270 'priority' => 61,
271 );
272
273 // Add house number suffix
274 $fields[$form . '_house_number_suffix'] = array(
275 'label' => __('Suffix', 'woocommerce-postnl'),
276 'class' => apply_filters('nl_custom_address_field_class', array('form-row-third last')),
277 'required' => false,
278 'maxlength' => 4,
279 'priority' => 62,
280 );
281
282 // Create new ordering for checkout fields
283 $order_keys = array(
284 $form . '_first_name',
285 $form . '_last_name',
286 $form . '_company',
287 $form . '_country',
288 $form . '_address_1',
289 $form . '_address_2',
290 $form . '_street_name',
291 $form . '_house_number',
292 $form . '_house_number_suffix',
293 $form . '_postcode',
294 $form . '_city',
295 $form . '_state',
296 );
297
298 if ($form == 'billing') {
299 array_push(
300 $order_keys,
301 $form . '_email',
302 $form . '_phone'
303 );
304 }
305
306 $new_order = array();
307
308 // Create reordered array and fill with old array values
309 foreach ( $order_keys as $key ) {
310 $new_order[$key] = $fields[$key];
311 }
312
313 // Merge (&overwrite) field array
314 $fields = array_merge($new_order, $fields);
315
316 return $fields;
317 }
318
319 /**
320 * Hide state field for countries without states (backwards compatible fix for WooCommerce bug #4223)
321 *
322 * @param array $allowed_states states per country
323 *
324 * @return array
325 */
326 public function hide_states($allowed_states) {
327 $hidden_states = array(
328 'AF' => array(),
329 'AT' => array(),
330 'BE' => array(),
331 'BI' => array(),
332 'CZ' => array(),
333 'DE' => array(),
334 'DK' => array(),
335 'FI' => array(),
336 'FR' => array(),
337 'HU' => array(),
338 'IS' => array(),
339 'IL' => array(),
340 'KR' => array(),
341 'NL' => array(),
342 'NO' => array(),
343 'PL' => array(),
344 'PT' => array(),
345 'SG' => array(),
346 'SK' => array(),
347 'SI' => array(),
348 'LK' => array(),
349 'SE' => array(),
350 'VN' => array(),
351 );
352 $states = $hidden_states + $allowed_states;
353
354 return $states;
355 }
356
357 /**
358 * Localize checkout fields live
359 *
360 * @param array $locale_fields list of fields filtered by locale
361 *
362 * @return array $locale_fields with custom fields added
363 */
364 public function country_locale_field_selectors($locale_fields) {
365 $custom_locale_fields = array(
366 'street_name' => '#billing_street_name_field, #shipping_street_name_field',
367 'house_number' => '#billing_house_number_field, #shipping_house_number_field',
368 'house_number_suffix' => '#billing_house_number_suffix_field, #shipping_house_number_suffix_field',
369 );
370
371 $locale_fields = array_merge($locale_fields, $custom_locale_fields);
372
373 return $locale_fields;
374 }
375
376 /**
377 * Make NL and BE checkout fields hidden by default
378 *
379 * @param array $fields default checkout fields
380 *
381 * @return array $fields default + custom checkoud fields
382 */
383 public function default_address_fields($fields) {
384 $custom_fields = array(
385 'street_name' => array(
386 'hidden' => true,
387 'required' => false,
388 ),
389 'house_number' => array(
390 'hidden' => true,
391 'required' => false,
392 ),
393 'house_number_suffix' => array(
394 'hidden' => true,
395 'required' => false,
396 ),
397 );
398
399 $fields = array_merge($fields, $custom_fields);
400
401 return $fields;
402 }
403
404 /**
405 * Load order custom data.
406 *
407 * @param array $data Default WC_Order data.
408 *
409 * @return array Custom WC_Order data.
410 */
411 public function load_order_data($data) {
412 // Billing
413 $data['billing_street_name'] = '';
414 $data['billing_house_number'] = '';
415 $data['billing_house_number_suffix'] = '';
416
417 // Shipping
418 $data['shipping_street_name'] = '';
419 $data['shipping_house_number'] = '';
420 $data['shipping_house_number_suffix'] = '';
421
422 return $data;
423 }
424
425 /**
426 * Custom billing admin edit fields.
427 *
428 * @param array $fields Default WC_Order data.
429 *
430 * @return array Custom WC_Order data.
431 */
432 public function admin_billing_fields($fields) {
433 $fields['street_name'] = array(
434 'label' => __('Street name', 'woocommerce-postnl'),
435 'show' => true
436 );
437
438 $fields['house_number'] = array(
439 'label' => __('Number', 'woocommerce-postnl'),
440 'show' => true
441 );
442
443 $fields['house_number_suffix'] = array(
444 'label' => __('Suffix', 'woocommerce-postnl'),
445 'show' => true
446 );
447
448 return $fields;
449 }
450
451 /**
452 * Custom shipping admin edit fields.
453 *
454 * @param array $fields Default WC_Order data.
455 *
456 * @return array Custom WC_Order data.
457 */
458 public function admin_shipping_fields($fields) {
459 $fields['street_name'] = array(
460 'label' => __('Street name', 'woocommerce-postnl'),
461 'show' => true
462 );
463
464 $fields['house_number'] = array(
465 'label' => __('Number', 'woocommerce-postnl'),
466 'show' => true
467 );
468
469 $fields['house_number_suffix'] = array(
470 'label' => __('Suffix', 'woocommerce-postnl'),
471 'show' => true
472 );
473
474 return $fields;
475 }
476
477 /**
478 * Custom user profile edit fields.
479 */
480 public function user_profile_fields($meta_fields) {
481 $postnl_billing_fields = array(
482 'billing_street_name' => array(
483 'label' => __('Street', 'woocommerce-postnl'),
484 'description' => ''
485 ),
486 'billing_house_number' => array(
487 'label' => __('Number', 'woocommerce-postnl'),
488 'description' => ''
489 ),
490 'billing_house_number_suffix' => array(
491 'label' => __('Suffix', 'woocommerce-postnl'),
492 'description' => ''
493 ),
494 );
495 $postnl_shipping_fields = array(
496 'shipping_street_name' => array(
497 'label' => __('Street', 'woocommerce-postnl'),
498 'description' => ''
499 ),
500 'shipping_house_number' => array(
501 'label' => __('Number', 'woocommerce-postnl'),
502 'description' => ''
503 ),
504 'shipping_house_number_suffix' => array(
505 'label' => __('Suffix', 'woocommerce-postnl'),
506 'description' => ''
507 ),
508 );
509
510 // add postnl fields to billing section
511 $billing_fields = array_merge($meta_fields['billing']['fields'], $postnl_billing_fields);
512 $billing_fields = $this->array_move_keys(
513 $billing_fields,
514 array('billing_street_name', 'billing_house_number', 'billing_house_number_suffix'),
515 'billing_address_2',
516 'after'
517 );
518 $meta_fields['billing']['fields'] = $billing_fields;
519
520 // add postnl fields to shipping section
521 $shipping_fields = array_merge($meta_fields['shipping']['fields'], $postnl_shipping_fields);
522 $shipping_fields = $this->array_move_keys(
523 $shipping_fields,
524 array('shipping_street_name', 'shipping_house_number', 'shipping_house_number_suffix'),
525 'shipping_address_2',
526 'after'
527 );
528 $meta_fields['shipping']['fields'] = $shipping_fields;
529
530 return $meta_fields;
531 }
532
533 /**
534 * Add custom fields in customer details ajax.
535 * called when clicking the "Load billing/shipping address" button on Edit Order view
536 * @return array
537 */
538 public function customer_details_ajax($customer_data) {
539 $user_id = (int) trim(stripslashes($_POST['user_id']));
540 $type_to_load = esc_attr(trim(stripslashes($_POST['type_to_load'])));
541
542 $custom_data = array(
543 $type_to_load . '_street_name' => get_user_meta($user_id, $type_to_load . '_street_name', true),
544 $type_to_load . '_house_number' => get_user_meta($user_id, $type_to_load . '_house_number', true),
545 $type_to_load . '_house_number_suffix' => get_user_meta(
546 $user_id,
547 $type_to_load . '_house_number_suffix',
548 true
549 ),
550 );
551
552 return array_merge($customer_data, $custom_data);
553 }
554
555 /**
556 * Save custom fields from admin.
557 */
558 public function save_custom_fields($post_id) {
559 $post_type = get_post_type($post_id);
560 if (($post_type == 'shop_order' || $post_type == 'shop_order_refund') && ! empty($_POST)) {
561 $order = WCX::get_order($post_id);
562 $addresses = array('billing', 'shipping');
563 $address_fields = array('street_name', 'house_number', 'house_number_suffix');
564 foreach ( $addresses as $address ) {
565 foreach ( $address_fields as $address_field ) {
566 if (isset($_POST["_{$address}_{$address_field}"])) {
567 WCX_Order::update_meta_data(
568 $order,
569 "_{$address}_{$address_field}",
570 stripslashes($_POST["_{$address}_{$address_field}"])
571 );
572 }
573 }
574 }
575 }
576
577 return;
578 }
579
580 /**
581 * Merge street name, street number and street suffix into the default 'address_1' field
582 *
583 * @param string $order_id Order ID of checkout order.
584 *
585 * @return void
586 */
587 public function merge_street_number_suffix($order_id) {
588 $order = WCX::get_order($order_id);
589 // file_put_contents('postdata.txt', print_r($_POST,true)); // for debugging
590 if (version_compare(WOOCOMMERCE_VERSION, '2.1', '<=')) {
591 // old versions use 'shiptobilling'
592 $ship_to_different_address = isset($_POST['shiptobilling']) ? false : true;
593 } else {
594 // WC2.1
595 $ship_to_different_address = isset($_POST['ship_to_different_address']) ? true : false;
596 }
597
598 // check if country is NL
599 if ($_POST['billing_country'] == 'NL' || $_POST['billing_country'] == 'BE') {
600 // concatenate street & house number & copy to 'billing_address_1'
601 $billing_house_number = $_POST['billing_house_number'] . (! empty($_POST['billing_house_number_suffix']) ? '-' . $_POST['billing_house_number_suffix'] : '');
602 $billing_address_1 = $_POST['billing_street_name'] . ' ' . $billing_house_number;
603 WCX_Order::set_address_prop($order, 'address_1', 'billing', $billing_address_1);
604
605 // check if 'ship to billing address' is checked
606 if ($ship_to_different_address == false && $this->cart_needs_shipping_address()) {
607 // use billing address
608 WCX_Order::set_address_prop($order, 'address_1', 'shipping', $billing_address_1);
609 }
610 }
611
612 if (($_POST['shipping_country'] == 'NL' || $_POST['shipping_country'] == 'BE') && $ship_to_different_address == true) {
613 // concatenate street & house number & copy to 'shipping_address_1'
614 $shipping_house_number = $_POST['shipping_house_number'] . (! empty($_POST['shipping_house_number_suffix']) ? '-' . $_POST['shipping_house_number_suffix'] : '');
615 $shipping_address_1 = $_POST['shipping_street_name'] . ' ' . $shipping_house_number;
616 WCX_Order::set_address_prop($order, 'address_1', 'shipping', $shipping_address_1);
617 }
618
619 return;
620 }
621
622 /**
623 * validate NL postcodes
624 * @return bool $valid
625 */
626 public function validate_postcode($valid, $postcode, $country) {
627 if ($country == 'NL') {
628 $valid = (bool) preg_match('/^[1-9][0-9]{3} ?(?!sa|sd|ss)[a-z]{2}$/i', trim($postcode));
629 }
630 if ($country == 'BE') {
631 $valid = (bool) preg_match('/^[1-9][0-9]{3}/i', trim($postcode));
632 }
633
634 return $valid;
635 }
636
637 /**
638 * validate address field 1 for shipping and billing
639 */
640 public function validate_address_fields($address, $errors) {
641 if ($address['billing_country'] == 'NL'
642 && ! (bool) preg_match(
643 self::SPLIT_STREET_REGEX,
644 trim($address['billing_address_1']
645 ))) {
646 $errors->add('address', __('Please enter a valid billing address.', 'woocommerce-postnl'));
647 }
648
649 if ($address['shipping_country'] == 'NL'
650 && array_key_exists('ship_to_different_address', $address)
651 && ! (bool) preg_match(
652 self::SPLIT_STREET_REGEX,
653 trim($address['shipping_address_1']
654 ))) {
655 $errors->add('address', __('Please enter a valid shipping address.', 'woocommerce-postnl'));
656 }
657 }
658
659 /**
660 * Clean postcodes : remove space, dashes (& other non alphanumeric characters)
661 * @return $billing_postcode
662 * @return $shipping_postcode
663 */
664 public function clean_billing_postcode() {
665 if ($_POST['billing_country'] == 'NL' || $_POST['billing_country'] == 'BE') {
666 $billing_postcode = preg_replace('/[^a-zA-Z0-9]/', '', $_POST['billing_postcode']);
667 } else {
668 $billing_postcode = $_POST['billing_postcode'];
669 }
670
671 return $billing_postcode;
672 }
673
674 public function clean_shipping_postcode() {
675 if ($_POST['shipping_country'] == 'NL' || $_POST['billing_country'] == 'BE') {
676 $shipping_postcode = preg_replace('/[^a-zA-Z0-9]/', '', $_POST['shipping_postcode']);
677 } else {
678 $shipping_postcode = $_POST['shipping_postcode'];
679 }
680
681 return $shipping_postcode;
682 }
683
684 /**
685 * Remove placeholders from posted checkout data
686 *
687 * @param string $order_id order_id of the new order
688 * @param array $posted Array of posted form data
689 *
690 * @return void
691 */
692 public function remove_placeholders($order_id, $posted) {
693 $order = WCX::get_order($order_id);
694 // get default address fields with their placeholders
695 $countries = new WC_Countries;
696 $fields = $countries->get_default_address_fields();
697
698 // define order_comments placeholder
699 $order_comments_placeholder = _x(
700 'Notes about your order, e.g. special notes for delivery.',
701 'placeholder',
702 'woocommerce'
703 );
704
705 // check if ship to billing is set
706 if (version_compare(WOOCOMMERCE_VERSION, '2.1', '<=')) {
707 // old versions use 'shiptobilling'
708 $ship_to_different_address = isset($_POST['shiptobilling']) ? false : true;
709 } else {
710 // WC2.1
711 $ship_to_different_address = isset($_POST['ship_to_different_address']) ? true : false;
712 }
713
714 // check the billing & shipping fields
715 $field_types = array('billing', 'shipping');
716 $check_fields = array('address_1', 'address_2', 'city', 'state', 'postcode');
717 foreach ( $field_types as $field_type ) {
718 foreach ( $check_fields as $check_field ) {
719 // file_put_contents(ABSPATH.'field_check.txt', $posted[$field_type.'_'.$check_field] .' || '. $fields[$check_field]['placeholder']."\n",FILE_APPEND);
720 if (isset($posted[$field_type . '_' . $check_field]) && isset($fields[$check_field]['placeholder']) && $posted[$field_type . '_' . $check_field] == $fields[$check_field]['placeholder']) {
721 WCX_Order::set_address_prop($order, $check_field, $field_type, '');
722
723 // also clear shipping field when ship_to_different_address is false
724 if ($ship_to_different_address == false && $field_type == 'billing') {
725 WCX_Order::set_address_prop($order, $check_field, 'shipping', '');
726 }
727 }
728 }
729 }
730
731 // check the order comments field
732 if ($posted['order_comments'] == $order_comments_placeholder) {
733 wp_update_post(
734 array(
735 'ID' => $order_id,
736 'post_excerpt' => '',
737 )
738 );
739 }
740
741 return;
742 }
743
744 /**
745 * WooCommerce concatenates translations for required field notices that result in
746 * confusing messages, so we translate the full notice to prevent this
747 */
748 function required_field_notices($notice, $field_label) {
749 // concatenate translations
750 $billing_nr = sprintf(__('Billing %s', 'woocommerce'), __('No.', 'woocommerce-postnl'));
751 $shipping_nr = sprintf(__('Shipping %s', 'woocommerce'), __('No.', 'woocommerce-postnl'));
752
753 switch($field_label) {
754 case $billing_nr:
755 $notice = __('<b>Billing No.</b> is a required field', 'woocommerce-postnl');
756 break;
757 case $shipping_nr:
758 $notice = __('<b>Shipping No.</b> is a required field', 'woocommerce-postnl');
759 break;
760 default:
761 break;
762 }
763
764 return $notice;
765 }
766
767 /**
768 * Custom country address formats.
769 *
770 * @param array $formats Defaul formats.
771 *
772 * @return array New NL format.
773 */
774 public function localisation_address_formats($formats) {
775 $formats['NL'] = "{company}\n{name}\n{address_1}\n{address_2}\n{postcode} {city}\n{country}";
776 $formats['BE'] = "{company}\n{name}\n{address_1}\n{address_2}\n{postcode} {city}\n{country}";
777
778 return $formats;
779 }
780
781 /**
782 * Custom country address format.
783 *
784 * @param array $replacements Default replacements.
785 * @param array $args Arguments to replace.
786 *
787 * @return array New replacements.
788 */
789 public function formatted_address_replacements($replacements, $args) {
790 extract($args);
791
792 if ( ! empty($street_name) && ($country == 'NL' || $country == 'BE')) {
793 $replacements['{address_1}'] = $street_name . ' ' . $house_number . $house_number_suffix;
794 }
795
796 return $replacements;
797 }
798
799 /**
800 * Custom order formatted billing address.
801 *
802 * @param array $address Default address.
803 * @param object $order Order data.
804 *
805 * @return array New address format.
806 */
807 public function order_formatted_billing_address($address, $order) {
808 $address['street_name'] = WCX_Order::get_meta($order, '_billing_street_name', true, 'view');
809 $address['house_number'] = WCX_Order::get_meta($order, '_billing_house_number', true, 'view');
810 $address['house_number_suffix'] = WCX_Order::get_meta($order, '_billing_house_number_suffix', true, 'view');
811 $address['house_number_suffix'] = ! empty($address['house_number_suffix']) ? '-' . $address['house_number_suffix'] : '';
812
813 return $address;
814 }
815
816 /**
817 * Custom order formatted shipping address.
818 *
819 * @param array $address Default address.
820 * @param object $order Order data.
821 *
822 * @return array New address format.
823 */
824 public function order_formatted_shipping_address($address, $order) {
825 $address['street_name'] = WCX_Order::get_meta($order, '_shipping_street_name', true, 'view');
826 $address['house_number'] = WCX_Order::get_meta($order, '_shipping_house_number', true, 'view');
827 $address['house_number_suffix'] = WCX_Order::get_meta($order, '_shipping_house_number_suffix', true, 'view');
828 $address['house_number_suffix'] = ! empty($address['house_number_suffix'])
829 ? '-' . $address['house_number_suffix']
830 : '';
831
832 return $address;
833 }
834
835 /**
836 * Custom user column billing address information.
837 *
838 * @param array $address Default address.
839 * @param int $user_id User id.
840 *
841 * @return array New address format.
842 */
843 public function user_column_billing_address($address, $user_id) {
844 $address['street_name'] = get_user_meta($user_id, 'billing_street_name', true);
845 $address['house_number'] = get_user_meta($user_id, 'billing_house_number', true);
846 $address['house_number_suffix'] = (get_user_meta($user_id, 'billing_house_number_suffix', true))
847 ? '-' . get_user_meta($user_id, 'billing_house_number_suffix', true)
848 : '';
849
850 return $address;
851 }
852
853 /**
854 * Custom user column shipping address information.
855 *
856 * @param array $address Default address.
857 * @param int $user_id User id.
858 *
859 * @return array New address format.
860 */
861 public function user_column_shipping_address($address, $user_id) {
862 $address['street_name'] = get_user_meta($user_id, 'shipping_street_name', true);
863 $address['house_number'] = get_user_meta($user_id, 'shipping_house_number', true);
864 $address['house_number_suffix'] = (get_user_meta($user_id, 'shipping_house_number_suffix', true))
865 ? '-' . get_user_meta($user_id, 'shipping_house_number_suffix', true)
866 : '';
867
868 return $address;
869 }
870
871 /**
872 * Custom my address formatted address.
873 *
874 * @param array $address Default address.
875 * @param int $customer_id Customer ID.
876 * @param string $name Field name (billing or shipping).
877 *
878 * @return array New address format.
879 */
880 public function my_account_my_address_formatted_address($address, $customer_id, $name) {
881 $address['street_name'] = get_user_meta($customer_id, $name . '_street_name', true);
882 $address['house_number'] = get_user_meta($customer_id, $name . '_house_number', true);
883 $address['house_number_suffix'] = (get_user_meta($customer_id, $name . '_house_number_suffix', true))
884 ? '-' . get_user_meta($customer_id, $name . '_house_number_suffix', true)
885 : '';
886
887 return $address;
888 }
889
890 /**
891 * Get a posted address field after sanitization and validation.
892 *
893 * @param string $key
894 * @param string $type billing for shipping
895 *
896 * @return string
897 */
898 public function get_posted_address_data($key, $posted, $type = 'billing') {
899 if ('billing' === $type
900 || ( ! $posted['ship_to_different_address']
901 && $this->cart_needs_shipping_address())) {
902 $return = isset($posted['billing_' . $key]) ? $posted['billing_' . $key] : '';
903 } else if ('shipping' === $type && ! $this->cart_needs_shipping_address()) {
904 $return = '';
905 } else {
906 $return = isset($posted['shipping_' . $key]) ? $posted['shipping_' . $key] : '';
907 }
908
909 return $return;
910 }
911
912 public function cart_needs_shipping_address() {
913 if (is_object(WC()->cart) && method_exists(WC()->cart, 'needs_shipping_address')
914 && function_exists('wc_ship_to_billing_address_only')
915 ) {
916 if (WC()->cart->needs_shipping_address() || wc_ship_to_billing_address_only()) {
917 return true;
918 } else {
919 return false;
920 }
921 } else {
922 return true;
923 }
924 }
925
926 /**
927 * Save order data.
928 *
929 * @param int $order_id
930 * @param array $posted
931 *
932 * @return void
933 */
934 public function save_order_data($order_id, $posted) {
935 $order = WCX::get_order($order_id);
936 // Billing.
937 WCX_Order::update_meta_data(
938 $order,
939 '_billing_street_name',
940 $this->get_posted_address_data('street_name', $posted)
941 );
942 WCX_Order::update_meta_data(
943 $order,
944 '_billing_house_number',
945 $this->get_posted_address_data('house_number', $posted)
946 );
947 WCX_Order::update_meta_data(
948 $order,
949 '_billing_house_number_suffix',
950 $this->get_posted_address_data('house_number_suffix', $posted)
951 );
952
953 // Shipping.
954 WCX_Order::update_meta_data(
955 $order,
956 '_shipping_street_name',
957 $this->get_posted_address_data('street_name', $posted, 'shipping')
958 );
959 WCX_Order::update_meta_data(
960 $order,
961 '_shipping_house_number',
962 $this->get_posted_address_data('house_number', $posted, 'shipping')
963 );
964 WCX_Order::update_meta_data(
965 $order,
966 '_shipping_house_number_suffix',
967 $this->get_posted_address_data('house_number_suffix', $posted, 'shipping')
968 );
969 }
970
971 /**
972 * Helper function to move array elements (one or more) to a position before a specific key
973 *
974 * @param array $array Main array to modify
975 * @param mixed $keys Single key or array of keys of element(s) to move
976 * @param string $reference_key key to put elements before or after
977 * @param string $position before or after
978 *
979 * @return array reordered array
980 */
981 public function array_move_keys($array, $keys, $reference_key, $position = 'before') {
982 // cast $key as array
983 $keys = (array) $keys;
984
985 if ( ! isset($array[$reference_key])) {
986 return $array;
987 }
988
989 $move = array();
990 foreach ( $keys as $key ) {
991 if ( ! isset($array[$key])) {
992 continue;
993 }
994 $move[$key] = $array[$key];
995 unset ($array[$key]);
996 }
997
998 if ($position == 'before') {
999 $move_to_pos = array_search($reference_key, array_keys($array));
1000 } else { // after
1001 $move_to_pos = array_search($reference_key, array_keys($array)) + 1;
1002 }
1003
1004 $new_array = array_slice($array, 0, $move_to_pos, true) + $move + array_slice(
1005 $array,
1006 $move_to_pos,
1007 null,
1008 true
1009 );
1010
1011 return $new_array;
1012 }
1013 }
1014
1015 endif; // class_exists
1016
1017 return new Woocommerce_PostNL_Postcode_Fields();
1018