$data = $data['response']['GeoObjectCollection']['featureMember'][0]; if ($data['GeoObject']['metaDataProperty']['GeocoderMetaData']['precision'] == 'other') { $try_new = TRUE; } } else { $try_new = TRUE; } if ($try_new && strpos($address, ',')) { // It might be that the first element of the address is a business name. // Lets drop the first element and see if we get anything better! list(, $address_new) = explode(',', $address, 2); //$request_new = $url.urlencode($address); $param = $api_params['request_params']['address']; $params[$param] = urlencode($address_new); $request_new = build_request_url($url, $params, $api_params['method']); $mapresponse = get_http_request($request_new, NULL, $ratelimit); $data_new = json_decode($mapresponse, TRUE); if ($data_new['response']['GeoObjectCollection']['metaDataProperty']['GeocoderResponseMetaData']['found'] > 0 && $data_new['response']['GeoObjectCollection']['featureMember'][0]['GeoObject']['metaDataProperty']['GeocoderMetaData']['precision'] != 'other') { $request = $request_new; $data = $data_new['response']['GeoObjectCollection']['featureMember'][0]; } } if (!$reverse) { // If using reverse queries, do not change lat/lon list($location['location_lon'], $location['location_lat']) = explode(' ', $data['GeoObject']['Point']['pos']); } $data = $data['GeoObject']['metaDataProperty']['GeocoderMetaData']['AddressDetails']; $location['location_country'] = strtolower($data['Country']['CountryNameCode']); $location['location_state'] = $data['Country']['AdministrativeArea']['AdministrativeAreaName']; if (isset($data['Country']['AdministrativeArea']['SubAdministrativeArea'])) { $location['location_county'] = $data['Country']['AdministrativeArea']['SubAdministrativeArea']['SubAdministrativeAreaName'];
function get_geolocation($address, $hostname) { global $config; switch (strtolower($config['geocoding']['api'])) { case 'osm': case 'openstreetmap': $location['location_geoapi'] = 'openstreetmap'; // Openstreetmap. The usage limits are stricter here. (http://wiki.openstreetmap.org/wiki/Nominatim_usage_policy) $url = "http://nominatim.openstreetmap.org/search?format=json&addressdetails=1&limit=1&q="; $reverse_url = "http://nominatim.openstreetmap.org/reverse?format=json&"; break; case 'google': $location['location_geoapi'] = 'google'; // See documentation here: https:// developers.google.com/maps/documentation/geocoding/ // Use of the Google Geocoding API is subject to a query limit of 2,500 geolocation requests per day. $url = "http://maps.googleapis.com/maps/api/geocode/json?sensor=false&address="; $reverse_url = "http://maps.googleapis.com/maps/api/geocode/json?sensor=false&"; break; case 'mapquest': default: $location['location_geoapi'] = 'mapquest'; // Mapquest open data. There are no usage limits. $url = "http://open.mapquestapi.com/nominatim/v1/search.php?format=json&addressdetails=1&limit=1&q="; $reverse_url = "http://open.mapquestapi.com/nominatim/v1/reverse.php?format=json&"; } if ($address != "Unknown" && $config['geocoding']['enable']) { $reverse = FALSE; // Forward geocoding by default // If location string contains coordinates ([33.234, -56.22]) use Reverse Geocoding. $pattern = '/\\[\\s*([+-]*\\d+[\\d\\.]*)[,\\s]+([+-]*\\d+[\\d\\.]*)[\\s\\]]+/'; if (preg_match($pattern, $address, $matches)) { $location['location_lat'] = $matches[1]; $location['location_lon'] = $matches[2]; $reverse = TRUE; } // If DNS LOC support is enabled and DNS LOC record is set, use Reverse Geocoding. if ($config['geocoding']['dns']) { // Ack! dns_get_record not only cannot retrieve LOC records, but it also actively filters them when using // DNS_ANY as query type (which, admittedly would not be all that reliable as per the manual). // Example LOC: // "20 31 55.893 N 4 57 38.269 E 45.00m 10m 100m 10m" // // From Wikipedia: d1 [m1 [s1]] {"N"|"S"} d2 [m2 [s2]] {"E"|"W"} // // Parsing this is something for Net_DNS2 as it has the code for it. include_once 'Net/DNS2.php'; include_once 'Net/DNS2/RR/LOC.php'; $resolver = new Net_DNS2_Resolver(); $response = $resolver->query($hostname, 'LOC', 'IN'); if ($response) { foreach ($response->answer as $answer) { if (is_numeric($answer->degree_latitude)) { $ns_multiplier = $answer->ns_hem == 'N' ? 1 : -1; $ew_multiplier = $answer->ew_hem == 'E' ? 1 : -1; $location['location_lat'] = round($answer->degree_latitude + $answer->min_latitude / 60 + $answer->sec_latitude / 3600, 7) * $ns_multiplier; $location['location_lon'] = round($answer->degree_longitude + $answer->min_longitude / 60 + $answer->sec_longitude / 3600, 7) * $ew_multiplier; $reverse = TRUE; } } } } if ($reverse) { if ($config['geocoding']['api'] == 'google') { // latlng=40.714224,-73.961452 $request = $reverse_url . 'latlng=' . $location['location_lat'] . ',' . $location['location_lon']; } else { // lat=51.521435&lon=-0.162714 $request = $reverse_url . 'lat=' . $location['location_lat'] . '&lon=' . $location['location_lon']; } } else { $request = $url . urlencode($address); } $mapresponse = get_http_request($request); $data = json_decode($mapresponse, true); if ($config['geocoding']['api'] == 'google') { if ($data['status'] == 'OVER_QUERY_LIMIT') { // Return empty array for overquery limit (for later recheck) return array(); } // Use google data only with good status response if ($data['status'] == 'OK') { $data = $data['results'][0]; if ($data['geometry']['location_type'] == 'APPROXIMATE') { // It might be that the first element of the address is a business name. // Lets drop the first element and see if we get anything better! list(, $address) = explode(',', $address, 2); $mapresponse = get_http_request($url . urlencode($address)); $data_new = json_decode($mapresponse, true); if ($data_new['status'] == 'OK' && $data_new['results'][0]['geometry']['location_type'] != 'APPROXIMATE') { $data = $data_new['results'][0]; } } } } elseif (!isset($location['location_lat'])) { $data = $data[0]; if (!count($data)) { // We seem to have hit a snag geocoding. It might be that the first element of the address is a business name. // Lets drop the first element and see if we get anything better! This works more often than one might expect. list(, $address) = explode(',', $address, 2); $mapresponse = get_http_request($url . urlencode($address)); $data = json_decode($mapresponse, true); // We only want the first entry in the returned data. $data = $data[0]; } } } print_debug("GEO-API REQUEST: {$request}"); // Put the values from the data array into the return array where they exist, else replace them with defaults or Unknown. if ($config['geocoding']['api'] == 'google') { $location['location_lat'] = $data['geometry']['location']['lat']; $location['location_lon'] = $data['geometry']['location']['lng']; foreach ($data['address_components'] as $entry) { switch ($entry['types'][0]) { case 'locality': $location['location_city'] = $entry['long_name']; break; case 'administrative_area_level_2': $location['location_county'] = $entry['long_name']; break; case 'administrative_area_level_1': $location['location_state'] = $entry['long_name']; break; case 'country': $location['location_country'] = strtolower($entry['short_name']); break; } } } else { $location['location_lat'] = $data['lat']; $location['location_lon'] = $data['lon']; $location['location_city'] = strlen($data['address']['town']) ? $data['address']['town'] : $data['address']['city']; // Would be nice to have an array of countries where we want state, and ones where we want County. For example, USA wants state, UK wants county. $location['location_county'] = $data['address']['county']; $location['location_state'] = $data['address']['state']; $location['location_country'] = $data['address']['country_code']; } // Use defaults if empty values if (!strlen($location['location_lat'])) { $location['location_lat'] = $config['geocoding']['default']['lat']; } if (!strlen($location['location_lon'])) { $location['location_lon'] = $config['geocoding']['default']['lon']; } if (!strlen($location['location_city'])) { $location['location_city'] = 'Unknown'; } if (!strlen($location['location_county'])) { $location['location_county'] = 'Unknown'; } if (!strlen($location['location_state'])) { $location['location_state'] = 'Unknown'; } if (!strlen($location['location_country'])) { $location['location_country'] = 'Unknown'; } return $location; }
* */ // FIXME: This is fairly messy and crude. Feel free to improve it! $color = $message_tags['ALERT_STATE'] == "RECOVER" ? "good" : "danger"; // JSON data $data = array("username" => $endpoint['username'], "channel" => $endpoint['channel']); $data['attachments'][] = array('fallback' => $message_tags['TITLE'], 'title' => $message_tags['TITLE'], 'title_link' => $message_tags['ALERT_URL'], 'fields' => array(array('title' => 'Device/Location', 'value' => $message_tags['DEVICE_HOSTNAME'] . " (" . $message_tags['DEVICE_OS'] . ")" . PHP_EOL . $message_tags['DEVICE_LOCATION'], 'short' => TRUE), array('title' => 'Entity', 'value' => $message_tags['ENTITY_TYPE'] . " / " . $message_tags['ENTITY_NAME'] . (isset($message_tags['ENTITY_DESCRIPTION']) ? ' ' . $message_tags['ENTITY_DESCRIPTION'] : ''), 'short' => TRUE), array('title' => 'Alert Message/Duration', 'value' => $message_tags['ALERT_MESSAGE'] . PHP_EOL . $message_tags['DURATION'], 'short' => TRUE), array('title' => 'Metrics', 'value' => str_replace(" ", "", $message_tags['METRICS']), 'short' => TRUE)), 'color' => $color); /* foreach ($graphs as $graph) { $data['attachments'][] = array('fallback' => "Graph Image", 'title' => $graph['label'], 'image_url' => $graph['url'], 'color' => 'danger'); } */ $data_string = json_encode($data); // JSON + HTTP headers $context_data = array('method' => 'POST', 'header' => "Connection: close\r\n" . "Content-Length: " . strlen($data_string) . "\r\n", 'content' => $data_string); // Send out API call $result = get_http_request($endpoint['url'], $context_data); // Check if call succeeded if ($result == "ok") { $notify_status['success'] = TRUE; } else { $notify_status['success'] = FALSE; } unset($data, $result, $context_data); // EOF
function get_geolocation($address, $geo_db = array(), $dns_only = FALSE) { global $config; $ok = FALSE; $location = array('location' => $address); // Init location array $location['location_geoapi'] = strtolower(trim($config['geocoding']['api'])); if (!isset($config['geo_api'][$location['location_geoapi']])) { // Use default if unknown api $location['location_geoapi'] = 'openstreetmap'; } $api_params =& $config['geo_api'][$location['location_geoapi']]; // Link to api specific params $params = $api_params['params']; // Init base request params // GEO API KEY and rate limits $ratelimit = FALSE; if (strlen($config['geocoding']['api_key']) && isset($api_params['request_params']['key'])) { $param = $api_params['request_params']['key']; $params[$param] = escape_html($config['geocoding']['api_key']); // KEYs is never used special characters if (isset($api_params['ratelimit_key'])) { $ratelimit = $api_params['ratelimit_key']; } } else { if (isset($api_params['ratelimit'])) { $ratelimit = $api_params['ratelimit']; } } if (isset($api_params['request_params']['id'])) { $params[$api_params['request_params']['id']] = OBSERVIUM_PRODUCT . '-' . substr(get_unique_id(), 0, 8); } if (isset($api_params['request_params']['uuid'])) { $params[$api_params['request_params']['uuid']] = get_unique_id(); } if (isset($config['geocoding']['enable']) && $config['geocoding']['enable']) { $reverse = FALSE; // by default forward geocoding $debug_msg = "Geocoding ENABLED, try detect device coordinates:" . PHP_EOL; // If device coordinates set manually, use Reverse Geocoding. if ($geo_db['location_manual']) { $location['location_lat'] = $geo_db['location_lat']; $location['location_lon'] = $geo_db['location_lon']; $reverse = TRUE; $debug_msg .= ' MANUAL coordinates - SET' . PHP_EOL; } else { if ($config['geocoding']['dns']) { /** * Ack! dns_get_record not only cannot retrieve LOC records, but it also actively filters them when using * DNS_ANY as query type (which, admittedly would not be all that reliable as per the manual). * * Example LOC: * "20 31 55.893 N 4 57 38.269 E 45.00m 10m 100m 10m" * * From Wikipedia: d1 [m1 [s1]] {"N"|"S"} d2 [m2 [s2]] {"E"|"W"} * * Parsing this is something for Net_DNS2 as it has the code for it. */ if ($geo_db['hostname']) { //include_once('Net/DNS2.php'); //include_once('Net/DNS2/RR/LOC.php'); $resolver = new Net_DNS2_Resolver(); try { $response = $resolver->query($geo_db['hostname'], 'LOC', 'IN'); } catch (Net_DNS2_Exception $e) { print_debug(' ' . $e->getMessage() . ' (' . $geo_db['hostname'] . ')'); } } else { $response = FALSE; print_debug(" DNS LOC enabled, but device hostname empty."); } if ($response) { if (OBS_DEBUG > 1) { var_dump($response->answer); } foreach ($response->answer as $answer) { if (is_numeric($answer->latitude) && is_numeric($answer->longitude)) { $location['location_lat'] = $answer->latitude; $location['location_lon'] = $answer->longitude; $reverse = TRUE; break; } else { if (is_numeric($answer->degree_latitude) && is_numeric($answer->degree_longitude)) { $ns_multiplier = $answer->ns_hem == 'N' ? 1 : -1; $ew_multiplier = $answer->ew_hem == 'E' ? 1 : -1; $location['location_lat'] = round($answer->degree_latitude + $answer->min_latitude / 60 + $answer->sec_latitude / 3600, 7) * $ns_multiplier; $location['location_lon'] = round($answer->degree_longitude + $answer->min_longitude / 60 + $answer->sec_longitude / 3600, 7) * $ew_multiplier; $reverse = TRUE; break; } } } if (isset($location['location_lat'])) { $debug_msg .= ' DNS LOC records - FOUND' . PHP_EOL; } else { $debug_msg .= ' DNS LOC records - NOT FOUND' . PHP_EOL; if ($dns_only) { // If we check only DNS LOC records but it not found, exit print_debug($debug_msg); return FALSE; } } } } } if ($reverse || !preg_match('/^<?(unknown|none)>?$/i', $address)) { /** * If location string contains coordinates use Reverse Geocoding. * Valid strings: * Some location [33.234, -56.22] * Some location (33.234 -56.22) * Some location [33.234;-56.22] * 33.234,-56.22 */ $pattern = '/(?:^|[\\[(])\\s*(?<lat>[+-]?\\d+(?:\\.\\d+)*)\\s*[,; ]\\s*(?<lon>[+-]?\\d+(?:\\.\\d+)*)\\s*(?:[\\])]|$)/'; if (!$reverse && preg_match($pattern, $address, $matches)) { if ($matches['lat'] >= -90 && $matches['lat'] <= 90 && $matches['lon'] >= -180 && $matches['lon'] <= 180) { $location['location_lat'] = $matches['lat']; $location['location_lon'] = $matches['lon']; $reverse = TRUE; } } if ($reverse) { $debug_msg .= ' by REVERSE query (API: ' . strtoupper($config['geocoding']['api']) . ', LAT: ' . $location['location_lat'] . ', LON: ' . $location['location_lon'] . ') - '; $url = $api_params['reverse_url']; if (isset($api_params['reverse_params'])) { // Additional params for reverse query $params = array_merge($params, $api_params['reverse_params']); } if (!is_numeric($location['location_lat']) || !is_numeric($location['location_lat'])) { // Do nothing for empty, skip requests for empty coordinates } else { if (isset($api_params['request_params']['lat']) && isset($api_params['request_params']['lon'])) { $ok = TRUE; $param = $api_params['request_params']['lat']; $params[$param] = $location['location_lat']; $param = $api_params['request_params']['lon']; $params[$param] = $location['location_lon']; } else { if (isset($api_params['request_params']['latlon'])) { $ok = TRUE; $param = $api_params['request_params']['latlon']; $params[$param] = $location['location_lat'] . ',' . $location['location_lon']; } } } } else { $debug_msg .= ' by PARSING sysLocation (API: ' . strtoupper($config['geocoding']['api']) . ') - '; $url = $api_params['direct_url']; if (isset($api_params['direct_params'])) { // Additional params for reverse query $params = array_merge($params, $api_params['direct_params']); } if ($address != '') { $ok = TRUE; $param = $api_params['request_params']['address']; $params[$param] = urlencode($address); //$request = $url . urlencode($address); } } if (OBS_DEBUG > 1) { print_vars($api_params); print_vars($params); } if ($ok) { // Build request query $request = build_request_url($url, $params, $api_params['method']); // First request $mapresponse = get_http_request($request, NULL, $ratelimit); switch ($GLOBALS['response_headers']['code'][0]) { case '4': // 4xx (timeout, rate limit, forbidden) // 4xx (timeout, rate limit, forbidden) case '5': // 5xx (server error) $geo_status = strtoupper($GLOBALS['response_headers']['status']); $debug_msg .= $geo_status . PHP_EOL; if (OBS_DEBUG < 2) { // Hide API KEY from output $request = str_replace($api_params['request_params']['key'] . '=' . escape_html($config['geocoding']['api_key']), $api_params['request_params']['key'] . '=' . '***', $request); } $debug_msg .= ' GEO API REQUEST: ' . $request; print_debug($debug_msg); // Return old array with new status (for later recheck) unset($geo_db['hostname'], $geo_db['location_updated']); $location['location_status'] = $debug_msg; $location['location_updated'] = format_unixtime($config['time']['now'], 'Y-m-d G:i:s'); //print_vars($location); //print_vars($geo_db); return array_merge($geo_db, $location); } $data = json_decode($mapresponse, TRUE); //print_vars($data); $geo_status = 'NOT FOUND'; $api_specific = is_file($config['install_dir'] . '/includes/geolocation/' . $location['location_geoapi'] . '.inc.php'); if ($api_specific) { // API specific parser require_once $config['install_dir'] . '/includes/geolocation/' . $location['location_geoapi'] . '.inc.php'; if ($data === FALSE) { // Return old array with new status (for later recheck) unset($geo_db['hostname'], $geo_db['location_updated']); //$location['location_status'] = $debug_msg; $location['location_updated'] = format_unixtime($config['time']['now'], 'Y-m-d G:i:s'); //print_vars($location); //print_vars($geo_db); return array_merge($geo_db, $location); } } else { if (!isset($location['location_lat'])) { $data = $data[0]; if (!count($data) && strpos($address, ',')) { // We seem to have hit a snag geocoding. It might be that the first element of the address is a business name. // Lets drop the first element and see if we get anything better! This works more often than one might expect. list(, $address_new) = explode(',', $address, 2); //$request_new = $url.urlencode($address); $param = $api_params['request_params']['address']; $params[$param] = urlencode($address_new); $request_new = build_request_url($url, $params, $api_params['method']); $mapresponse = get_http_request($request_new, NULL, $ratelimit); $data_new = json_decode($mapresponse, TRUE); if (count($data_new[0])) { // We only want the first entry in the returned data. $data = $data_new[0]; $request = $request_new; } } } } if (OBS_DEBUG > 1 && count($data)) { var_dump($data); } } else { $geo_status = 'NOT REQUESTED'; } } } if (!$api_specific) { // Nominatum if (!$reverse) { // If using reverse queries, do not change lat/lon $location['location_lat'] = $data['lat']; $location['location_lon'] = $data['lon']; } foreach (array('town', 'city', 'hamlet', 'village') as $param) { if (isset($data['address'][$param])) { $location['location_city'] = $data['address'][$param]; break; } } $location['location_state'] = $data['address']['state']; $location['location_county'] = isset($data['address']['county']) ? $data['address']['county'] : $data['address']['state_district']; $location['location_country'] = $data['address']['country_code']; } // Use defaults if empty values if (!strlen($location['location_lat']) || !strlen($location['location_lon'])) { // Reset to empty coordinates $location['location_lat'] = array('NULL'); $location['location_lon'] = array('NULL'); //$location['location_lat'] = $config['geocoding']['default']['lat']; //$location['location_lon'] = $config['geocoding']['default']['lon']; //if (is_numeric($config['geocoding']['default']['lat']) && is_numeric($config['geocoding']['default']['lon'])) //{ // $location['location_manual'] = 1; // Set manual key for ability reset from WUI //} } else { // Always round lat/lon same as DB precision (DECIMAL(10,7)) $location['location_lat'] = round($location['location_lat'], 7); $location['location_lon'] = round($location['location_lon'], 7); } foreach (array('city', 'county', 'state') as $entry) { // Remove duplicate County/State words $param = 'location_' . $entry; $location[$param] = strlen($location[$param]) ? str_ireplace(' ' . $entry, '', $location[$param]) : 'Unknown'; } if (strlen($location['location_country'])) { $location['location_country'] = strtolower($location['location_country']); $geo_status = 'FOUND'; } else { $location['location_country'] = 'Unknown'; } // Print some debug informations $debug_msg .= $geo_status . PHP_EOL; if (OBS_DEBUG < 2) { // Hide API KEY from output $request = str_replace($api_params['request_params']['key'] . '=' . escape_html($config['geocoding']['api_key']), $api_params['request_params']['key'] . '=' . '***', $request); } $debug_msg .= ' GEO API REQUEST: ' . $request; if ($geo_status == 'FOUND') { $debug_msg .= PHP_EOL . ' GEO LOCATION: '; $debug_msg .= country_from_code($location['location_country']) . ' (Country), ' . $location['location_state'] . ' (State), '; $debug_msg .= $location['location_county'] . ' (County), ' . $location['location_city'] . ' (City)'; $debug_msg .= PHP_EOL . ' GEO COORDINATES: '; $debug_msg .= $location['location_lat'] . ' (Latitude), ' . $location['location_lon'] . ' (Longitude)'; } else { $debug_msg .= PHP_EOL . ' QUERY DATE: ' . date('r'); // This is requered for increase data in DB } print_debug($debug_msg); $location['location_status'] = $debug_msg; return $location; }
} else { if ($matches[1] == 'Comment') { continue; // skip comments } } } $response .= $line . PHP_EOL; } } } else { // Use RIPE whois API query $whois_url = 'https://stat.ripe.net/data/whois/data.json?'; $whois_url .= 'sourceapp=' . urlencode(OBSERVIUM_PRODUCT . '-' . get_unique_id()); $whois_url .= '&resource=' . urlencode($ip); $request = get_http_request($whois_url); if ($request) { $request = json_decode($request, TRUE); // Convert to array if ($request['status'] == 'ok' && count($request['data']['records'])) { $whois_parts = array(); foreach ($request['data']['records'] as $i => $parts) { $key = $parts[0]['key']; if (in_array($key, array('NetRange', 'inetnum', 'inet6num'))) { $org = 0; $whois_parts[0] = ''; foreach ($parts as $part) { if (in_array($part['key'], array('Ref', 'source', 'nic-hdl-br'))) { break; } else { if (in_array($part['key'], array('Organization', 'org', 'mnt-irt'))) {
$endpoint['url'] = 'https://redoxygen.net/sms.dll?Action=SendSMS'; } // Default from value if not set if ($endpoint['from'] == "") { $endpoint['from'] = 'Observium'; } // Pre-pend from value to message $message = $endpoint['from'] . " " . $message; $url = $endpoint['url']; // Remove common delimiters used in phone numbers, e.g. dot, dash, space, from recipient number $recipient = str_replace('.', '', $endpoint['recipient']); $recipient = str_replace('-', '', $recipient); $recipient = str_replace(' ', '', $recipient); // URL encode POST values $recipient = urlencode($recipient); $email = urlencode($endpoint['email']); $password = urlencode($endpoint['password']); $message = urlencode($message); $acctid = urlencode($endpoint['acctid']); // POST Data - ENSURE AccountId is the first parameter, their API seems to fail if not. $postdata = "AccountId=" . $acctid . "&Email=" . $email . "&Password="******"&Recipient=" . $recipient . "&Message=" . $message; $context_data = array('method' => 'POST', 'content' => $postdata); // Send out API call and parse response into an associative array $response = get_http_request($url, $context_data); if ($response == '0000') { $notify_status['success'] = TRUE; } else { $notify_status['success'] = FALSE; } unset($url, $send, $message, $response, $postdata, $context_data); // EOF
<?php /** * Observium * * This file is part of Observium. * * @package observium * @subpackage alerting * @copyright (C) 2006-2013 Adam Armstrong, (C) 2013-2016 Observium Limited * */ $message = $message_tags['TITLE'] . PHP_EOL; $message .= str_replace(" ", "", $message_tags['METRICS']); // JSON data $data_string = json_encode(array("originator" => $endpoint['originator'], "body" => $message)); // JSON data + HTTP headers $context_data = array('method' => 'POST', 'header' => "Connection: close\r\n" . "Accept: application/json\r\n" . "Content-Type: application/json\r\n" . "Content-Length: " . strlen($data_string) . "\r\n" . "Authorization: AccessKey " . $endpoint['token'] . "\r\n", 'content' => $data_string); // API URL to POST to $url = $endpoint['url']; // Send out API call and parse response into an associative array $result = json_decode(get_http_request($url, $context_data), TRUE); if ($result['message'] == 'SUCCESS') { $notify_status['success'] = TRUE; } else { $notify_status['success'] = FALSE; } unset($message, $result, $context_data); // EOF
foreach (dbFetchRows("SELECT COUNT(*) AS `count`, `os` FROM `devices` GROUP BY `os`") as $data) { $stats['devicetypes'][$data['os']] = $data['count']; } // Per-type counts foreach (dbFetchRows("SELECT COUNT(*) AS `count`, `type` FROM `devices` GROUP BY `type`") as $data) { $stats['types'][$data['type']] = $data['count']; } // Per-apptype counts foreach (dbFetchRows("SELECT COUNT(*) AS `count`, `app_type` FROM `applications` GROUP BY `app_type`") as $data) { $stats['app_types'][$data['app_type']] = $data['count']; } // Serialize and base64 encode stats array for transportation $stat_serial = serialize($stats); $stat_base64 = base64_encode($stat_serial); $url = "http://update.observium.org/latest.php?i=" . $stats['ports'] . "&d=" . $stats['devices'] . "&v=" . OBSERVIUM_VERSION . "&stats=" . $stat_base64; $data = rtrim(get_http_request($url)); if ($data) { list($omnipotence, $year, $month, $revision) = explode(".", $data); list($cur, $tag) = explode("-", OBSERVIUM_VERSION); /// FIXME. $tag is OBSERVIUM_TRAIN? list($cur_omnipotence, $cur_year, $cur_month, $cur_revision) = explode(".", $cur); $version_string = $omnipotence . '.' . $year . '.' . $month . '.' . $revision; file_put_contents($config['rrd_dir'] . '/version.txt', $version_string); if ($argv[1] == "--cron" || isset($options['q'])) { $fd = fopen($config['log_file'], 'a'); fputs($fd, $string . "\n"); fclose($fd); } else { if ($cur != $data) { echo "当前版本 : {$cur_revision}\n"; if ($revision > $cur_revision || TRUE) {
function get_geolocation($address, $geo_db = array()) { global $config; $location = array('location' => $address); // Init location array switch (strtolower($config['geocoding']['api'])) { case 'osm': case 'openstreetmap': $location['location_geoapi'] = 'openstreetmap'; // Openstreetmap. The usage limits are stricter here. (http://wiki.openstreetmap.org/wiki/Nominatim_usage_policy) $url = "http://nominatim.openstreetmap.org/search?format=json&accept-language=en&addressdetails=1&limit=1&q="; $reverse_url = "http://nominatim.openstreetmap.org/reverse?format=json&accept-language=en&"; break; case 'google': $location['location_geoapi'] = 'google'; // See documentation here: https:// developers.google.com/maps/documentation/geocoding/ // Use of the Google Geocoding API is subject to a query limit of 2,500 geolocation requests per day. $url = "http://maps.googleapis.com/maps/api/geocode/json?sensor=false&language=en&address="; $reverse_url = "http://maps.googleapis.com/maps/api/geocode/json?sensor=false&language=en&"; break; case 'yandex': $location['location_geoapi'] = 'yandex'; $url = "http://geocode-maps.yandex.ru/1.x/?format=json&lang=en_US&results=1&geocode="; $reverse_url = "http://geocode-maps.yandex.ru/1.x/?format=json&lang=en_US&results=1&sco=latlong&"; break; case 'mapquest': default: $location['location_geoapi'] = 'mapquest'; // Mapquest open data. There are no usage limits. $url = "http://open.mapquestapi.com/nominatim/v1/search.php?format=json&accept-language=en&addressdetails=1&limit=1&q="; $reverse_url = "http://open.mapquestapi.com/nominatim/v1/reverse.php?format=json&accept-language=en&"; } if (isset($config['geocoding']['enable']) && $config['geocoding']['enable']) { $reverse = FALSE; // by default forward geocoding $debug_msg = "Geocoding启用, 尝试定位设备坐标." . PHP_EOL; // If device coordinates set manually, use Reverse Geocoding. if ($geo_db['location_manual']) { $location['location_lat'] = $geo_db['location_lat']; $location['location_lon'] = $geo_db['location_lon']; $reverse = TRUE; $debug_msg .= ' MANUAL coordinates - SET' . PHP_EOL; } else { if ($config['geocoding']['dns']) { /** * Ack! dns_get_record not only cannot retrieve LOC records, but it also actively filters them when using * DNS_ANY as query type (which, admittedly would not be all that reliable as per the manual). * * Example LOC: * "20 31 55.893 N 4 57 38.269 E 45.00m 10m 100m 10m" * * From Wikipedia: d1 [m1 [s1]] {"N"|"S"} d2 [m2 [s2]] {"E"|"W"} * * Parsing this is something for Net_DNS2 as it has the code for it. */ if ($geo_db['hostname']) { include_once 'Net/DNS2.php'; include_once 'Net/DNS2/RR/LOC.php'; $resolver = new Net_DNS2_Resolver(); try { $response = $resolver->query($geo_db['hostname'], 'LOC', 'IN'); } catch (Net_DNS2_Exception $e) { print_debug(' ' . $e->getMessage() . ' (' . $geo_db['hostname'] . ')'); } } else { $response = FALSE; print_debug(" DNS 位置已激活, 不过设备主机名为空."); } if ($response) { if (OBS_DEBUG > 1) { var_dump($response->answer); } foreach ($response->answer as $answer) { if (is_numeric($answer->latitude) && is_numeric($answer->longitude)) { $location['location_lat'] = $answer->latitude; $location['location_lon'] = $answer->longitude; $reverse = TRUE; break; } else { if (is_numeric($answer->degree_latitude) && is_numeric($answer->degree_longitude)) { $ns_multiplier = $answer->ns_hem == 'N' ? 1 : -1; $ew_multiplier = $answer->ew_hem == 'E' ? 1 : -1; $location['location_lat'] = round($answer->degree_latitude + $answer->min_latitude / 60 + $answer->sec_latitude / 3600, 7) * $ns_multiplier; $location['location_lon'] = round($answer->degree_longitude + $answer->min_longitude / 60 + $answer->sec_longitude / 3600, 7) * $ew_multiplier; $reverse = TRUE; break; } } } if (isset($location['location_lat'])) { $debug_msg .= ' 通过DNS位置记录 - 找到' . PHP_EOL; } else { $debug_msg .= ' 通过DNS位置记录 - 未找到' . PHP_EOL; } } } } if ($reverse || !preg_match('/^<?(unknown|none)>?$/i', $address)) { /** * If location string contains coordinates use Reverse Geocoding. * Valid strings: * Some location [33.234, -56.22] * Some location (33.234 -56.22) * Some location [33.234;-56.22] * 33.234,-56.22 */ $pattern = '/(?:^|[\\[(])\\s*(?<lat>[+-]?\\d+(?:\\.\\d+)*)\\s*[,; ]\\s*(?<lon>[+-]?\\d+(?:\\.\\d+)*)\\s*(?:[\\])]|$)/'; if (!$reverse && preg_match($pattern, $address, $matches)) { if ($matches['lat'] >= -90 && $matches['lat'] <= 90 && $matches['lon'] >= -180 && $matches['lon'] <= 180) { $location['location_lat'] = $matches['lat']; $location['location_lon'] = $matches['lon']; $reverse = TRUE; } } if ($reverse) { $debug_msg .= ' by REVERSE query (API: ' . strtoupper($config['geocoding']['api']) . ', LAT: ' . $location['location_lat'] . ', LON: ' . $location['location_lon'] . ') - '; if (!is_numeric($location['location_lat']) || !is_numeric($location['location_lat'])) { // Do nothing for empty, skip requests for empty coordinates } else { if ($config['geocoding']['api'] == 'google') { // latlng=40.714224,-73.961452 $request = $reverse_url . 'latlng=' . $location['location_lat'] . ',' . $location['location_lon']; } else { if ($config['geocoding']['api'] == 'yandex') { // geocode=40.714224,-73.961452 $request = $reverse_url . 'geocode=' . $location['location_lat'] . ',' . $location['location_lon']; } else { // lat=51.521435&lon=-0.162714 $request = $reverse_url . 'lat=' . $location['location_lat'] . '&lon=' . $location['location_lon']; } } } } else { $debug_msg .= ' by PARSING sysLocation (API: ' . strtoupper($config['geocoding']['api']) . ') - '; if ($address != '') { $request = $url . urlencode($address); } } if ($request) { // First request $mapresponse = get_http_request($request); $data = json_decode($mapresponse, TRUE); $geo_status = 'NOT FOUND'; if ($config['geocoding']['api'] == 'google') { if ($data['status'] == 'OVER_QUERY_LIMIT') { $debug_msg .= $geo_status; print_debug($debug_msg); // Return empty array for overquery limit (for later recheck) return array('location_status' => $debug_msg); } // Use google data only with good status response if ($data['status'] == 'OK') { $data = $data['results'][0]; if ($data['geometry']['location_type'] == 'APPROXIMATE') { // It might be that the first element of the address is a business name. // Lets drop the first element and see if we get anything better! list(, $address) = explode(',', $address, 2); $request_new = $url . urlencode($address); $mapresponse = get_http_request($request_new); $data_new = json_decode($mapresponse, TRUE); if ($data_new['status'] == 'OK' && $data_new['results'][0]['geometry']['location_type'] != 'APPROXIMATE') { $request = $request_new; $data = $data_new['results'][0]; } } } } else { if ($config['geocoding']['api'] == 'yandex') { $try_new = FALSE; if ($data['response']['GeoObjectCollection']['metaDataProperty']['GeocoderResponseMetaData']['found'] > 0) { $data = $data['response']['GeoObjectCollection']['featureMember'][0]; if ($data['GeoObject']['metaDataProperty']['GeocoderMetaData']['precision'] == 'other') { $try_new = TRUE; } } else { $try_new = TRUE; } if ($try_new && strpos($address, ',')) { // It might be that the first element of the address is a business name. // Lets drop the first element and see if we get anything better! list(, $address) = explode(',', $address, 2); $request_new = $url . urlencode($address); $mapresponse = get_http_request($request_new); $data_new = json_decode($mapresponse, TRUE); if ($data_new['response']['GeoObjectCollection']['metaDataProperty']['GeocoderResponseMetaData']['found'] > 0 && $data_new['response']['GeoObjectCollection']['featureMember'][0]['GeoObject']['metaDataProperty']['GeocoderMetaData']['precision'] != 'other') { $request = $request_new; $data = $data_new['response']['GeoObjectCollection']['featureMember'][0]; } } } else { if (!isset($location['location_lat'])) { $data = $data[0]; if (!count($data) && strpos($address, ',')) { // We seem to have hit a snag geocoding. It might be that the first element of the address is a business name. // Lets drop the first element and see if we get anything better! This works more often than one might expect. list(, $address) = explode(',', $address, 2); $request_new = $url . urlencode($address); $mapresponse = get_http_request($request_new); $data_new = json_decode($mapresponse, TRUE); if (count($data_new[0])) { // We only want the first entry in the returned data. $data = $data_new[0]; $request = $request_new; } } } } } if (OBS_DEBUG > 1 && count($data)) { var_dump($data); } } else { $geo_status = '没有要求'; } } } // Put the values from the data array into the return array where they exist, else replace them with defaults or Unknown. if ($config['geocoding']['api'] == 'google') { $location['location_lat'] = $data['geometry']['location']['lat']; $location['location_lon'] = $data['geometry']['location']['lng']; foreach ($data['address_components'] as $entry) { switch ($entry['types'][0]) { case 'postal_town': case 'locality': $location['location_city'] = $entry['long_name']; break; case 'administrative_area_level_2': $location['location_county'] = $entry['long_name']; break; case 'administrative_area_level_1': $location['location_state'] = $entry['long_name']; break; case 'country': $location['location_country'] = strtolower($entry['short_name']); break; } } } else { if ($config['geocoding']['api'] == 'yandex') { list($location['location_lon'], $location['location_lat']) = explode(' ', $data['GeoObject']['Point']['pos']); $data = $data['GeoObject']['metaDataProperty']['GeocoderMetaData']['AddressDetails']; $location['location_country'] = strtolower($data['Country']['CountryNameCode']); $location['location_state'] = $data['Country']['AdministrativeArea']['AdministrativeAreaName']; $location['location_county'] = $data['Country']['AdministrativeArea']['SubAdministrativeArea']['SubAdministrativeAreaName']; $location['location_city'] = $data['Country']['AdministrativeArea']['SubAdministrativeArea']['Locality']['LocalityName']; } else { $location['location_lat'] = $data['lat']; $location['location_lon'] = $data['lon']; $location['location_city'] = strlen($data['address']['town']) ? $data['address']['town'] : $data['address']['city']; // Would be nice to have an array of countries where we want state, and ones where we want County. For example, USA wants state, UK wants county. $location['location_county'] = $data['address']['county']; $location['location_state'] = $data['address']['state']; $location['location_country'] = $data['address']['country_code']; } } // Use defaults if empty values if (!strlen($location['location_lat']) || !strlen($location['location_lon'])) { // Reset to empty coordinates $location['location_lat'] = array('NULL'); $location['location_lon'] = array('NULL'); //$location['location_lat'] = $config['geocoding']['default']['lat']; //$location['location_lon'] = $config['geocoding']['default']['lon']; //if (is_numeric($config['geocoding']['default']['lat']) && is_numeric($config['geocoding']['default']['lon'])) //{ // $location['location_manual'] = 1; // Set manual key for ability reset from WUI //} } else { // Always round lat/lon same as DB precision (DECIMAL(10,7)) $location['location_lat'] = round($location['location_lat'], 7); $location['location_lon'] = round($location['location_lon'], 7); } if (!strlen($location['location_city'])) { $location['location_city'] = '未知的城市'; } if (!strlen($location['location_county'])) { $location['location_county'] = '未知的城镇'; } if (!strlen($location['location_state'])) { $location['location_state'] = '未知的省份'; } if (!strlen($location['location_country'])) { $location['location_country'] = '未知的国家'; } else { $geo_status = 'FOUND'; } // Print some debug informations $debug_msg .= $geo_status . PHP_EOL; $debug_msg .= ' GEO API REQUEST: ' . $request; if ($geo_status == 'FOUND') { $debug_msg .= PHP_EOL . ' GEOLOCATION: '; $debug_msg .= country_from_code($location['location_country']) . ' (Country), ' . $location['location_state'] . ' (State), '; $debug_msg .= $location['location_county'] . ' (County), ' . $location['location_city'] . ' (City)'; $debug_msg .= PHP_EOL . ' GEO COORDINATES: '; $debug_msg .= $location['location_lat'] . ' (Latitude), ' . $location['location_lon'] . ' (Longitude)'; } else { $debug_msg .= PHP_EOL . ' QUERY DATE: ' . date('r'); // This is requered for increase data in DB } print_debug($debug_msg); $location['location_status'] = $debug_msg; return $location; }
case "status": case "mempool": case "processor": if (is_numeric($vars['entity_id']) && is_entity_permitted($vars['entity_id'], 'processor')) { $entity = get_entity_by_id_cache($vars['entity_type'], $vars['entity_id']); echo generate_entity_popup($entity, $vars['entity_type']); } else { print_warning("You are not permitted to view this entity."); } exit; break; case "mac": if (Net_MAC::check($vars['entity_id'])) { // Other way by using Pear::Net_MAC, see here: http://pear.php.net/manual/en/package.networking.net-mac.importvendors.php $url = 'http://api.macvendors.com/' . urlencode($vars['entity_id']); $response = get_http_request($url); if ($response) { echo 'MAC vendor: ' . $response; } else { echo '未找到'; } } else { echo '不正确的MAC地址'; } exit; break; default: print_error("未知的实体类型."); exit; break; }
$stats['misc']['max_len']['port_label_num'] = dbFetchCell("SELECT MAX(LENGTH(`port_label_num`)) FROM `ports`"); $stats['version'] = OBSERVIUM_VERSION; $stats['uuid'] = get_unique_id(); return $stats; } $last_checked = get_obs_attrib('last_versioncheck'); if (!is_numeric($last_checked) || $last_checked < time() - 3600 || $options['u']) { $stats = get_instance_stats(); // Serialize and base64 encode stats array for transportation $stat_serial = serialize($stats); $stat_base64 = base64_encode($stat_serial); $query = http_build_query(array('stats' => $stat_base64)); $context_data = array('method' => 'POST', 'header' => "Connection: close\r\n" . "Content-Length: " . strlen($query) . "\r\n", 'content' => $query); //$context = stream_context_create(array( 'http' => $context_data )); //$versions = file_get_contents( 'http://www.observium.org/versions.php', false, $context); $versions = get_http_request('http://www.observium.org/versions.php', $context_data); if ($versions = json_decode($versions, TRUE)) { if (OBSERVIUM_EDITION == "community") { $train = "ce"; } elseif (OBSERVIUM_TRAIN == "stable") { $train = "stable"; } else { $train = "current"; } // this same as rolling $latest = $versions[$train]; set_obs_attrib('latest_ver', $latest['version']); set_obs_attrib('latest_rev', $latest['revision']); set_obs_attrib('latest_rev_date', $latest['date']); } set_obs_attrib('last_versioncheck', time());
foreach (dbFetch("SELECT COUNT(*) AS count,os from devices group by `os`") as $data) { $stats['devicetypes'][$data['os']] = $data['count']; } // Per-type counts foreach (dbFetch("SELECT COUNT(*) AS `count`, `type` FROM `devices` GROUP BY `type`") as $data) { $stats['types'][$data['type']] = $data['count']; } // Per-apptype counts foreach (dbFetch("SELECT COUNT(*) AS `count`, `app_type` FROM `applications` GROUP BY `app_type`") as $data) { $stats['app_types'][$data['app_type']] = $data['count']; } // Serialize and base64 encode stats array for transportation $stat_serial = serialize($stats); $stat_base64 = base64_encode($stat_serial); $url = "http://update.observium.org/latest.php?i=" . $stats['ports'] . "&d=" . $stats['devices'] . "&v=" . $config['version'] . "&stats=" . $stat_base64; $data = get_http_request($url); if ($data) { list($omnipotence, $year, $month, $revision) = explode(".", $data); list($cur, $tag) = explode("-", $config['version']); list($cur_omnipotence, $cur_year, $cur_month, $cur_revision) = explode(".", $cur); if ($argv[1] == "--cron" || isset($options['q'])) { $fd = fopen($config['log_file'], 'a'); fputs($fd, $string . "\n"); fclose($fd); shell_exec("echo {$omnipotence}.{$year}.{$month}.{$month} > " . $config['rrd_dir'] . "/version.txt "); } else { if ($cur != $data) { echo "Current Revision : {$cur_revision}\n"; if ($revision > $cur_revision) { echo "最新版本 : {$revision}\n"; }
} if ($user_info !== null) { $verified_user_id = $user_info['user_id']; $is_admin = $user_info['is_admin']; $login_id = $user_info['login_id']; $name = $user_info['name']; $avatar = $user_info['avatar']; } if ($is_logout) { $session_token = ''; } setcookie('npclient', 'web', $expire); setcookie('nptoken', $session_token, $expire); return array('method' => $method, 'path' => $path, 'path_parts' => $url_parts, 'user_id' => $verified_user_id, 'login_id' => $login_id, 'logged_in' => $verified_user_id > 0, 'login_failure' => $login_failure, 'name' => $name, 'is_admin' => $is_admin, 'content_type' => $content_type, 'form' => $form, 'raw_content' => $raw_content, 'files' => $files, 'cookies' => $cookies, 'ip' => $ip, 'avatar' => $avatar, 'now' => time()); } $request = get_http_request(); $file = process_url_mapping($request); $log_not_found = $file == 'not_found.php'; // a little hacky. if ($log_not_found) { $legacy_url = sql_query_item("SELECT * FROM `legacy_article_url` WHERE `old_url` = '" . sql_sanitize_string($request['path']) . "' LIMIT 1"); if ($legacy_url != null) { $redir_url = trim($legacy_url['new_url']); header('HTTP/1.1 301 Moved Permanently'); header('Location: ' . $redir_url); exit; } } // overwrites suppress_skin to true, possibly require 'php/' . $file; $response = execute($request);
function get_geolocation($address) { global $config, $debug; switch (strtolower($config['geocoding']['api'])) { case 'osm': case 'openstreetmap': $location['location_geoapi'] = 'openstreetmap'; /// Openstreetmap. The usage limits are stricter here. (http://wiki.openstreetmap.org/wiki/Nominatim_usage_policy) $url = "http://nominatim.openstreetmap.org/search?format=json&addressdetails=1&limit=1&q="; $reverse_url = "http://nominatim.openstreetmap.org/reverse?format=json&"; break; case 'google': $location['location_geoapi'] = 'google'; // See documentation here: https://developers.google.com/maps/documentation/geocoding/ /// Use of the Google Geocoding API is subject to a query limit of 2,500 geolocation requests per day. $url = "http://api.map.baidu.com/geocoder/v2/?address="; $reverse_url = "http://api.map.baidu.com/geocoder/v2/json?sensor=false&"; break; case 'mapquest': default: $location['location_geoapi'] = 'mapquest'; /// Mapquest open data. There are no usage limits. $url = "http://open.mapquestapi.com/nominatim/v1/search.php?format=json&addressdetails=1&limit=1&q="; $reverse_url = "http://open.mapquestapi.com/nominatim/v1/reverse.php?format=json&"; } if ($address != "Unknown" && $config['geocoding']['enable']) { // If location string contains coordinates ([33.234, -56.22]) use Reverse Geocoding. $pattern = '/\\[\\s*([+-]*\\d+[\\d\\.]*)[,\\s]+([+-]*\\d+[\\d\\.]*)[\\s\\]]+/'; if (preg_match($pattern, $address, $matches)) { $location['location_lat'] = $matches[1]; $location['location_lon'] = $matches[2]; if ($config['geocoding']['api'] == 'openstreetmap') { //latlng=40.714224,-73.961452 $request = $reverse_url . 'latlng=' . $location['location_lat'] . ',' . $location['location_lon']; } else { //lat=51.521435&lon=-0.162714 $request = $reverse_url . 'lat=' . $location['location_lat'] . '&lon=' . $location['location_lon']; } } else { $request = $url . urlencode($address); } $mapresponse = get_http_request($request); $data = json_decode($mapresponse, true); if ($config['geocoding']['api'] == 'openstreetmap') { if ($data['status'] == 'OVER_QUERY_LIMIT') { // Return empty array for overquery limit (for later recheck) return array(); } // Use google data only with good status response if ($data['status'] == 'OK') { $data = $data['results'][0]; if ($data['geometry']['location_type'] == 'APPROXIMATE') { // It might be that the first element of the address is a business name. // Lets drop the first element and see if we get anything better! list(, $address) = explode(',', $address, 2); $mapresponse = get_http_request($url . urlencode($address)); $data_new = json_decode($mapresponse, true); if ($data_new['status'] == 'OK' && $data_new['results'][0]['geometry']['location_type'] != 'APPROXIMATE') { $data = $data_new['results'][0]; } } } } elseif (!isset($location['location_lat'])) { $data = $data[0]; if (!count($data)) { /// We seem to have hit a snag geocoding. It might be that the first element of the address is a business name. /// Lets drop the first element and see if we get anything better! This works more often than one might expect. list(, $address) = explode(',', $address, 2); $mapresponse = get_http_request($url . urlencode($address)); $data = json_decode($mapresponse, true); /// We only want the first entry in the returned data. $data = $data[0]; } } } if ($debug) { echo "GEO-API 需要: {$request}\n"; } /// Put the values from the data array into the return array where they exist, else replace them with defaults or Unknown. if ($config['geocoding']['api'] == 'google') { $location['location_lat'] = $data['geometry']['location']['lat']; $location['location_lon'] = $data['geometry']['location']['lng']; foreach ($data['address_components'] as $entry) { switch ($entry['types'][0]) { case 'locality': $location['location_city'] = $entry['long_name']; break; case 'administrative_area_level_2': $location['location_county'] = $entry['long_name']; break; case 'administrative_area_level_1': $location['location_state'] = $entry['long_name']; break; case 'country': $location['location_country'] = strtolower($entry['short_name']); break; } } } else { $location['location_lat'] = $data['lat']; $location['location_lon'] = $data['lon']; $location['location_city'] = strlen($data['address']['town']) ? $data['address']['town'] : $data['address']['city']; /// Would be nice to have an array of countries where we want state, and ones where we want County. For example, USA wants state, UK wants county. $location['location_county'] = $data['address']['county']; $location['location_state'] = $data['address']['state']; $location['location_country'] = $data['address']['country_code']; } // Use defaults if empty values if (!strlen($location['location_lat'])) { $location['location_lat'] = $config['geocoding']['default']['lat']; } if (!strlen($location['location_lon'])) { $location['location_lon'] = $config['geocoding']['default']['lon']; } if (!strlen($location['location_city'])) { $location['location_city'] = 'Unknown'; } if (!strlen($location['location_county'])) { $location['location_county'] = 'Unknown'; } if (!strlen($location['location_state'])) { $location['location_state'] = 'Unknown'; } if (!strlen($location['location_country'])) { $location['location_country'] = 'Unknown'; } return $location; }