PluginProbe
Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) / 1.6.22
Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) v1.6.22
1.8.12.3 1.8.12.2 1.8.12.1 1.8.12 1.8.11.3 1.8.11.2 1.8.11.1 1.8.11 1.6.6 1.6.60 1.6.7 1.6.8 1.6.9 1.7.0 1.7.0.1 1.7.0.11 1.7.0.12 1.7.0.14 1.7.0.2 1.7.0.3 1.7.0.5 1.7.0.6 1.7.0.7 1.7.0.9 1.8.0 All 210 releases
charitable / includes / class-charitable-locations.php

class-charitable-locations.php in Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) 1.6.22, at includes/class-charitable-locations.php

407 lines 11.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Contains the class that provides a utility functions relating to locales.
4 *
5 * @version 1.0.0
6 * @package Charitable/Classes/Charitable_Locations
7 * @author Eric Daams
8 * @copyright Copyright (c) 2019, Studio 164a
9 * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
10 */
11
12 // Exit if accessed directly.
13 if ( ! defined( 'ABSPATH' ) ) { exit; }
14
15 if ( ! class_exists( 'Charitable_Locations' ) ) :
16
17 /**
18 * Charitable_Locations
19 *
20 * @since 1.0.0
21 */
22 class Charitable_Locations {
23
24 /**
25 * The single instance of this class.
26 *
27 * @var Charitable_Locations|null
28 */
29 private static $instance = null;
30
31 /**
32 * List of countries in country_code=>name format.
33 *
34 * @var string[] $countries
35 * @since 1.0.0
36 */
37 private $countries = array();
38
39 /**
40 * List of states as a multidimensional array, grouped by country.
41 *
42 * @var array[] $states
43 * @since 1.0.0
44 */
45 private $states = array();
46
47 /**
48 * List of different countries' address formats.
49 *
50 * @var string[]
51 */
52 private $address_formats;
53
54 /**
55 * Returns and/or create the single instance of this class.
56 *
57 * @since 1.2.0
58 *
59 * @return Charitable_Locations
60 */
61 public static function get_instance() {
62 if ( is_null( self::$instance ) ) {
63 self::$instance = new self();
64 }
65
66 return self::$instance;
67 }
68
69 /**
70 * Set up the class.
71 *
72 * @since 1.2.0
73 */
74 private function __construct() {}
75
76 /**
77 * Return an array with all the countries supported by Charitable.
78 *
79 * @since 1.0.0
80 *
81 * @return string[]
82 */
83 public function get_countries() {
84 if ( empty( $this->countries ) ) {
85 $this->countries = apply_filters( 'charitable_countries', include( charitable()->get_path( 'directory' ) . 'i18n/countries.php' ) );
86 }
87
88 return $this->countries;
89 }
90
91 /**
92 * Return the country codes of countries with states.
93 *
94 * @since 1.0.0
95 *
96 * @return string[]
97 */
98 public function get_countries_with_states() {
99 return array(
100 'AU',
101 'BD',
102 'BG',
103 'BR',
104 'CA',
105 'CN',
106 'ES',
107 'GR',
108 'HK',
109 'HU',
110 'ID',
111 'IN',
112 'IR',
113 'IT',
114 'JP',
115 'MX',
116 'MY',
117 'NP',
118 'NZ',
119 'PE',
120 'TH',
121 'TR',
122 'US',
123 'ZA',
124 );
125 }
126
127 /**
128 * Return an array with all the states supported by Charitable.
129 *
130 * @since 1.0.0
131 *
132 * @return string[]
133 */
134 public function get_all_states() {
135
136 foreach ( $this->get_countries_with_states() as $country_code ) {
137 $this->get_states_for_country( $country_code );
138 }
139
140 return $this->states;
141 }
142
143 /**
144 * Return the states in this country.
145 *
146 * @since 1.0.0
147 *
148 * @param string $country_code The three-character country code.
149 * @return string[]
150 */
151 public function get_states_for_country( $country_code ) {
152
153 if ( ! in_array( $country_code, $this->get_countries_with_states() ) ) {
154 return array();
155 }
156
157 if ( ! isset( $this->states[ $country_code ] ) ) {
158 $this->states[ $country_code ] = apply_filters( 'charitable_country_states', include( charitable()->get_path( 'directory' ) . '/i18n/states/' . $country_code . '.php' ), $country_code );
159 }
160
161 return $this->states[ $country_code ];
162 }
163
164 /**
165 * Get the base country for the website.
166 *
167 * @since 1.0.0
168 *
169 * @return string
170 */
171 public function get_base_country() {
172 $country = esc_attr( get_option( 'charitable_default_country' ) );
173
174 return apply_filters( 'charitable_countries_base_country', $country );
175 }
176
177 /**
178 * Get country address formats.
179 *
180 * @since 1.0.0
181 *
182 * @return string[]
183 */
184 public function get_address_formats() {
185
186 if ( ! isset( $this->address_formats ) ) {
187
188 // Common formats.
189 $postcode_before_city = "{company}\n{name}\n{address_1}\n{address_2}\n{postcode} {city}\n{country}";
190
191 // Define address formats.
192 $this->address_formats = apply_filters('charitable_localisation_address_formats', array(
193 'default' => "{name}\n{company}\n{address_1}\n{address_2}\n{city}\n{state}\n{postcode}\n{country}",
194 'AU' => "{name}\n{company}\n{address_1}\n{address_2}\n{city} {state} {postcode}\n{country}",
195 'AT' => $postcode_before_city,
196 'BE' => $postcode_before_city,
197 'CA' => "{company}\n{name}\n{address_1}\n{address_2}\n{city} {state} {postcode}\n{country}",
198 'CH' => $postcode_before_city,
199 'CN' => "{country} {postcode}\n{state}, {city}, {address_2}, {address_1}\n{company}\n{name}",
200 'CZ' => $postcode_before_city,
201 'DE' => $postcode_before_city,
202 'EE' => $postcode_before_city,
203 'FI' => $postcode_before_city,
204 'DK' => $postcode_before_city,
205 'FR' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode} {city_upper}\n{country}",
206 'HK' => "{company}\n{first_name} {last_name_upper}\n{address_1}\n{address_2}\n{city_upper}\n{state_upper}\n{country}",
207 'HU' => "{name}\n{company}\n{city}\n{address_1}\n{address_2}\n{postcode}\n{country}",
208 'IS' => $postcode_before_city,
209 'IT' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode}\n{city}\n{state_upper}\n{country}",
210 'JP' => "{postcode}\n{state}{city}{address_1}\n{address_2}\n{company}\n{last_name} {first_name}\n {country}",
211 'TW' => "{postcode}\n{city}{address_2}\n{address_1}\n{company}\n{last_name} {first_name}\n {country}",
212 'LI' => $postcode_before_city,
213 'NL' => $postcode_before_city,
214 'NZ' => "{name}\n{company}\n{address_1}\n{address_2}\n{city} {postcode}\n{country}",
215 'NO' => $postcode_before_city,
216 'PL' => $postcode_before_city,
217 'SK' => $postcode_before_city,
218 'SI' => $postcode_before_city,
219 'ES' => "{name}\n{company}\n{address_1}\n{address_2}\n{postcode} {city}\n{state}\n{country}",
220 'SE' => $postcode_before_city,
221 'TR' => "{name}\n{company}\n{address_1}\n{address_2}\n{postcode} {city} {state}\n{country}",
222 'US' => "{name}\n{company}\n{address_1}\n{address_2}\n{city}, {state_code} {postcode}\n{country}",
223 'VN' => "{name}\n{company}\n{address_1}\n{city}\n{country}",
224 ));
225
226 }//end if
227
228 return $this->address_formats;
229 }
230
231 /**
232 * Return the address format to use for the given address.
233 *
234 * @since 1.0.0
235 *
236 * @param array $address_fields Address fields.
237 * @return string
238 */
239 private function get_address_format( $address_fields ) {
240 $formats = $this->get_address_formats();
241 $country = $address_fields['country'];
242
243 /**
244 * If the country is set and it has its own specific format, use that. Otherwise, use default format.
245 */
246 $format = isset( $formats[ $country ] ) ? $formats[ $country ] : $formats['default'];
247
248 /**
249 * By default, the country field is left out for local addresses.
250 *
251 * Use the `charitable_formatted_address_force_country_display` filter
252 * to force the country to always be printed.
253 *
254 * @since 1.0.0
255 *
256 * @param boolean $force_country Whether the country is always shown. False by default.
257 */
258 if ( $country == $this->get_base_country() && false === apply_filters( 'charitable_formatted_address_force_country_display', false ) ) {
259 $format = str_replace( '{country}', '', $format );
260 }
261
262 return $format;
263
264 }
265
266 /**
267 * Process an array of address fields, trimming whitespace and adding full country and full state names.
268 *
269 * @since 1.0.0
270 *
271 * @param array $address_fields Address fields.
272 * @return string[]
273 */
274 private function sanitize_address_fields( $address_fields ) {
275 if ( ! is_array( $address_fields ) ) {
276 return $address_fields;
277 }
278
279 $address_fields = array_map( 'trim', array_filter( $address_fields, 'is_string' ) );
280
281 /**
282 * Set up empty default fields and merge with address fields.
283 */
284 $defaults = array(
285 'first_name' => '',
286 'last_name' => '',
287 'company' => '',
288 'address' => '',
289 'address_2' => '',
290 'city' => '',
291 'state' => '',
292 'full_state' => '',
293 'postcode' => '',
294 'country' => '',
295 'full_country' => '',
296 );
297
298 $address_fields = array_merge( $defaults, $address_fields );
299 $country = $address_fields['country'];
300 $state = $address_fields['state'];
301
302 /**
303 * If country is empty, return address fields as they are.
304 */
305 if ( empty( $country ) ) {
306 return $address_fields;
307 }
308
309 $countries = $this->get_countries();
310
311 if ( array_key_exists( $country, $countries ) ) {
312 $address_fields['full_country'] = $countries[ $country ];
313 }
314
315 /**
316 * Return address fields as they are if state is not set.
317 */
318 if ( empty( $state ) ) {
319 return $address_fields;
320 }
321
322 $states = $this->get_states_for_country( $country );
323
324 if ( array_key_exists( $address_fields['state'], $states ) ) {
325 $address_fields['full_state'] = $states[ $address_fields['state'] ];
326 }
327
328 return $address_fields;
329
330 }
331
332 /**
333 * Get formatted address based on country of address.
334 *
335 * @since 1.0.0
336 *
337 * @param array $address_fields Address fields.
338 * @return string
339 */
340 public function get_formatted_address( $address_fields = array() ) {
341 $address_fields = $this->sanitize_address_fields( $address_fields );
342 $formatted_address = '';
343
344 /* If main address field is empty, then do not format. */
345 if ( empty( $address_fields['address'] ) ) {
346 return $formatted_address;
347 }
348
349 /* Substitute address parts into the string */
350 $replace = array_map( 'esc_html', apply_filters( 'charitable_formatted_address_replacements', array(
351 '{first_name}' => $address_fields['first_name'],
352 '{last_name}' => $address_fields['last_name'],
353 '{name}' => $address_fields['first_name'] . ' ' . $address_fields['last_name'],
354 '{company}' => $address_fields['company'],
355 '{address_1}' => $address_fields['address'],
356 '{address_2}' => $address_fields['address_2'],
357 '{city}' => $address_fields['city'],
358 '{state}' => $address_fields['full_state'],
359 '{postcode}' => $address_fields['postcode'],
360 '{country}' => $address_fields['full_country'],
361 '{first_name_upper}' => strtoupper( $address_fields['first_name'] ),
362 '{last_name_upper}' => strtoupper( $address_fields['last_name'] ),
363 '{name_upper}' => strtoupper( $address_fields['first_name'] . ' ' . $address_fields['last_name'] ),
364 '{company_upper}' => strtoupper( $address_fields['company'] ),
365 '{address_1_upper}' => strtoupper( $address_fields['address'] ),
366 '{address_2_upper}' => strtoupper( $address_fields['address_2'] ),
367 '{city_upper}' => strtoupper( $address_fields['city'] ),
368 '{state_upper}' => strtoupper( $address_fields['full_state'] ),
369 '{state_code}' => strtoupper( $address_fields['state'] ),
370 '{postcode_upper}' => strtoupper( $address_fields['postcode'] ),
371 '{country_upper}' => strtoupper( $address_fields['full_country'] ),
372 ), $address_fields ) );
373
374 $format = $this->get_address_format( $address_fields );
375 $formatted_address = str_replace( array_keys( $replace ), $replace, $format );
376
377 /* Clean up white space */
378 $formatted_address = preg_replace( '/ +/', ' ', trim( $formatted_address ) );
379 $formatted_address = preg_replace( '/\n\n+/', "\n", $formatted_address );
380
381 /* Break newlines apart and remove empty lines/trim commas and white space */
382 $formatted_address = explode( "\n", $formatted_address );
383 $formatted_address = array_map( array( $this, 'trim_formatted_address_line' ), $formatted_address );
384 $formatted_address = array_filter( $formatted_address );
385
386 /* Add html breaks */
387 $formatted_address = implode( '<br/>', $formatted_address );
388
389 return $formatted_address;
390
391 }
392
393 /**
394 * Trim white space and commas off a line.
395 *
396 * @since 1.0.0
397 *
398 * @param string $line The line to be trimmed.
399 * @return string
400 */
401 private function trim_formatted_address_line( $line ) {
402 return trim( $line, ', ' );
403 }
404 }
405
406 endif;
407