Prevent PO Box Addresses mydev_prevent_po_box_addresses MY-Dev | Mohamed Youssef]]> https://my-dev.pro 1.0.0 $url, CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 10, CURLOPT_CONNECTTIMEOUT => 5, ]); $response = curl_exec($connection); if ($response === false) { curl_close($connection); return []; } $status = curl_getinfo($connection, CURLINFO_HTTP_CODE); curl_close($connection); if ($status !== 200) { return []; } return json_decode($response, true); } // fetch longitude & latitude based on ZIP Code private function getCustomerLocation(string $zipcode, string $countryCode = 'US'): array { $url = sprintf( 'https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/findAddressCandidates?SingleLine=%s&f=json&outFields=*&countryCode=%s', urlencode((string)$zipcode), urlencode($countryCode) ); $response = $this->getRequest($url); if (empty($response['candidates'])) { return []; } return $response['candidates'][0]['location']; } private function getAvailableBoxes(string $zipcode, string $countryCode = 'US'): array { $location = $this->getCustomerLocation($zipcode, $countryCode); if (empty($location)) { return []; } $longitude = $location['x']; $latitude = $location['y']; $url = sprintf( 'https://poboxes.usps.com/pobol/app/poLocations/search?longitude=%s&latitude=%s', $location['x'], $location['y'] ); return $this->getRequest($url); } private function normalizeAddress(string $address): string { $address = strtoupper(trim($address)); // Remove punctuation $address = preg_replace('/[.,#]/', ' ', $address); // Normalize whitespace $address = preg_replace('/\s+/', ' ', $address); $replacements = [ // Directions 'NORTHWEST' => 'NW', 'NORTHEAST' => 'NE', 'SOUTHWEST' => 'SW', 'SOUTHEAST' => 'SE', 'NORTH' => 'N', 'SOUTH' => 'S', 'EAST' => 'E', 'WEST' => 'W', // Street suffixes 'STREET' => 'ST', 'AVENUE' => 'AVE', 'ROAD' => 'RD', 'DRIVE' => 'DR', 'BOULEVARD' => 'BLVD', 'LANE' => 'LN', 'COURT' => 'CT', 'CIRCLE' => 'CIR', 'PLACE' => 'PL', 'PARKWAY' => 'PKWY', 'TERRACE' => 'TER', 'HIGHWAY' => 'HWY', 'SQUARE' => 'SQ', 'TRAIL' => 'TRL', 'WAY' => 'WAY', 'LOOP' => 'LOOP', 'CENTER' => 'CTR', 'MOUNT' => 'MT', 'JUNCTION' => 'JCT', // Common unit designators 'APARTMENT' => 'APT', 'SUITE' => 'STE', 'BUILDING' => 'BLDG', 'FLOOR' => 'FL', 'ROOM' => 'RM', // PO Box 'POST OFFICE BOX' => 'PO BOX', 'POST OFFICE' => 'PO', ]; foreach ($replacements as $search => $replace) { $address = preg_replace( '/\b' . preg_quote($search, '/') . '\b/', $replace, $address ); } // Normalize whitespace again $address = preg_replace('/\s+/', ' ', trim($address)); return $address; } public function hasPOBoxFacility(string $zipCode, string $address): bool { $status = false; $facilities = $this->getAvailableBoxes((string)$zipCode); if (empty($facilities)) { return $status; } $searchAddress = $this->normalizeAddress($address); $address_zipcode = explode('-', $zipCode); // Use only the first part of the ZIP code $zipcode = $address_zipcode[0]; $zip4code = $address_zipcode[1] ?? null; foreach ($facilities as $facility) { if (($facility['address']['zipCode'] ?? '') !== $zipcode ) { continue; } $facilityAddress = $this->normalizeAddress($facility['address']['addressLine1']); if (strpos($searchAddress, $facilityAddress) !== false || strpos($facilityAddress, $searchAddress) !== false) { $status = true; } if (($facility['address']['zip4Code'] ?? '') !== $zip4code) { $status = false; } if ($status) { break; } } return $status; } ]]> request->post['country_id'] == '') {]]> model_account_address->hasPOBoxFacility($this->request->post['postcode'], $this->request->post['address_1'])) { $json['error']['address_1'] = $this->language->get('error_po_box'); } ]]> model_localisation_country->getCountry($this->request->post['country_id']);]]> model_account_address->hasPOBoxFacility($this->request->post['postcode'], $this->request->post['address_1'])) { $json['error']['address_1'] = $this->language->get('error_po_box'); } ]]> request->post['country_id'] == '') {]]> load->model('account/address'); if ($this->model_account_address->hasPOBoxFacility($this->request->post['postcode'], $this->request->post['address_1'])) { $json['error']['address_1'] = $this->language->get('error_po_box'); } ]]>