Completed
Push — develop ( 07de1c...011379 )
by David
03:12
created

Shipping_Zone::load_zone_locations()   B

Complexity

Conditions 8
Paths 8

Size

Total Lines 37

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
nc 8
nop 0
dl 0
loc 37
rs 8.0835
c 0
b 0
f 0
1
<?php
2
3
4
namespace Wordlift\Shipping_Data;
5
6
7
use WC_Shipping_Zone;
8
9
class Shipping_Zone {
10
11
	/**
12
	 * @var WC_Shipping_Zone
13
	 */
14
	private $wc_shipping_zone;
15
16
	/**
17
	 * @var Shipping_Method[]
18
	 */
19
	private $methods;
20
21
	/**
22
	 * @var string
23
	 */
24
	private $country_code;
25
26
	/**
27
	 * @var string[]
28
	 */
29
	private $regions = array();
30
31
	/**
32
	 * @var string[]
33
	 */
34
	private $postal_codes = array();
35
36
	/**
37
	 * @var string[]
38
	 */
39
	private $postal_code_prefixes = array();
40
41
	/**
42
	 * @var string[]
43
	 */
44
	private $postal_code_ranges = array();
45
46
	/**
47
	 * Shipping_Zone constructor.
48
	 *
49
	 * @param WC_Shipping_Zone $wc_shipping_zone
50
	 * @param string $country_code
51
	 */
52
	public function __construct( $wc_shipping_zone, $country_code ) {
53
54
		$this->wc_shipping_zone = $wc_shipping_zone;
55
		$this->country_code     = $country_code;
56
57
		$this->load_zone_locations();
58
59
	}
60
61
	private function load_zone_locations() {
62
63
		$this->regions              = array();
64
		$this->postal_codes         = array();
65
		$this->postal_code_prefixes = array();
66
		$this->postal_code_ranges   = array();
67
68
		// Bail out if country code isn't set.
69
		if ( ! isset( $this->country_code ) ) {
70
			return;
71
		}
72
73
		foreach ( $this->wc_shipping_zone->get_zone_locations() as $zone_location ) {
74
			switch ( $zone_location->type ) {
75
				case 'state':
76
					if ( 0 === strpos( $zone_location->code, "$this->country_code:" ) ) {
77
						$this->regions[] = substr( $zone_location->code, 3 );
78
					}
79
80
					break;
81
82
				case 'postcode':
83
					if ( '*' === substr( $zone_location->code, - 1 ) ) {
84
						$this->postal_code_prefixes[] = $zone_location->code;
85
					} else if ( - 1 < strpos( $zone_location->code, '...' ) ) {
86
						$this->postal_code_ranges[] = $zone_location->code;
87
					} else {
88
						$this->postal_codes[] = $zone_location->code;
89
					}
90
91
					break;
92
93
				default:
94
			}
95
		}
96
97
	}
98
99
	private function load_methods() {
100
101
		$this->methods = array_map( 'Wordlift\Shipping_Data\Shipping_Method::from_wc_shipping_method',
102
			$this->wc_shipping_zone->get_shipping_methods( true ) );
103
104
	}
105
106
	public function add_available_delivery_method( &$jsonld ) {
107
108
		$this->load_methods();
109
110
		foreach ( $this->methods as $method ) {
111
			$method->add_available_delivery_method( $jsonld );
112
		}
113
114
	}
115
116
	public function add_offer_shipping_details( &$jsonld ) {
117
118
		$this->load_methods();
119
120
		// Ignore the default zone if no methods are configured.
121
		if ( 0 === $this->wc_shipping_zone->get_id() && 0 === count( $this->methods ) ) {
122
			return;
123
		}
124
125
		$this->make_sure_shipping_details_exists_and_it_is_an_array( $jsonld );
126
127
		$offer_shipping_details = array( '@type' => 'OfferShippingDetails', );
128
129
		$this->add_shipping_destination( $offer_shipping_details );
130
131
		/*
132
		 * Use Case UC003
133
		 * 1.4.3
134
		 *
135
		 * https://editorial.thenextweb.com/wp-admin/admin-ajax.php?action=wl_ttl_cache_cleaner__flush
136
		 */
137
		foreach ( $this->methods as $method ) {
138
			$method->add_shipping_rate( $offer_shipping_details );
139
		}
140
141
		$jsonld['shippingDetails'][] = $offer_shipping_details;
142
143
	}
144
145
	private function make_sure_shipping_details_exists_and_it_is_an_array( &$jsonld ) {
146
147
		if ( ! isset( $jsonld['shippingDetails'] ) ) {
148
			$jsonld['shippingDetails'] = array();
149
		}
150
151 View Code Duplication
		if ( ! is_array( $jsonld['shippingDetails'] ) ||
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
152
		     ( ! empty( $jsonld['shippingDetails'] ) && ! is_numeric( key( $jsonld['shippingDetails'] ) ) ) ) {
153
			$jsonld['shippingDetails'] = array( $jsonld['shippingDetails'] );
154
		}
155
156
	}
157
158
	private function add_shipping_destination( &$shipping_details ) {
159
160
		if ( ! isset( $this->country_code ) ) {
161
			return;
162
		}
163
164
		$shipping_destination = array(
165
			'@type'          => 'DefinedRegion',
166
			'addressCountry' => $this->country_code,
167
		);
168
169
		$this->add_address_region( $shipping_destination );
170
		$this->add_postal_code( $shipping_destination );
171
		$this->add_postal_code_prefix( $shipping_destination );
172
		$this->add_postal_code_range( $shipping_destination );
173
174
		$shipping_details['shippingDestination'] = $shipping_destination;
175
176
177
	}
178
179
	private function add_address_region( &$shipping_destination ) {
180
181
		if ( empty( $this->regions ) ) {
182
			return;
183
		}
184
185
		$shipping_destination['addressRegion'] = $this->regions;
186
187
	}
188
189
	private function add_postal_code( &$shipping_destination ) {
190
191
		if ( empty( $this->postal_codes ) ) {
192
			return;
193
		}
194
195
		$shipping_destination['postalCode'] = $this->postal_codes;
196
197
	}
198
199
	private function add_postal_code_prefix( &$shipping_destination ) {
200
201
		if ( empty( $this->postal_code_prefixes ) ) {
202
			return;
203
		}
204
205
		foreach ( $this->postal_code_prefixes as $postal_code_prefix ) {
206
			$shipping_destination['postalCodePrefix'][] = substr( $postal_code_prefix, 0, - 1 );
207
		}
208
209
	}
210
211
	private function add_postal_code_range( &$shipping_destination ) {
212
213
		if ( empty( $this->postal_code_ranges ) ) {
214
			return;
215
		}
216
217
		$shipping_destination['postalCodeRanges'] = array();
218
		foreach ( $this->postal_code_ranges as $post_code_range ) {
219
			$range = explode( '...', $post_code_range );
220
221
			$shipping_destination['postalCodeRanges'][] = array(
222
				'postalCodeBegin' => $range[0],
223
				'postalCodeEnd'   => $range[1],
224
			);
225
		}
226
227
	}
228
229
	public static function from_wc_shipping_zone( $wc_shipping_zone, $country_code = null ) {
230
231
		return new self( $wc_shipping_zone, $country_code );
232
	}
233
234
}