| 1 | <?php |
| 2 | /* |
| 3 | +--------------------------------------------------------------------+ |
| 4 | | Copyright CiviCRM LLC. All rights reserved. | |
| 5 | | | |
| 6 | | This work is published under the GNU AGPLv3 license with some | |
| 7 | | permitted exceptions and without any warranty. For full license | |
| 8 | | and copyright information, see https://civicrm.org/licensing | |
| 9 | +--------------------------------------------------------------------+ |
| 10 | */ |
| 11 | |
| 12 | /** |
| 13 | * @package CRM |
| 14 | * @copyright CiviCRM LLC https://civicrm.org/licensing |
| 15 | */ |
| 16 | |
| 17 | /** |
| 18 | * Address utilities. |
| 19 | */ |
| 20 | class CRM_Utils_Address_USPS { |
| 21 | |
| 22 | /** |
| 23 | * Whether USPS validation should be disabled during import. |
| 24 | * |
| 25 | * @var bool |
| 26 | */ |
| 27 | protected static $_disabled = FALSE; |
| 28 | |
| 29 | /** |
| 30 | * Disable the USPS validation. |
| 31 | * |
| 32 | * @param bool $disable |
| 33 | */ |
| 34 | public static function disable($disable = TRUE) { |
| 35 | self::$_disabled = $disable; |
| 36 | } |
| 37 | |
| 38 | /** |
| 39 | * Check address against USPS. |
| 40 | * |
| 41 | * @param array $values |
| 42 | * |
| 43 | * @return bool |
| 44 | */ |
| 45 | public static function checkAddress(&$values) { |
| 46 | if (self::$_disabled) { |
| 47 | return FALSE; |
| 48 | } |
| 49 | if (!isset($values['street_address']) || |
| 50 | (!isset($values['city']) && |
| 51 | !isset($values['state_province']) && |
| 52 | !isset($values['postal_code']) |
| 53 | ) |
| 54 | ) { |
| 55 | return FALSE; |
| 56 | } |
| 57 | |
| 58 | $userID = Civi::settings()->get('address_standardization_userid'); |
| 59 | $url = Civi::settings()->get('address_standardization_url'); |
| 60 | |
| 61 | if (empty($userID) || |
| 62 | empty($url) |
| 63 | ) { |
| 64 | return FALSE; |
| 65 | } |
| 66 | |
| 67 | $address2 = str_replace(',', '', $values['street_address']); |
| 68 | |
| 69 | $XMLQuery = '<AddressValidateRequest USERID="' . $userID . '"><Address ID="0"><Address1>' . CRM_Utils_Array::value('supplemental_address_1', $values, '') . '</Address1><Address2>' . $address2 . '</Address2><City>' . $values['city'] . '</City><State>' . $values['state_province'] . '</State><Zip5>' . $values['postal_code'] . '</Zip5><Zip4>' . CRM_Utils_Array::value('postal_code_suffix', $values, '') . '</Zip4></Address></AddressValidateRequest>'; |
| 70 | |
| 71 | $client = new GuzzleHttp\Client(); |
| 72 | $request = $client->request('GET', $url, [ |
| 73 | 'query' => [ |
| 74 | 'API' => 'Verify', |
| 75 | 'XML' => $XMLQuery, |
| 76 | ], |
| 77 | ]); |
| 78 | |
| 79 | $session = CRM_Core_Session::singleton(); |
| 80 | |
| 81 | $code = $request->getStatusCode(); |
| 82 | if ($code != 200) { |
| 83 | $session->setStatus(ts('USPS Address Lookup Failed with HTTP status code: %1', |
| 84 | [1 => $code] |
| 85 | )); |
| 86 | return FALSE; |
| 87 | } |
| 88 | |
| 89 | $responseBody = $request->getBody(); |
| 90 | |
| 91 | $xml = simplexml_load_string($responseBody); |
| 92 | |
| 93 | if (is_null($xml) || is_null($xml->Address)) { |
| 94 | $session->setStatus(ts('Your USPS API Lookup has Failed.')); |
| 95 | return FALSE; |
| 96 | } |
| 97 | |
| 98 | if ($xml->Number == '80040b1a') { |
| 99 | $session->setStatus(ts('Your USPS API Authorization has Failed.')); |
| 100 | return FALSE; |
| 101 | } |
| 102 | |
| 103 | if (array_key_exists('Error', $xml->Address)) { |
| 104 | $session->setStatus(ts('Address not found in USPS database.')); |
| 105 | return FALSE; |
| 106 | } |
| 107 | |
| 108 | $values['street_address'] = (string) $xml->Address->Address2; |
| 109 | $values['city'] = (string) $xml->Address->City; |
| 110 | $values['state_province'] = (string) $xml->Address->State; |
| 111 | $values['postal_code'] = (string) $xml->Address->Zip5; |
| 112 | $values['postal_code_suffix'] = (string) $xml->Address->Zip4; |
| 113 | |
| 114 | if (array_key_exists('Address1', $xml->Address)) { |
| 115 | $values['supplemental_address_1'] = (string) $xml->Address->Address1; |
| 116 | } |
| 117 | |
| 118 | return TRUE; |
| 119 | } |
| 120 | |
| 121 | } |