255)CatalogValidator::invalid('address',__('Enter the venue street, town and country.','abece-booking')); $address=trim(sanitize_text_field($address));if(mb_strlen($address)<3)CatalogValidator::invalid('address',__('Enter the venue street, town and country.','abece-booking')); $endpoint=apply_filters('abece_booking_geocoding_endpoint',defined('ASB_GEOCODING_URL')?ASB_GEOCODING_URL:'https://nominatim.openstreetmap.org/search'); if(!is_string($endpoint)||!wp_http_validate_url($endpoint)||wp_parse_url($endpoint,PHP_URL_SCHEME)!=='https')throw new CatalogException('abece_booking_geocoding_unavailable',__('Address search is unavailable. You can enter coordinates manually.','abece-booking'),503); $locale=str_replace('_','-',determine_locale());$key='abece_booking_geo_'.hash('sha256',$endpoint.'|'.$locale.'|'.$address);$cached=get_transient($key);if(is_array($cached))return ['results'=>$cached]; global $wpdb;$lock=\ABeCe\Booking\Infrastructure\Database\Tables::lock($wpdb,'geocoding'); if((string)$wpdb->get_var($wpdb->prepare('SELECT GET_LOCK(%s,0)',$lock))!=='1')$this->busy(); try{ $cached=get_transient($key);if(is_array($cached))return ['results'=>$cached]; if(microtime(true)-(float)get_transient('abece_booking_geocoding_last_request')<1.0)$this->busy(); if(!set_transient('abece_booking_geocoding_last_request',microtime(true),60))throw new CatalogException('abece_booking_geocoding_unavailable',__('Address search is unavailable. You can enter coordinates manually.','abece-booking'),503); $response=wp_safe_remote_get(add_query_arg(['q'=>$address,'format'=>'jsonv2','limit'=>5],$endpoint),['timeout'=>8,'redirection'=>0,'limit_response_size'=>65536,'user-agent'=>'ABeCe Booking/'.Plugin::VERSION.' (+'.home_url('/').')','headers'=>['Accept'=>'application/json','Accept-Language'=>$locale]]); if(is_wp_error($response)||wp_remote_retrieve_response_code($response)!==200)throw new CatalogException('abece_booking_geocoding_unavailable',__('Address search is unavailable. You can enter coordinates manually.','abece-booking'),503); $data=json_decode(wp_remote_retrieve_body($response),true); if(!is_array($data)||!array_is_list($data))throw new CatalogException('abece_booking_geocoding_unavailable',__('Address search is unavailable. You can enter coordinates manually.','abece-booking'),503); $results=[];foreach(array_slice($data,0,5)as $row){ if(!is_array($row)||!isset($row['lat'],$row['lon'],$row['display_name'])||!is_numeric($row['lat'])||!is_numeric($row['lon'])||!is_string($row['display_name']))continue; $lat=(float)$row['lat'];$lon=(float)$row['lon'];if(!is_finite($lat)||!is_finite($lon)||abs($lat)>90||abs($lon)>180)continue; $label=sanitize_text_field($row['display_name']);if($label==='')continue; $results[]=['latitude'=>$lat,'longitude'=>$lon,'label'=>$label]; } set_transient($key,$results,DAY_IN_SECONDS);return ['results'=>$results]; }finally{$wpdb->get_var($wpdb->prepare('SELECT RELEASE_LOCK(%s)',$lock));} } private function busy():never{throw new CatalogException('abece_booking_geocoding_busy',__('Please wait a moment before searching again.','abece-booking'),429);} }