PluginProbe
Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) / 1.6.31
Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) v1.6.31
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.31, at includes/class-charitable-locations.php

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