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

397 lines 11.7 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) 2015, Studio 164a
9 * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
10 */
11
12 if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly.
13
14 if ( ! class_exists( 'Charitable_Locations' ) ) :
15
16 /**
17 * Charitable_Locations
18 *
19 * @since 1.0.0
20 */
21 class Charitable_Locations {
22
23 /**
24 * The single instance of this class.
25 *
26 * @var Charitable_Locations|null
27 * @access private
28 * @static
29 */
30 private static $instance = null;
31
32 /**
33 * List of countries in country_code=>name format.
34 *
35 * @var string[] $countries
36 * @access private
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 * @access private
46 * @since 1.0.0
47 */
48 private $states = array();
49
50 /**
51 * List of different countries' address formats.
52 *
53 * @var string[]
54 * @access private
55 */
56 private $address_formats;
57
58 /**
59 * Returns and/or create the single instance of this class.
60 *
61 * @return Charitable_Locations
62 * @access public
63 * @since 1.2.0
64 */
65 public static function get_instance() {
66 if ( is_null( self::$instance ) ) {
67 self::$instance = new Charitable_Locations();
68 }
69
70 return self::$instance;
71 }
72
73 /**
74 * Set up the class.
75 *
76 * @access private
77 * @since 1.2.0
78 */
79 private function __construct() {}
80
81 /**
82 * Return an array with all the countries supported by Charitable.
83 *
84 * @return string[]
85 * @access public
86 * @since 1.0.0
87 */
88 public function get_countries() {
89 if ( empty( $this->countries ) ) {
90 $this->countries = apply_filters( 'charitable_countries', include( charitable()->get_path('directory') . 'i18n/countries.php' ) );
91 }
92
93 return $this->countries;
94 }
95
96 /**
97 * Return the country codes of countries with states.
98 *
99 * @return string[]
100 * @access public
101 * @since 1.0.0
102 */
103 public function get_countries_with_states() {
104 return array(
105 'AU',
106 'BD',
107 'BG',
108 'BR',
109 'CA',
110 'CN',
111 'ES',
112 'GR',
113 'HK',
114 'HU',
115 'ID',
116 'IN',
117 'IR',
118 'IT',
119 'JP',
120 'MX',
121 'MY',
122 'NP',
123 'NZ',
124 'PE',
125 'TH',
126 'TR',
127 'US',
128 'ZA'
129 );
130 }
131
132 /**
133 * Return an array with all the states supported by Charitable.
134 *
135 * @return string[]
136 * @access public
137 * @since 1.0.0
138 */
139 public function get_all_states() {
140 foreach ( $this->get_countries_with_states() as $country_code ) {
141 $this->get_states_for_country( $country_code );
142 }
143
144 return $this->states;
145 }
146
147 /**
148 * Return the states in this country.
149 *
150 * @param string $country_code
151 * @return string[]
152 * @access public
153 * @since 1.0.0
154 */
155 public function get_states_for_country( $country_code ) {
156 if ( ! in_array( $country_code, $this->get_countries_with_states() ) ) {
157 return array();
158 }
159
160 if ( ! isset( $this->states[$country_code] ) ) {
161 $this->states[$country_code] = apply_filters( 'charitable_country_states', include( charitable()->get_path('directory') . '/i18n/states/' . $country_code . '.php' ), $country_code );
162 }
163
164 return $this->states[$country_code];
165 }
166
167 /**
168 * Get the base country for the website.
169 *
170 * @return string
171 * @access public
172 * @since 1.0.0
173 */
174 public function get_base_country() {
175 $country = esc_attr( get_option( 'charitable_default_country' ) );
176
177 return apply_filters( 'charitable_countries_base_country', $country );
178 }
179
180 /**
181 * Get country address formats.
182 *
183 * @return string[]
184 * @access public
185 * @since 1.0.0
186 */
187 public function get_address_formats() {
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 }
229
230 return $this->address_formats;
231 }
232
233 /**
234 * Return the address format to use for the given address.
235 *
236 * @param array $address_fields
237 * @return string
238 * @access private
239 * @since 1.0.0
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 * For local addresses, leave the country field blank (unless explicitly forced).
252 *
253 * @hook charitable_formatted_address_force_country_display
254 */
255 if ( $country == $this->get_base_country() && false === apply_filters( 'charitable_formatted_address_force_country_display', false ) ) {
256 $format = str_replace( '{country}', '', $format );
257 }
258
259 return $format;
260 }
261
262 /**
263 * Process an array of address fields, trimming whitespace and adding full country and full state names.
264 *
265 * @param string[] $address_fields
266 * @return string[]
267 * @access private
268 * @since 1.0.0
269 */
270 private function sanitize_address_fields( $address_fields ) {
271
272 $address_fields = array_map( 'trim', $address_fields );
273
274 /**
275 * Set up empty default fields and merge with address fields.
276 */
277 $defaults = array(
278 'first_name' => '',
279 'last_name' => '',
280 'company' => '',
281 'address' => '',
282 'address_2' => '',
283 'city' => '',
284 'state' => '',
285 'full_state' => '',
286 'postcode' => '',
287 'country' => '',
288 'full_country' => ''
289 );
290 $address_fields = array_merge( $defaults, $address_fields );
291
292 $country = $address_fields['country'];
293 $state = $address_fields['state'];
294
295 /**
296 * If country is empty, return address fields as they are.
297 */
298 if ( empty( $country ) ) {
299 return $address_fields;
300 }
301
302 $countries = $this->get_countries();
303
304 if ( isset( $countries[ $country ] ) ) {
305
306 $address_fields['full_country'] = $countries[ $country ];
307
308 }
309
310 /**
311 * Return address fields as they are if state is not set.
312 */
313 if ( empty( $state ) ) {
314 return $address_fields;
315 }
316
317 $states = $this->get_states_for_country( $country );
318
319 if ( isset( $states[ $address_fields['state'] ] ) ) {
320
321 $address_fields['full_state'] = $states[ $address_fields['state'] ];
322
323 }
324
325 return $address_fields;
326 }
327
328 /**
329 * Get formatted address based on country of address.
330 *
331 * @param string[] $address_fields
332 * @return string
333 * @access public
334 * @since 1.0.0
335 */
336 public function get_formatted_address( $address_fields = array() ) {
337
338 $address_fields = $this->sanitize_address_fields( $address_fields );
339
340 // Substitute address parts into the string
341 $replace = array_map( 'esc_html', apply_filters( 'charitable_formatted_address_replacements', array(
342 '{first_name}' => $address_fields['first_name'],
343 '{last_name}' => $address_fields['last_name'],
344 '{name}' => $address_fields['first_name'] . ' ' . $address_fields['last_name'],
345 '{company}' => $address_fields['company'],
346 '{address_1}' => $address_fields['address'],
347 '{address_2}' => $address_fields['address_2'],
348 '{city}' => $address_fields['city'],
349 '{state}' => $address_fields['full_state'],
350 '{postcode}' => $address_fields['postcode'],
351 '{country}' => $address_fields['full_country'],
352 '{first_name_upper}' => strtoupper( $address_fields['first_name'] ),
353 '{last_name_upper}' => strtoupper( $address_fields['last_name'] ),
354 '{name_upper}' => strtoupper( $address_fields['first_name'] . ' ' . $address_fields['last_name'] ),
355 '{company_upper}' => strtoupper( $address_fields['company'] ),
356 '{address_1_upper}' => strtoupper( $address_fields['address'] ),
357 '{address_2_upper}' => strtoupper( $address_fields['address_2'] ),
358 '{city_upper}' => strtoupper( $address_fields['city'] ),
359 '{state_upper}' => strtoupper( $address_fields['full_state'] ),
360 '{state_code}' => strtoupper( $address_fields['state'] ),
361 '{postcode_upper}' => strtoupper( $address_fields['postcode'] ),
362 '{country_upper}' => strtoupper( $address_fields['full_country'] ),
363 ), $address_fields ) );
364
365 $format = $this->get_address_format( $address_fields );
366 $formatted_address = str_replace( array_keys( $replace ), $replace, $format );
367
368 // Clean up white space
369 $formatted_address = preg_replace( '/ +/', ' ', trim( $formatted_address ) );
370 $formatted_address = preg_replace( '/\n\n+/', "\n", $formatted_address );
371
372 // Break newlines apart and remove empty lines/trim commas and white space
373 $formatted_address = explode( "\n", $formatted_address );
374 $formatted_address = array_map( array( $this, 'trim_formatted_address_line' ), $formatted_address );
375 $formatted_address = array_filter( $formatted_address );
376
377 // Add html breaks
378 $formatted_address = implode( '<br/>', $formatted_address );
379
380 // We're done!
381 return $formatted_address;
382 }
383
384 /**
385 * trim white space and commas off a line.
386 *
387 * @param string $line
388 * @return string
389 * @access private
390 * @since 1.0.0
391 */
392 private function trim_formatted_address_line( $line ) {
393 return trim( $line, ", " );
394 }
395 }
396
397 endif; // End class_exists check