Commit | Line | Data |
---|---|---|
6a488035 | 1 | <?php |
6a488035 TO |
2 | /* |
3 | +--------------------------------------------------------------------+ | |
232624b1 | 4 | | CiviCRM version 4.4 | |
6a488035 TO |
5 | +--------------------------------------------------------------------+ |
6 | | Copyright CiviCRM LLC (c) 2004-2013 | | |
7 | +--------------------------------------------------------------------+ | |
8 | | This file is a part of CiviCRM. | | |
9 | | | | |
10 | | CiviCRM is free software; you can copy, modify, and distribute it | | |
11 | | under the terms of the GNU Affero General Public License | | |
12 | | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. | | |
13 | | | | |
14 | | CiviCRM is distributed in the hope that it will be useful, but | | |
15 | | WITHOUT ANY WARRANTY; without even the implied warranty of | | |
16 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | | |
17 | | See the GNU Affero General Public License for more details. | | |
18 | | | | |
19 | | You should have received a copy of the GNU Affero General Public | | |
20 | | License and the CiviCRM Licensing Exception along | | |
21 | | with this program; if not, contact CiviCRM LLC | | |
22 | | at info[AT]civicrm[DOT]org. If you have questions about the | | |
23 | | GNU Affero General Public License or the licensing of CiviCRM, | | |
24 | | see the CiviCRM license FAQ at http://civicrm.org/licensing | | |
25 | +--------------------------------------------------------------------+ | |
26 | */ | |
27 | ||
28 | /** | |
29 | * | |
30 | * @package CRM | |
31 | * @copyright CiviCRM LLC (c) 2004-2013 | |
32 | * $Id$ | |
33 | * | |
34 | */ | |
35 | ||
36 | /** | |
37 | * This is class to handle address related functions | |
38 | */ | |
39 | class CRM_Core_BAO_Address extends CRM_Core_DAO_Address { | |
40 | ||
41 | /** | |
42 | * takes an associative array and creates a address | |
43 | * | |
44 | * @param array $params (reference ) an assoc array of name/value pairs | |
45 | * @param boolean $fixAddress true if you need to fix (format) address values | |
46 | * before inserting in db | |
47 | * | |
48 | * @return array $blocks array of created address | |
49 | * @access public | |
50 | * @static | |
51 | */ | |
52 | static function create(&$params, $fixAddress, $entity = NULL) { | |
53 | if (!isset($params['address']) || !is_array($params['address'])) { | |
54 | return; | |
55 | } | |
56 | CRM_Core_BAO_Block::sortPrimaryFirst($params['address']); | |
57 | $addresses = array(); | |
58 | $contactId = NULL; | |
59 | ||
60 | $updateBlankLocInfo = CRM_Utils_Array::value('updateBlankLocInfo', $params, FALSE); | |
61 | if (!$entity) { | |
62 | $contactId = $params['contact_id']; | |
63 | //get all the addresses for this contact | |
64 | $addresses = self::allAddress($contactId, $updateBlankLocInfo); | |
65 | } | |
66 | else { | |
67 | // get all address from location block | |
68 | $entityElements = array( | |
69 | 'entity_table' => $params['entity_table'], | |
70 | 'entity_id' => $params['entity_id'], | |
71 | ); | |
72 | $addresses = self::allEntityAddress($entityElements); | |
73 | } | |
74 | ||
75 | $isPrimary = $isBilling = TRUE; | |
76 | $blocks = array(); | |
77 | foreach ($params['address'] as $key => $value) { | |
78 | if (!is_array($value)) { | |
79 | continue; | |
80 | } | |
81 | ||
82 | $addressExists = self::dataExists($value); | |
83 | if ( !CRM_Utils_Array::value('id', $value) ) { | |
84 | if ($updateBlankLocInfo) { | |
85 | if ((!empty($addresses) || !$addressExists) && array_key_exists($key, $addresses)) { | |
86 | $value['id'] = $addresses[$key]; | |
87 | } | |
88 | } | |
89 | else { | |
90 | if (!empty($addresses) && array_key_exists(CRM_Utils_Array::value('location_type_id', $value), $addresses)) { | |
91 | $value['id'] = $addresses[CRM_Utils_Array::value('location_type_id', $value)]; | |
92 | } | |
93 | } | |
94 | } | |
95 | ||
96 | // Note there could be cases when address info already exist ($value[id] is set) for a contact/entity | |
97 | // BUT info is not present at this time, and therefore we should be really careful when deleting the block. | |
98 | // $updateBlankLocInfo will help take appropriate decision. CRM-5969 | |
99 | if (isset($value['id']) && !$addressExists && $updateBlankLocInfo) { | |
100 | //delete the existing record | |
101 | CRM_Core_BAO_Block::blockDelete('Address', array('id' => $value['id'])); | |
102 | continue; | |
103 | } | |
104 | elseif (!$addressExists) { | |
105 | continue; | |
106 | } | |
107 | ||
108 | if ($isPrimary && CRM_Utils_Array::value('is_primary', $value)) { | |
109 | $isPrimary = FALSE; | |
110 | } | |
111 | else { | |
112 | $value['is_primary'] = 0; | |
113 | } | |
114 | ||
115 | if ($isBilling && CRM_Utils_Array::value('is_billing', $value)) { | |
116 | $isBilling = FALSE; | |
117 | } | |
118 | else { | |
119 | $value['is_billing'] = 0; | |
120 | } | |
121 | ||
122 | if (!CRM_Utils_Array::value('manual_geo_code', $value)) { | |
123 | $value['manual_geo_code'] = 0; | |
124 | } | |
125 | $value['contact_id'] = $contactId; | |
126 | $blocks[] = self::add($value, $fixAddress); | |
127 | } | |
128 | ||
129 | return $blocks; | |
130 | } | |
131 | ||
132 | /** | |
133 | * takes an associative array and adds address | |
134 | * | |
135 | * @param array $params (reference ) an assoc array of name/value pairs | |
136 | * @param boolean $fixAddress true if you need to fix (format) address values | |
137 | * before inserting in db | |
138 | * | |
139 | * @return object CRM_Core_BAO_Address object on success, null otherwise | |
140 | * @access public | |
141 | * @static | |
142 | */ | |
143 | static function add(&$params, $fixAddress) { | |
144 | static $customFields = NULL; | |
145 | $address = new CRM_Core_DAO_Address(); | |
146 | ||
147 | // fixAddress mode to be done | |
148 | if ($fixAddress) { | |
149 | CRM_Core_BAO_Address::fixAddress($params); | |
150 | } | |
151 | ||
152 | $hook = empty($params['id']) ? 'create' : 'edit'; | |
153 | CRM_Utils_Hook::pre($hook, 'Address', CRM_Utils_Array::value('id', $params), $params); | |
154 | ||
155 | // if id is set & is_primary isn't we can assume no change | |
156 | if (is_numeric(CRM_Utils_Array::value('is_primary', $params)) || empty($params['id'])) { | |
157 | CRM_Core_BAO_Block::handlePrimary($params, get_class()); | |
158 | } | |
159 | $config = CRM_Core_Config::singleton(); | |
160 | $address->copyValues($params); | |
161 | ||
162 | $address->save(); | |
163 | ||
164 | if ($address->id) { | |
165 | if (!$customFields) { | |
166 | $customFields = CRM_Core_BAO_CustomField::getFields('Address', FALSE, TRUE); | |
167 | } | |
168 | if (!empty($customFields)) { | |
169 | $addressCustom = CRM_Core_BAO_CustomField::postProcess($params, | |
170 | $customFields, | |
171 | $address->id, | |
172 | 'Address', | |
173 | TRUE | |
174 | ); | |
175 | } | |
176 | if (!empty($addressCustom)) { | |
177 | CRM_Core_BAO_CustomValueTable::store($addressCustom, 'civicrm_address', $address->id); | |
178 | } | |
179 | ||
180 | //call the function to sync shared address | |
181 | self::processSharedAddress($address->id, $params); | |
182 | ||
183 | // call the function to create shared relationships | |
184 | // we only create create relationship if address is shared by Individual | |
185 | if ($address->master_id != 'null') { | |
186 | self::processSharedAddressRelationship($address->master_id, $params); | |
187 | } | |
188 | ||
189 | // lets call the post hook only after we've done all the follow on processing | |
190 | CRM_Utils_Hook::post($hook, 'Address', $address->id, $address); | |
191 | } | |
192 | ||
193 | return $address; | |
194 | } | |
195 | ||
196 | /** | |
197 | * format the address params to have reasonable values | |
198 | * | |
199 | * @param array $params (reference ) an assoc array of name/value pairs | |
200 | * | |
201 | * @return void | |
202 | * @access public | |
203 | * @static | |
204 | */ | |
205 | static function fixAddress(&$params) { | |
206 | if (CRM_Utils_Array::value('billing_street_address', $params)) { | |
207 | //Check address is comming from online contribution / registration page | |
208 | //Fixed :CRM-5076 | |
209 | $billing = array( | |
210 | 'street_address' => 'billing_street_address', | |
211 | 'city' => 'billing_city', | |
212 | 'postal_code' => 'billing_postal_code', | |
213 | 'state_province' => 'billing_state_province', | |
214 | 'state_province_id' => 'billing_state_province_id', | |
215 | 'country' => 'billing_country', | |
216 | 'country_id' => 'billing_country_id', | |
217 | ); | |
218 | ||
219 | foreach ($billing as $key => $val) { | |
220 | if ($value = CRM_Utils_Array::value($val, $params)) { | |
221 | if (CRM_Utils_Array::value($key, $params)) { | |
222 | unset($params[$val]); | |
223 | } | |
224 | else { | |
225 | //add new key and removed old | |
226 | $params[$key] = $value; | |
227 | unset($params[$val]); | |
228 | } | |
229 | } | |
230 | } | |
231 | } | |
232 | ||
233 | /* Split the zip and +4, if it's in US format */ | |
234 | if (CRM_Utils_Array::value('postal_code', $params) && | |
235 | preg_match('/^(\d{4,5})[+-](\d{4})$/', | |
236 | $params['postal_code'], | |
237 | $match | |
238 | ) | |
239 | ) { | |
240 | $params['postal_code'] = $match[1]; | |
241 | $params['postal_code_suffix'] = $match[2]; | |
242 | } | |
243 | ||
244 | // add country id if not set | |
245 | if ((!isset($params['country_id']) || !is_numeric($params['country_id'])) && | |
246 | isset($params['country']) | |
247 | ) { | |
248 | $country = new CRM_Core_DAO_Country(); | |
249 | $country->name = $params['country']; | |
250 | if (!$country->find(TRUE)) { | |
251 | $country->name = NULL; | |
252 | $country->iso_code = $params['country']; | |
253 | $country->find(TRUE); | |
254 | } | |
255 | $params['country_id'] = $country->id; | |
256 | } | |
257 | ||
258 | // add state_id if state is set | |
259 | if ((!isset($params['state_province_id']) || !is_numeric($params['state_province_id'])) | |
260 | && isset($params['state_province']) | |
261 | ) { | |
262 | if (!empty($params['state_province'])) { | |
263 | $state_province = new CRM_Core_DAO_StateProvince(); | |
264 | $state_province->name = $params['state_province']; | |
265 | ||
266 | // add country id if present | |
267 | if (!empty($params['country_id'])) { | |
268 | $state_province->country_id = $params['country_id']; | |
269 | } | |
270 | ||
271 | if (!$state_province->find(TRUE)) { | |
272 | unset($state_province->name); | |
273 | $state_province->abbreviation = $params['state_province']; | |
274 | $state_province->find(TRUE); | |
275 | } | |
276 | $params['state_province_id'] = $state_province->id; | |
277 | if (empty($params['country_id'])) { | |
278 | // set this here since we have it | |
279 | $params['country_id'] = $state_province->country_id; | |
280 | } | |
281 | } | |
282 | else { | |
283 | $params['state_province_id'] = 'null'; | |
284 | } | |
285 | } | |
286 | ||
287 | // add county id if county is set | |
288 | // CRM-7837 | |
289 | if ((!isset($params['county_id']) || !is_numeric($params['county_id'])) | |
290 | && isset($params['county']) && !empty($params['county']) | |
291 | ) { | |
292 | $county = new CRM_Core_DAO_County(); | |
293 | $county->name = $params['county']; | |
294 | ||
295 | if (isset($params['state_province_id'])) { | |
296 | $county->state_province_id = $params['state_province_id']; | |
297 | } | |
298 | ||
299 | if ($county->find(TRUE)) { | |
300 | $params['county_id'] = $county->id; | |
301 | } | |
302 | } | |
303 | ||
304 | // currently copy values populates empty fields with the string "null" | |
305 | // and hence need to check for the string null | |
306 | if (isset($params['state_province_id']) && | |
307 | is_numeric($params['state_province_id']) && | |
308 | (!isset($params['country_id']) || empty($params['country_id'])) | |
309 | ) { | |
310 | // since state id present and country id not present, hence lets populate it | |
311 | // jira issue http://issues.civicrm.org/jira/browse/CRM-56 | |
312 | $params['country_id'] = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_StateProvince', | |
313 | $params['state_province_id'], | |
314 | 'country_id' | |
315 | ); | |
316 | } | |
317 | ||
318 | //special check to ignore non numeric values if they are not | |
319 | //detected by formRule(sometimes happens due to internet latency), also allow user to unselect state/country | |
320 | if (isset($params['state_province_id'])) { | |
321 | if (empty($params['state_province_id'])) { | |
322 | $params['state_province_id'] = 'null'; | |
323 | } | |
324 | elseif (!is_numeric($params['state_province_id']) || | |
325 | ((int ) $params['state_province_id'] < 1000) | |
326 | ) { | |
327 | // CRM-3393 ( the hacky 1000 check) | |
328 | $params['state_province_id'] = 'null'; | |
329 | } | |
330 | } | |
331 | ||
332 | if (isset($params['country_id'])) { | |
333 | if (empty($params['country_id'])) { | |
334 | $params['country_id'] = 'null'; | |
335 | } | |
336 | elseif (!is_numeric($params['country_id']) || | |
337 | ((int ) $params['country_id'] < 1000) | |
338 | ) { | |
339 | // CRM-3393 ( the hacky 1000 check) | |
340 | $params['country_id'] = 'null'; | |
341 | } | |
342 | } | |
343 | ||
344 | // add state and country names from the ids | |
345 | if (isset($params['state_province_id']) && is_numeric($params['state_province_id'])) { | |
346 | $params['state_province'] = CRM_Core_PseudoConstant::stateProvinceAbbreviation($params['state_province_id']); | |
347 | } | |
348 | ||
349 | if (isset($params['country_id']) && is_numeric($params['country_id'])) { | |
350 | $params['country'] = CRM_Core_PseudoConstant::country($params['country_id']); | |
351 | } | |
352 | ||
353 | $config = CRM_Core_Config::singleton(); | |
354 | ||
355 | $asp = CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::ADDRESS_STANDARDIZATION_PREFERENCES_NAME, | |
356 | 'address_standardization_provider' | |
357 | ); | |
358 | // clean up the address via USPS web services if enabled | |
359 | if ($asp === 'USPS' && | |
360 | $params['country_id'] == 1228 | |
361 | ) { | |
362 | CRM_Utils_Address_USPS::checkAddress($params); | |
363 | ||
364 | // do street parsing again if enabled, since street address might have changed | |
ef0d4de8 DL |
365 | $parseStreetAddress = |
366 | CRM_Utils_Array::value( | |
367 | 'street_address_parsing', | |
368 | CRM_Core_BAO_Setting::valueOptions( | |
369 | CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME, | |
370 | 'address_options' | |
371 | ), | |
372 | FALSE | |
373 | ); | |
6a488035 TO |
374 | |
375 | if ($parseStreetAddress && !empty($params['street_address'])) { | |
376 | foreach (array( | |
377 | 'street_number', 'street_name', 'street_unit', 'street_number_suffix') as $fld) { | |
378 | unset($params[$fld]); | |
379 | } | |
380 | // main parse string. | |
381 | $parseString = CRM_Utils_Array::value('street_address', $params); | |
382 | $parsedFields = CRM_Core_BAO_Address::parseStreetAddress($parseString); | |
383 | ||
384 | // merge parse address in to main address block. | |
385 | $params = array_merge($params, $parsedFields); | |
386 | } | |
387 | } | |
388 | ||
389 | // add latitude and longitude and format address if needed | |
390 | if (!empty($config->geocodeMethod) && ($config->geocodeMethod != 'CRM_Utils_Geocode_OpenStreetMaps') && empty($params['manual_geo_code'])) { | |
391 | $class = $config->geocodeMethod; | |
392 | $class::format($params); | |
393 | } | |
394 | } | |
395 | ||
396 | /** | |
397 | * Check if there is data to create the object | |
398 | * | |
399 | * @param array $params (reference ) an assoc array of name/value pairs | |
400 | * | |
401 | * @return boolean | |
402 | * | |
403 | * @access public | |
404 | * @static | |
405 | */ | |
406 | static function dataExists(&$params) { | |
407 | //check if location type is set if not return false | |
408 | if (!isset($params['location_type_id'])) { | |
409 | return FALSE; | |
410 | } | |
411 | ||
412 | $config = CRM_Core_Config::singleton(); | |
413 | foreach ($params as $name => $value) { | |
414 | if (in_array($name, array( | |
415 | 'is_primary', 'location_type_id', 'id', 'contact_id', 'is_billing', 'display', 'master_id'))) { | |
416 | continue; | |
417 | } | |
418 | elseif (!CRM_Utils_System::isNull($value)) { | |
419 | // name could be country or country id | |
420 | if (substr($name, 0, 7) == 'country') { | |
421 | // make sure its different from the default country | |
422 | // iso code | |
423 | $defaultCountry = $config->defaultContactCountry(); | |
424 | // full name | |
425 | $defaultCountryName = $config->defaultContactCountryName(); | |
426 | ||
427 | if ($defaultCountry) { | |
428 | if ($value == $defaultCountry || | |
429 | $value == $defaultCountryName || | |
430 | $value == $config->defaultContactCountry | |
431 | ) { | |
432 | // do nothing | |
433 | } | |
434 | else { | |
435 | return TRUE; | |
436 | } | |
437 | } | |
438 | else { | |
439 | // return if null default | |
440 | return TRUE; | |
441 | } | |
442 | } | |
443 | else { | |
444 | return TRUE; | |
445 | } | |
446 | } | |
447 | } | |
448 | ||
449 | return FALSE; | |
450 | } | |
451 | ||
452 | /** | |
453 | * Given the list of params in the params array, fetch the object | |
454 | * and store the values in the values array | |
455 | * | |
456 | * @param array $entityBlock associated array of fields | |
457 | * @param boolean $microformat if microformat output is required | |
458 | * @param int $fieldName conditional field name | |
459 | * | |
460 | * @return array $addresses array with address fields | |
461 | * @access public | |
462 | * @static | |
463 | */ | |
464 | static function &getValues(&$entityBlock, $microformat = FALSE, $fieldName = 'contact_id') { | |
465 | if (empty($entityBlock)) { | |
466 | return NULL; | |
467 | } | |
468 | $addresses = array(); | |
469 | $address = new CRM_Core_BAO_Address(); | |
470 | ||
471 | if (!CRM_Utils_Array::value('entity_table', $entityBlock)) { | |
472 | $address->$fieldName = CRM_Utils_Array::value($fieldName, $entityBlock); | |
473 | } | |
474 | else { | |
475 | $addressIds = array(); | |
476 | $addressIds = self::allEntityAddress($entityBlock); | |
477 | ||
478 | if (!empty($addressIds[1])) { | |
479 | $address->id = $addressIds[1]; | |
480 | } | |
481 | else { | |
482 | return $addresses; | |
483 | } | |
484 | } | |
485 | //get primary address as a first block. | |
486 | $address->orderBy('is_primary desc, id'); | |
487 | ||
488 | $address->find(); | |
489 | ||
490 | $count = 1; | |
491 | while ($address->fetch()) { | |
492 | // deprecate reference. | |
493 | if ($count > 1) { | |
494 | foreach (array( | |
495 | 'state', 'state_name', 'country', 'world_region') as $fld) { | |
496 | if (isset($address->$fld))unset($address->$fld); | |
497 | } | |
498 | } | |
499 | $stree = $address->street_address; | |
500 | $values = array(); | |
501 | CRM_Core_DAO::storeValues($address, $values); | |
502 | ||
503 | // add state and country information: CRM-369 | |
504 | if (!empty($address->state_province_id)) { | |
505 | $address->state = CRM_Core_PseudoConstant::stateProvinceAbbreviation($address->state_province_id, FALSE); | |
506 | $address->state_name = CRM_Core_PseudoConstant::stateProvince($address->state_province_id, FALSE); | |
507 | } | |
508 | ||
509 | if (!empty($address->country_id)) { | |
510 | $address->country = CRM_Core_PseudoConstant::country($address->country_id); | |
511 | ||
512 | //get world region | |
513 | $regionId = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_Country', $address->country_id, 'region_id'); | |
514 | ||
515 | $address->world_region = CRM_Core_PseudoConstant::worldregion($regionId); | |
516 | } | |
517 | ||
518 | $address->addDisplay($microformat); | |
519 | ||
520 | $values['display'] = $address->display; | |
521 | $values['display_text'] = $address->display_text; | |
522 | ||
523 | if (is_numeric($address->master_id)) { | |
524 | $values['use_shared_address'] = 1; | |
525 | } | |
526 | ||
527 | $addresses[$count] = $values; | |
528 | ||
529 | //unset is_primary after first block. Due to some bug in earlier version | |
530 | //there might be more than one primary blocks, hence unset is_primary other than first | |
531 | if ($count > 1) { | |
532 | unset($addresses[$count]['is_primary']); | |
533 | } | |
534 | ||
535 | $count++; | |
536 | } | |
537 | ||
538 | return $addresses; | |
539 | } | |
540 | ||
541 | /** | |
542 | * Add the formatted address to $this-> display | |
543 | * | |
544 | * @param NULL | |
545 | * | |
546 | * @return void | |
547 | * | |
548 | * @access public | |
549 | * | |
550 | */ | |
551 | function addDisplay($microformat = FALSE) { | |
552 | $fields = array( | |
553 | // added this for CRM 1200 | |
554 | 'address_id' => $this->id, | |
555 | // CRM-4003 | |
556 | 'address_name' => str_replace('\ 1', ' ', $this->name), | |
557 | 'street_address' => $this->street_address, | |
558 | 'supplemental_address_1' => $this->supplemental_address_1, | |
559 | 'supplemental_address_2' => $this->supplemental_address_2, | |
560 | 'city' => $this->city, | |
561 | 'state_province_name' => isset($this->state_name) ? $this->state_name : "", | |
562 | 'state_province' => isset($this->state) ? $this->state : "", | |
563 | 'postal_code' => isset($this->postal_code) ? $this->postal_code : "", | |
564 | 'postal_code_suffix' => isset($this->postal_code_suffix) ? $this->postal_code_suffix : "", | |
565 | 'country' => isset($this->country) ? $this->country : "", | |
566 | 'world_region' => isset($this->world_region) ? $this->world_region : "", | |
567 | ); | |
568 | ||
569 | if (isset($this->county_id) && $this->county_id) { | |
570 | $fields['county'] = CRM_Core_PseudoConstant::county($this->county_id); | |
571 | } | |
572 | else { | |
573 | $fields['county'] = NULL; | |
574 | } | |
575 | ||
576 | $this->display = CRM_Utils_Address::format($fields, NULL, $microformat); | |
577 | $this->display_text = CRM_Utils_Address::format($fields); | |
578 | } | |
579 | ||
580 | /** | |
581 | * Get all the addresses for a specified contact_id, with the primary address being first | |
582 | * | |
583 | * @param int $id the contact id | |
584 | * | |
585 | * @return array the array of adrress data | |
586 | * @access public | |
587 | * @static | |
588 | */ | |
589 | static function allAddress($id, $updateBlankLocInfo = FALSE) { | |
590 | if (!$id) { | |
591 | return NULL; | |
592 | } | |
593 | ||
594 | $query = " | |
595 | SELECT civicrm_address.id as address_id, civicrm_address.location_type_id as location_type_id | |
596 | FROM civicrm_contact, civicrm_address | |
597 | WHERE civicrm_address.contact_id = civicrm_contact.id AND civicrm_contact.id = %1 | |
598 | ORDER BY civicrm_address.is_primary DESC, address_id ASC"; | |
599 | $params = array(1 => array($id, 'Integer')); | |
600 | ||
601 | $addresses = array(); | |
602 | $dao = CRM_Core_DAO::executeQuery($query, $params); | |
603 | $count = 1; | |
604 | while ($dao->fetch()) { | |
605 | if ($updateBlankLocInfo) { | |
606 | $addresses[$count++] = $dao->address_id; | |
607 | } | |
608 | else { | |
609 | $addresses[$dao->location_type_id] = $dao->address_id; | |
610 | } | |
611 | } | |
612 | return $addresses; | |
613 | } | |
614 | ||
615 | /** | |
616 | * Get all the addresses for a specified location_block id, with the primary address being first | |
617 | * | |
618 | * @param array $entityElements the array containing entity_id and | |
619 | * entity_table name | |
620 | * | |
621 | * @return array the array of adrress data | |
622 | * @access public | |
623 | * @static | |
624 | */ | |
625 | static function allEntityAddress(&$entityElements) { | |
626 | if (empty($entityElements)) { | |
627 | return $addresses; | |
628 | } | |
629 | ||
630 | $entityId = $entityElements['entity_id']; | |
631 | $entityTable = $entityElements['entity_table']; | |
632 | ||
633 | $sql = " | |
634 | SELECT civicrm_address.id as address_id | |
635 | FROM civicrm_loc_block loc, civicrm_location_type ltype, civicrm_address, {$entityTable} ev | |
636 | WHERE ev.id = %1 | |
637 | AND loc.id = ev.loc_block_id | |
638 | AND civicrm_address.id IN (loc.address_id, loc.address_2_id) | |
639 | AND ltype.id = civicrm_address.location_type_id | |
640 | ORDER BY civicrm_address.is_primary DESC, civicrm_address.location_type_id DESC, address_id ASC "; | |
641 | ||
642 | $params = array(1 => array($entityId, 'Integer')); | |
643 | $addresses = array(); | |
644 | $dao = CRM_Core_DAO::executeQuery($sql, $params); | |
645 | $locationCount = 1; | |
646 | while ($dao->fetch()) { | |
647 | $addresses[$locationCount] = $dao->address_id; | |
648 | $locationCount++; | |
649 | } | |
650 | return $addresses; | |
651 | } | |
652 | ||
653 | static function addStateCountryMap(&$stateCountryMap, $defaults = NULL) { | |
654 | // first fix the statecountry map if needed | |
655 | if (empty($stateCountryMap)) { | |
656 | return; | |
657 | } | |
658 | ||
659 | $config = CRM_Core_Config::singleton(); | |
660 | if (!isset($config->stateCountryMap)) { | |
661 | $config->stateCountryMap = array(); | |
662 | } | |
663 | ||
664 | $config->stateCountryMap = array_merge($config->stateCountryMap, $stateCountryMap); | |
665 | } | |
666 | ||
c5e02dc5 | 667 | static function fixAllStateSelects(&$form, $defaults, $batchFieldNames = false) { |
6a488035 | 668 | $config = CRM_Core_Config::singleton(); |
c5d184af DL |
669 | $map = null; |
670 | if (is_array($batchFieldNames)) { | |
671 | $map = $batchFieldNames; | |
672 | } | |
fe3098fd | 673 | elseif (!empty($config->stateCountryMap)) { |
c5d184af DL |
674 | $map = $config->stateCountryMap; |
675 | } | |
c5e02dc5 AH |
676 | if (!empty($map)) { |
677 | foreach ($map as $index => $match) { | |
fe3098fd PJ |
678 | if (array_key_exists('state_province', $match) |
679 | || array_key_exists('country', $match) | |
680 | || array_key_exists('county', $match) | |
6a488035 | 681 | ) { |
fe3098fd PJ |
682 | $countryElementName = CRM_Utils_Array::value('country', $match); |
683 | $stateProvinceElementName = CRM_Utils_Array::value('state_province', $match); | |
684 | $countyElementName = CRM_Utils_Array::value('county', $match); | |
6a488035 TO |
685 | CRM_Contact_Form_Edit_Address::fixStateSelect( |
686 | $form, | |
fe3098fd PJ |
687 | $countryElementName, |
688 | $stateProvinceElementName, | |
689 | $countyElementName, | |
690 | CRM_Utils_Array::value($countryElementName, $defaults), | |
691 | CRM_Utils_Array::value($stateProvinceElementName, $defaults) | |
6a488035 TO |
692 | ); |
693 | } | |
694 | else { | |
695 | unset($config->stateCountryMap[$index]); | |
696 | } | |
697 | } | |
698 | } | |
699 | } | |
700 | ||
701 | /** | |
702 | * Function to get address sequence | |
703 | * | |
704 | * @return array of address sequence. | |
705 | */ | |
706 | static function addressSequence() { | |
707 | $config = CRM_Core_Config::singleton(); | |
708 | $addressSequence = $config->addressSequence(); | |
709 | ||
710 | $countryState = $cityPostal = FALSE; | |
711 | foreach ($addressSequence as $key => $field) { | |
712 | if ( | |
713 | in_array($field, array('country', 'state_province')) && | |
714 | !$countryState | |
715 | ) { | |
716 | $countryState = TRUE; | |
717 | $addressSequence[$key] = 'country_state_province'; | |
718 | } | |
719 | elseif ( | |
720 | in_array($field, array('city', 'postal_code')) && | |
721 | !$cityPostal | |
722 | ) { | |
723 | $cityPostal = TRUE; | |
724 | $addressSequence[$key] = 'city_postal_code'; | |
725 | } | |
726 | elseif ( | |
727 | in_array($field, array('country', 'state_province', 'city', 'postal_code')) | |
728 | ) { | |
729 | unset($addressSequence[$key]); | |
730 | } | |
731 | } | |
732 | ||
733 | return $addressSequence; | |
734 | } | |
735 | ||
736 | /** | |
737 | * Parse given street address string in to street_name, | |
738 | * street_unit, street_number and street_number_suffix | |
739 | * eg "54A Excelsior Ave. Apt 1C", or "917 1/2 Elm Street" | |
740 | * | |
741 | * NB: civic street formats for en_CA and fr_CA used by default if those locales are active | |
742 | * otherwise en_US format is default action | |
743 | * | |
744 | * @param string Street address including number and apt | |
745 | * @param string Locale - to set locale used to parse address | |
746 | * | |
747 | * @return array $parseFields parsed fields values. | |
748 | * @access public | |
749 | * @static | |
750 | */ | |
751 | static function parseStreetAddress($streetAddress, $locale = NULL) { | |
752 | $config = CRM_Core_Config::singleton(); | |
753 | ||
754 | /* locales supported include: | |
755 | * en_US - http://pe.usps.com/cpim/ftp/pubs/pub28/pub28.pdf | |
756 | * en_CA - http://www.canadapost.ca/tools/pg/manual/PGaddress-e.asp | |
757 | * fr_CA - http://www.canadapost.ca/tools/pg/manual/PGaddress-f.asp | |
758 | * NB: common use of comma after street number also supported | |
759 | * default is en_US | |
760 | */ | |
761 | ||
762 | $supportedLocalesForParsing = array('en_US', 'en_CA', 'fr_CA'); | |
763 | if (!$locale) { | |
764 | $locale = $config->lcMessages; | |
765 | } | |
766 | // as different locale explicitly requested but is not available, display warning message and set $locale = 'en_US' | |
767 | if (!in_array($locale, $supportedLocalesForParsing)) { | |
768 | CRM_Core_Session::setStatus(ts('Unsupported locale specified to parseStreetAddress: %1. Proceeding with en_US locale.', array(1 => $locale)), ts('Unsupported Locale'), 'alert'); | |
769 | $locale = 'en_US'; | |
770 | } | |
771 | $parseFields = array( | |
772 | 'street_name' => '', | |
773 | 'street_unit' => '', | |
774 | 'street_number' => '', | |
775 | 'street_number_suffix' => '', | |
776 | ); | |
777 | ||
778 | if (empty($streetAddress)) { | |
779 | return $parseFields; | |
780 | } | |
781 | ||
782 | $streetAddress = trim($streetAddress); | |
783 | ||
784 | $matches = array(); | |
785 | if (in_array($locale, array( | |
786 | 'en_CA', 'fr_CA')) && preg_match('/^([A-Za-z0-9]+)[ ]*\-[ ]*/', $streetAddress, $matches)) { | |
787 | $parseFields['street_unit'] = $matches[1]; | |
788 | // unset from rest of street address | |
789 | $streetAddress = preg_replace('/^([A-Za-z0-9]+)[ ]*\-[ ]*/', '', $streetAddress); | |
790 | } | |
791 | ||
792 | // get street number and suffix. | |
793 | $matches = array(); | |
794 | //alter street number/suffix handling so that we accept -digit | |
795 | if (preg_match('/^[A-Za-z0-9]+([\S]+)/', $streetAddress, $matches)) { | |
796 | // check that $matches[0] is numeric, else assume no street number | |
797 | if (preg_match('/^(\d+)/', $matches[0])) { | |
798 | $streetNumAndSuffix = $matches[0]; | |
799 | ||
800 | // get street number. | |
801 | $matches = array(); | |
802 | if (preg_match('/^(\d+)/', $streetNumAndSuffix, $matches)) { | |
803 | $parseFields['street_number'] = $matches[0]; | |
804 | $suffix = preg_replace('/^(\d+)/', '', $streetNumAndSuffix); | |
805 | $parseFields['street_number_suffix'] = trim($suffix); | |
806 | } | |
807 | ||
808 | // unset from main street address. | |
809 | $streetAddress = preg_replace('/^[A-Za-z0-9]+([\S]+)/', '', $streetAddress); | |
810 | $streetAddress = trim($streetAddress); | |
811 | } | |
812 | } | |
813 | elseif (preg_match('/^(\d+)/', $streetAddress, $matches)) { | |
814 | $parseFields['street_number'] = $matches[0]; | |
815 | // unset from main street address. | |
816 | $streetAddress = preg_replace('/^(\d+)/', '', $streetAddress); | |
817 | $streetAddress = trim($streetAddress); | |
818 | } | |
819 | ||
820 | // suffix might be like 1/2 | |
821 | $matches = array(); | |
822 | if (preg_match('/^\d\/\d/', $streetAddress, $matches)) { | |
823 | $parseFields['street_number_suffix'] .= $matches[0]; | |
824 | ||
825 | // unset from main street address. | |
826 | $streetAddress = preg_replace('/^\d+\/\d+/', '', $streetAddress); | |
827 | $streetAddress = trim($streetAddress); | |
828 | } | |
829 | ||
830 | // now get the street unit. | |
831 | // supportable street unit formats. | |
832 | $streetUnitFormats = array( | |
833 | 'APT', 'APARTMENT', 'BSMT', 'BASEMENT', 'BLDG', 'BUILDING', | |
834 | 'DEPT', 'DEPARTMENT', 'FL', 'FLOOR', 'FRNT', 'FRONT', | |
835 | 'HNGR', 'HANGER', 'LBBY', 'LOBBY', 'LOWR', 'LOWER', | |
836 | 'OFC', 'OFFICE', 'PH', 'PENTHOUSE', 'TRLR', 'TRAILER', | |
837 | 'UPPR', 'RM', 'ROOM', 'SIDE', 'SLIP', 'KEY', | |
838 | 'LOT', 'PIER', 'REAR', 'SPC', 'SPACE', | |
839 | 'STOP', 'STE', 'SUITE', 'UNIT', '#', | |
840 | ); | |
841 | ||
842 | // overwriting $streetUnitFormats for 'en_CA' and 'fr_CA' locale | |
843 | if (in_array($locale, array( | |
844 | 'en_CA', 'fr_CA'))) { | |
845 | $streetUnitFormats = array('APT', 'APP', 'SUITE', 'BUREAU', 'UNIT'); | |
846 | } | |
847 | ||
848 | $streetUnitPreg = '/(' . implode('|\s', $streetUnitFormats) . ')(.+)?/i'; | |
849 | $matches = array(); | |
850 | if (preg_match($streetUnitPreg, $streetAddress, $matches)) { | |
851 | $parseFields['street_unit'] = trim($matches[0]); | |
852 | $streetAddress = str_replace($matches[0], '', $streetAddress); | |
853 | $streetAddress = trim($streetAddress); | |
854 | } | |
855 | ||
856 | // consider remaining string as street name. | |
857 | $parseFields['street_name'] = $streetAddress; | |
858 | ||
859 | //run parsed fields through stripSpaces to clean | |
860 | foreach ($parseFields as $parseField => $value) { | |
861 | $parseFields[$parseField] = CRM_Utils_String::stripSpaces($value); | |
862 | } | |
863 | ||
864 | return $parseFields; | |
865 | } | |
866 | ||
867 | /** | |
868 | * Validate the address fields based on the address options enabled | |
869 | * in the Address Settings | |
870 | * | |
871 | * @param array $fields an array of importable/exportable contact fields | |
872 | * | |
873 | * @return array $fields an array of contact fields and only the enabled address options | |
874 | * @access public | |
875 | * @static | |
876 | */ | |
877 | static function validateAddressOptions($fields) { | |
878 | static $addressOptions = NULL; | |
879 | if (!$addressOptions) { | |
ef0d4de8 DL |
880 | $addressOptions = |
881 | CRM_Core_BAO_Setting::valueOptions( | |
882 | CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME, | |
883 | 'address_options' | |
884 | ); | |
6a488035 TO |
885 | } |
886 | ||
887 | if (is_array($fields) && !empty($fields)) { | |
888 | foreach ($addressOptions as $key => $value) { | |
889 | if (!$value && isset($fields[$key])) { | |
890 | unset($fields[$key]); | |
891 | } | |
892 | } | |
893 | } | |
894 | return $fields; | |
895 | } | |
896 | ||
897 | /** | |
898 | * Check if current address is used by any other contacts | |
899 | * | |
900 | * @param int $addressId address id | |
901 | * | |
902 | * @return count of contacts that use this shared address | |
903 | * @access public | |
904 | * @static | |
905 | */ | |
906 | static function checkContactSharedAddress($addressId) { | |
907 | $query = 'SELECT count(id) FROM civicrm_address WHERE master_id = %1'; | |
908 | return CRM_Core_DAO::singleValueQuery($query, array(1 => array($addressId, 'Integer'))); | |
909 | } | |
910 | ||
911 | /** | |
912 | * Function to check if current address fields are shared with any other address | |
913 | * | |
914 | * @param array $fields address fields in profile | |
915 | * @param int $contactId contact id | |
916 | * | |
917 | * @access public | |
918 | * @static | |
919 | */ | |
920 | static function checkContactSharedAddressFields(&$fields, $contactId) { | |
921 | if (!$contactId || !is_array($fields) || empty($fields)) { | |
922 | return; | |
923 | } | |
924 | ||
925 | $sharedLocations = array(); | |
926 | ||
927 | $query = " | |
928 | SELECT is_primary, | |
929 | location_type_id | |
930 | FROM civicrm_address | |
931 | WHERE contact_id = %1 | |
932 | AND master_id IS NOT NULL"; | |
933 | ||
934 | $dao = CRM_Core_DAO::executeQuery($query, array(1 => array($contactId, 'Positive'))); | |
935 | while ($dao->fetch()) { | |
936 | $sharedLocations[$dao->location_type_id] = $dao->location_type_id; | |
937 | if ($dao->is_primary) { | |
938 | $sharedLocations['Primary'] = 'Primary'; | |
939 | } | |
940 | } | |
941 | ||
942 | //no need to process further. | |
943 | if (empty($sharedLocations)) { | |
944 | return; | |
945 | } | |
946 | ||
947 | $addressFields = array( | |
948 | 'city', | |
949 | 'county', | |
950 | 'country', | |
951 | 'geo_code_1', | |
952 | 'geo_code_2', | |
953 | 'postal_code', | |
954 | 'address_name', | |
955 | 'state_province', | |
956 | 'street_address', | |
957 | 'postal_code_suffix', | |
958 | 'supplemental_address_1', | |
959 | 'supplemental_address_2', | |
960 | ); | |
961 | ||
962 | foreach ($fields as $name => & $values) { | |
963 | if (!is_array($values) || empty($values)) { | |
964 | continue; | |
965 | } | |
966 | ||
967 | $nameVal = explode('-', $values['name']); | |
968 | $fldName = CRM_Utils_Array::value(0, $nameVal); | |
969 | $locType = CRM_Utils_Array::value(1, $nameVal); | |
970 | if (CRM_Utils_Array::value('location_type_id', $values)) { | |
971 | $locType = $values['location_type_id']; | |
972 | } | |
973 | ||
974 | if (in_array($fldName, $addressFields) && | |
975 | in_array($locType, $sharedLocations) | |
976 | ) { | |
977 | $values['is_shared'] = TRUE; | |
978 | } | |
979 | } | |
980 | } | |
981 | ||
982 | /** | |
983 | * Function to update the shared addresses if master address is modified | |
984 | * | |
985 | * @param int $addressId address id | |
986 | * @param array $params associated array of address params | |
987 | * | |
988 | * @return void | |
989 | * @access public | |
990 | * @static | |
991 | */ | |
992 | static function processSharedAddress($addressId, $params) { | |
993 | $query = 'SELECT id FROM civicrm_address WHERE master_id = %1'; | |
994 | $dao = CRM_Core_DAO::executeQuery($query, array(1 => array($addressId, 'Integer'))); | |
995 | ||
996 | // unset contact id | |
997 | $skipFields = array('is_primary', 'location_type_id', 'is_billing', 'master_id', 'contact_id'); | |
998 | foreach ($skipFields as $value) { | |
999 | unset($params[$value]); | |
1000 | } | |
1001 | ||
1002 | $addressDAO = new CRM_Core_DAO_Address(); | |
1003 | while ($dao->fetch()) { | |
1004 | $addressDAO->copyValues($params); | |
1005 | $addressDAO->id = $dao->id; | |
1006 | $addressDAO->save(); | |
1007 | $addressDAO->free(); | |
1008 | } | |
1009 | } | |
1010 | ||
1011 | /** | |
1012 | * Function to create relationship between contacts who share an address | |
1013 | * | |
1014 | * Note that currently we create relationship only for Individual contacts | |
1015 | * Individual + Household and Individual + Orgnization | |
1016 | * | |
1017 | * @param int $masterAddressId master address id | |
1018 | * @param array $params associated array of submitted values | |
1019 | * | |
1020 | * @return void | |
1021 | * @access public | |
1022 | * @static | |
1023 | */ | |
1024 | static function processSharedAddressRelationship($masterAddressId, $params) { | |
1025 | if (!$masterAddressId) { | |
1026 | return; | |
1027 | } | |
1028 | // get the contact type of contact being edited / created | |
1029 | $currentContactType = CRM_Contact_BAO_Contact::getContactType($params['contact_id']); | |
1030 | $currentContactId = $params['contact_id']; | |
1031 | ||
1032 | // if current contact is not of type individual return | |
1033 | if ($currentContactType != 'Individual') { | |
1034 | return; | |
1035 | } | |
1036 | ||
1037 | // get the contact id and contact type of shared contact | |
1038 | // check the contact type of shared contact, return if it is of type Individual | |
1039 | ||
1040 | $query = 'SELECT cc.id, cc.contact_type | |
1041 | FROM civicrm_contact cc INNER JOIN civicrm_address ca ON cc.id = ca.contact_id | |
1042 | WHERE ca.id = %1'; | |
1043 | ||
1044 | $dao = CRM_Core_DAO::executeQuery($query, array(1 => array($masterAddressId, 'Integer'))); | |
1045 | ||
1046 | $dao->fetch(); | |
1047 | ||
1048 | // if current contact is not of type individual return, since we don't create relationship between | |
1049 | // 2 individuals | |
1050 | if ($dao->contact_type == 'Individual') { | |
1051 | return; | |
1052 | } | |
1053 | $sharedContactType = $dao->contact_type; | |
1054 | $sharedContactId = $dao->id; | |
1055 | ||
1056 | // create relationship between ontacts who share an address | |
1057 | if ($sharedContactType == 'Organization') { | |
1058 | return CRM_Contact_BAO_Contact_Utils::createCurrentEmployerRelationship($currentContactId, $sharedContactId); | |
1059 | } | |
1060 | else { | |
1061 | // get the relationship type id of "Household Member of" | |
1062 | $relationshipType = 'Household Member of'; | |
1063 | } | |
1064 | ||
1065 | $cid = array('contact' => $currentContactId); | |
1066 | ||
1067 | $relTypeId = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_RelationshipType', $relationshipType, 'id', 'name_a_b'); | |
1068 | ||
1069 | if (!$relTypeId) { | |
1070 | CRM_Core_Error::fatal(ts("You seem to have deleted the relationship type '%1'", array(1 => $relationshipType))); | |
1071 | } | |
1072 | ||
1073 | // create relationship | |
1074 | $relationshipParams = array( | |
1075 | 'is_active' => TRUE, | |
1076 | 'relationship_type_id' => $relTypeId . '_a_b', | |
1077 | 'contact_check' => array($sharedContactId => TRUE), | |
1078 | ); | |
1079 | ||
1080 | list($valid, $invalid, $duplicate, | |
1081 | $saved, $relationshipIds | |
1082 | ) = CRM_Contact_BAO_Relationship::create($relationshipParams, $cid); | |
1083 | } | |
1084 | ||
1085 | /** | |
1086 | * Function to check and set the status for shared address delete | |
1087 | * | |
1088 | * @param int $addressId address id | |
1089 | * @param int $contactId contact id | |
1090 | * @param boolean $returnStatus by default false | |
1091 | * | |
1092 | * @return string $statusMessage | |
1093 | * @access public | |
1094 | * @static | |
1095 | */ | |
1096 | static function setSharedAddressDeleteStatus($addressId = NULL, $contactId = NULL, $returnStatus = FALSE) { | |
1097 | // check if address that is being deleted has any shared | |
1098 | if ($addressId) { | |
1099 | $entityId = $addressId; | |
1100 | $query = 'SELECT cc.id, cc.display_name | |
1101 | FROM civicrm_contact cc INNER JOIN civicrm_address ca ON cc.id = ca.contact_id | |
1102 | WHERE ca.master_id = %1'; | |
1103 | } | |
1104 | else { | |
1105 | $entityId = $contactId; | |
1106 | $query = 'SELECT cc.id, cc.display_name | |
1107 | FROM civicrm_address ca1 | |
1108 | INNER JOIN civicrm_address ca2 ON ca1.id = ca2.master_id | |
1109 | INNER JOIN civicrm_contact cc ON ca2.contact_id = cc.id | |
1110 | WHERE ca1.contact_id = %1'; | |
1111 | } | |
1112 | ||
1113 | $dao = CRM_Core_DAO::executeQuery($query, array(1 => array($entityId, 'Integer'))); | |
1114 | ||
1115 | $deleteStatus = array(); | |
1116 | $sharedContactList = array(); | |
1117 | $statusMessage = NULL; | |
1118 | $addressCount = 0; | |
1119 | while ($dao->fetch()) { | |
1120 | if (empty($deleteStatus)) { | |
1121 | $deleteStatus[] = ts('The following contact(s) have address records which were shared with the address you removed from this contact. These address records are no longer shared - but they have not been removed or altered.'); | |
1122 | } | |
1123 | ||
1124 | $contactViewUrl = CRM_Utils_System::url('civicrm/contact/view', "reset=1&cid={$dao->id}"); | |
1125 | $sharedContactList[] = "<a href='{$contactViewUrl}'>{$dao->display_name}</a>"; | |
1126 | $deleteStatus[] = "<a href='{$contactViewUrl}'>{$dao->display_name}</a>"; | |
1127 | ||
1128 | $addressCount++; | |
1129 | } | |
1130 | ||
1131 | if (!empty($deleteStatus)) { | |
1132 | $statusMessage = implode('<br/>', $deleteStatus) . '<br/>'; | |
1133 | } | |
1134 | ||
1135 | if (!$returnStatus) { | |
1136 | CRM_Core_Session::setStatus($statusMessage, '', 'info'); | |
1137 | } | |
1138 | else { | |
1139 | return array( | |
1140 | 'contactList' => $sharedContactList, | |
1141 | 'count' => $addressCount, | |
1142 | ); | |
1143 | } | |
1144 | } | |
12445e1c CW |
1145 | |
1146 | /** | |
1147 | * Call common delete function | |
1148 | */ | |
1149 | static function del($id) { | |
a65e2e55 | 1150 | return CRM_Contact_BAO_Contact::deleteObjectWithPrimary('Address', $id); |
12445e1c | 1151 | } |
dc86f881 CW |
1152 | |
1153 | /** | |
1154 | * Get options for a given address field. | |
1155 | * @see CRM_Core_DAO::buildOptions | |
1156 | * | |
1157 | * TODO: Should we always assume chainselect? What fn should be responsible for controlling that flow? | |
1158 | * TODO: In context of chainselect, what to return if e.g. a country has no states? | |
1159 | * | |
1160 | * @param String $fieldName | |
3d3ef918 | 1161 | * @param String $context: @see CRM_Core_DAO::buildOptionsContext |
dc86f881 CW |
1162 | * @param Array $props: whatever is known about this dao object |
1163 | */ | |
1164 | public static function buildOptions($fieldName, $context = NULL, $props = array()) { | |
1165 | $params = array(); | |
1166 | // Special logic for fields whose options depend on context or properties | |
1167 | switch ($fieldName) { | |
1168 | // Filter state_province list based on chosen country or site defaults | |
1169 | case 'state_province_id': | |
1170 | if (empty($props['country_id'])) { | |
1171 | $config = CRM_Core_Config::singleton(); | |
1172 | if (!empty($config->provinceLimit)) { | |
1173 | $props['country_id'] = $config->provinceLimit; | |
1174 | } | |
1175 | else { | |
1176 | $props['country_id'] = $config->defaultContactCountry; | |
1177 | } | |
1178 | } | |
1179 | if (!empty($props['country_id'])) { | |
1180 | $params['condition'] = 'country_id IN (' . implode(',', (array) $props['country_id']) . ')'; | |
1181 | } | |
1182 | break; | |
1183 | // Filter country list based on site defaults | |
1184 | case 'country_id': | |
786ad6e1 CW |
1185 | if ($context != 'get' && $context != 'validate') { |
1186 | $config = CRM_Core_Config::singleton(); | |
1187 | if (!empty($config->countryLimit) && is_array($config->countryLimit)) { | |
1188 | $params['condition'] = 'id IN (' . implode(',', $config->countryLimit) . ')'; | |
1189 | } | |
dc86f881 CW |
1190 | } |
1191 | break; | |
1192 | // Filter county list based on chosen state | |
1193 | case 'county_id': | |
1194 | if (!empty($props['state_province_id'])) { | |
1195 | $params['condition'] = 'state_province_id IN (' . implode(',', (array) $props['state_province_id']) . ')'; | |
1196 | } | |
1197 | break; | |
1198 | } | |
786ad6e1 | 1199 | return CRM_Core_PseudoConstant::get(__CLASS__, $fieldName, $params, $context); |
dc86f881 | 1200 | } |
6a488035 | 1201 | } |