From f909470b5d5a34876303aebdb15387ef071102c6 Mon Sep 17 00:00:00 2001 From: Jon Ziebell Date: Sat, 20 Jun 2020 14:49:07 -0400 Subject: [PATCH] Fixed #282 - Pre-screen for bad addresses --- api/address.php | 50 ++++++++++++++++++++++++++++++--------- api/ecobee_thermostat.php | 12 +++++----- 2 files changed, 45 insertions(+), 17 deletions(-) diff --git a/api/address.php b/api/address.php index 5bca5da..b1188dc 100644 --- a/api/address.php +++ b/api/address.php @@ -19,7 +19,7 @@ class address extends cora\crud { /** * Search for an address based on an address string. This will make an API - * call to Smarty Streets using that address string (after first checking + * call to SmartyStreets using that address string (after first checking * the cache to see if we've done it before), then it will either create the * address row for this user or return the existing one if it already * exists. @@ -30,20 +30,48 @@ class address extends cora\crud { * 2. 123 Sesame Street (query smarty, return existing row) * 3. 123 Sesame Street (query smarty (cached), return existing row) * - * @param string $address_string Freeform address string + * @param string $address Address components (line_1, locality, + * administrative_area, postal_code) * @param string $country ISO 3 country code * * @return array The address row. */ - public function search($address_string, $country) { - $normalized = $this->api( - 'smarty_streets', - 'smarty_streets_api', - [ - 'street' => $address_string, - 'country' => $country - ] - ); + public function search($address, $country) { + /** + * If any of these fields are missing, set normalized to an empty array + * and skip the SmartyStreets lookup. Also, line_1 must have a number and + * text. + */ + foreach(['line_1', 'locality', 'administrative_area', 'postal_code'] as $key) { + if( + isset($address[$key]) === false || + trim($address[$key]) === '' || + $address[$key] === null + ) { + $normalized = []; + break; + } + } + + if( + isset($address['line_1']) === true && + preg_match('/\d+ [0-9]*[a-z]+/i', trim(preg_replace('/[^a-z0-9 ]/i', ' ', $address['line_1']))) !== 1 + ) { + $normalized = []; + } + + // If normalized wasn't overrridden, check with SmartyStreets. + if(isset($normalized) === false) { + $address_string = $address['line_1'] . ', ' . $address['locality'] . ', ' . $address['administrative_area'] . ', ' . $address['postal_code']; + $normalized = $this->api( + 'smarty_streets', + 'smarty_streets_api', + [ + 'street' => $address_string, + 'country' => $country + ] + ); + } $key = $this->generate_key($normalized); $existing_address = $this->get([ diff --git a/api/ecobee_thermostat.php b/api/ecobee_thermostat.php index 834526e..38e5bae 100644 --- a/api/ecobee_thermostat.php +++ b/api/ecobee_thermostat.php @@ -299,19 +299,19 @@ class ecobee_thermostat extends cora\crud { * @return array */ private function get_address($thermostat, $ecobee_thermostat) { - $address_parts = []; + $address = []; if(isset($ecobee_thermostat['location']['streetAddress']) === true) { - $address_parts[] = $ecobee_thermostat['location']['streetAddress']; + $address['line_1'] = $ecobee_thermostat['location']['streetAddress']; } if(isset($ecobee_thermostat['location']['city']) === true) { - $address_parts[] = $ecobee_thermostat['location']['city']; + $address['locality'] = $ecobee_thermostat['location']['city']; } if(isset($ecobee_thermostat['location']['provinceState']) === true) { - $address_parts[] = $ecobee_thermostat['location']['provinceState']; + $address['administrative_area'] = $ecobee_thermostat['location']['provinceState']; } if(isset($ecobee_thermostat['location']['postalCode']) === true) { - $address_parts[] = $ecobee_thermostat['location']['postalCode']; + $address['postal_code'] = $ecobee_thermostat['location']['postalCode']; } if( @@ -334,7 +334,7 @@ class ecobee_thermostat extends cora\crud { 'address', 'search', [ - 'address_string' => implode(', ', $address_parts), + 'address' => $address, 'country' => $country ] );