wolkal3000_options ein Array geocache anlegen. Darunter für jeden hash ein Array schreiben, also: Datenmodell: $geocache = array ( hash1 = array ( 'wolkal3000_geo_lat' => '', 'wolkal3000_geo_lon' => '', 'wolkal3000_geo_timestamp' => 0, ), hash2 = array ... ); Schreiben: $options = get_options ( 'wolkal3000_options' ); $geocache = $options ( 'geocache' ); $geocache['hashx'] = array ( $lat, $lon, time(), ); $options ( 'geocache' ) = $geocache; Löschen: foreach ( $geocache as $key => $value ) { if ( $key['wolkal3000_geo_timestamp'] < time() - 2592000 ) { unset ( $options['geocache']['hashx'] ) } } set_options ( 'wolkal3000_options' ); Suchen: if ( isset ( $options['geocache']['hashx'] ) ) ... */ if ( '' == $location ) { return array ('', ''); } // check the cache first global $wpdb; $table = $wpdb->prefix.WOLKAL3000_GEO_TABLE; $hash = hash ('md5', $location); $query = "SELECT wolkal3000_geo_lat, wolkal3000_geo_lon FROM $table WHERE wolkal3000_geo_hash = '$hash'"; $result = $wpdb->get_row( $query, ARRAY_N ); if ( $wpdb->num_rows == 1 ) { // it should only be a single row! wolkal3000_error_log (INFO, "geocode cache hit hash $hash lat $result[0] lon $result[1]"); } else { // do the housekeeping first, before we create a new caching entry. // remove all cache entries which are older than 30 days. $outdated = time() - 2592000; // 30 Tage $query = "DELETE FROM $table WHERE wolkal3000_geo_timestamp < $outdated"; $wpdb->query($query); $options = get_option('wolkal3000_options'); $result = array ('', ''); switch ( $options['wolkal3000_geocoding'] ) { case "osm" : $result = wolkal3000_geocode_osm($location); break; } $file = dirname (__FILE__) . "/geocode-result-$hash.txt"; file_put_contents ($file, var_export ($result, TRUE)); // do the caching now, but only if both values are set. // $wpdb_insert does all the sanitizing for us. $lat = $result[0]; $lon = $result[1]; if ('' != $lat && '' != $lon) { $wpdb->insert($table, array( 'wolkal3000_geo_location' => substr( $location, 0, 128 ), 'wolkal3000_geo_hash' => $hash, 'wolkal3000_geo_lat' => $lat, 'wolkal3000_geo_lon' => $lon, 'wolkal3000_geo_timestamp' => time(), )); wolkal3000_error_log (INFO, "geocoded and cached lat=$lat lon=$lon for location $location"); } // error handling? } return ($result); } function wolkal3000_geocode_osm($location) { // https://wiki.openstreetmap.org/wiki/Nominatim // https://nominatim.openstreetmap.org/search?q=Hotel+Gumberger+Gasthof+GmbH&format=json' $location = urlencode($location); wolkal3000_error_log (INFO, "wolkal3000_geocode_osm: location $location"); // the main problem with Nominatim is that it doesn't understand calendar location information very well. // we ought to cut off the location name and the country, i.e. zip code, city & street address only $url = 'https://nominatim.openstreetmap.org/search?q="' . $location . '"&format=json'; $response = wp_remote_get($url); $json = wp_remote_retrieve_body($response); $http_code = wp_remote_retrieve_response_code($response); // we need to catch errors // https://www.php.net/manual/en/function.json-decode.php $decoded = json_decode($json, true); // TODO error handling e.g. if we get no usable values. /* $file = dirname (__FILE__) . '/json-decoded.txt'; // should simply be ->lat and -> lon file_put_contents ($file, var_export ($decoded, TRUE)); // The first array level ([0]) is only needed because OSM returns a JSON with enclosing []. */ $lat = $decoded['0']['lat']; $lon = $decoded['0']['lon']; wolkal3000_error_log (INFO, "wolkal3000_geocode_osm found lat=$lat lon=$lon loc $location"); return array ($lat, $lon); }