Commit 983e26b9 authored by lyricnz's avatar lyricnz
Browse files

758126: Initial port of Geonames module to D7

parent de8f7731
// $Id
- Added functions for continent codes, country info, feature code info, us states info
- Added some tables and functions for metadata to local tables (countryinfo and featurecodes)
- Removed all "module_invoke_all" calls.
- Aggregated the full configuration in geonames_config.inc
- Probably done lots of other stuff as well ;)
COMMITTED 29.09:
geonames bugfix line 462/465.. "==" to "=", and "else if" to "if"
wikipediasearch changed columns from associative array to array
wikipediabbox changed columns from associative array to array
PENDING:
postalcodesearch styled code
children styled code
countrycode styled code
countryinfo styled code
countrysubdivision styled code
hierarchy styled code
nearbyplace
The GeoNames contrib project is a collection of modules to integrate with
the webservers and data provided by GeoNames http://www.geonames.org/
=======================================================================
GeoNames Wikipedia Search: Integrate Wikipedia Results into Search
=======================================================================
Creates a new search type "Wikipedia" that includes results from
http://www.geonames.org/export/wikipedia-webservice.html#wikipediaSearch
The results provided by the module also include all values from the XML, including
coordinates and a thumbnail image.
[entry] => Array
(
[lang] => en
[title] => Stock Exchange Tower
[summary] => at 125 Old Broad Street. Standing at 103 m (339 feet) tall, with 26 floors, the tower was completed in 1970. It served as the headquarters and offices for the London Stock Exchange until its departure for new premises in Paternoster Square, in July 2004. ''Face to face'' trading was conducted on the trading floor of the exchange, until it was abolished in favour of electronic trading (...)
[feature] =>
[population] => 0
[elevation] => 0
[lat] => 51.5144
[lng] => -0.0867
[wikipediaUrl] => http://en.wikipedia.org/wiki/Stock_Exchange_Tower
[thumbnailImg] => http://www.geonames.org/img/wikipedia/11000/thumb-10323-100.jpg
)
These could be themed something like
/**
* Include a thumbnail in wikipedia search results (provided by geonames/wikipedia_search.module)
*/
function yourmodule_search_item($item, $type) {
switch ($item['type']) {
case 'wikipedia':
// Add coordinates to the extra information
$entry = $item['entry'];
$item['extra'] = array('LAT:' . $entry['lat'], 'LONG:' . $entry['lng']);
// Add a thumbnail image to the results
if ($entry['thumbnailImg']) {
$img_html = theme('image', $entry['thumbnailImg'], $item['title'], $item['title'], NULL, FALSE);
$link_html = l($img_html, $item['link'], array(), NULL, NULL, FALSE, TRUE);
$item['snippet'] = $link_html . $item['snippet'];
}
$html = theme_search_item($item, $type);
break;
default:
$html = theme_search_item($item, $type);
break;
}
return $html;
}
<?php
// $Id$
/**
* @file
* Administration-related functions for GeoNames
*/
/**
* Admin Settings Page
*/
function geonames_admin_settings() {
$form['geonames_docs_path'] = array(
'#type' => 'textfield',
'#title' => t('Path to GeoNames Documentation'),
'#description' => t('Where do you want the documentation to reside?'),
'#default_value' => variable_get('geonames_docs_path', 'geonames/docs'),
);
$form['cache'] = array(
'#type' => 'fieldset',
'#title' => t('Cache'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
);
$form['cache']['clear_cache'] = array(
'#type' => 'markup',
'#markup' => t('There are currently %num items in the cache. [!clearlink]', array(
'%num' => db_query("SELECT COUNT(*) FROM {cache_geonames}")->fetchField(),
'!clearlink' => l(t('Clear cache'), 'admin/config/geonames/clear_cache'),
)),
);
$form['cache']['geonames_cache'] = array(
'#type' => 'radios',
'#title' => t('Caching'),
'#description' => t('Enable unless you have a good reason to disable it.'),
'#default_value' => variable_get('geonames_cache', TRUE),
'#options' => array(1 => 'Enabled', 0 => 'Disabled'),
);
$form['cache']['geonames_cache_limit'] = array(
'#type' => 'textfield',
'#title' => t('Cache lifetime'),
'#description' => t('Cache items for ... days'),
'#default_value' => variable_get('geonames_cache_limit', 14),
);
$form['cache']['geonames_reveal_cache'] = array(
'#type' => 'radios',
'#title' => t('Reveal Cache'),
'#description' => t('If an item is retrieved from the cache, the request[cached] property will be available in the result object if this switch is set to Yes.'),
'#default_value' => variable_get('geonames_reveal_cache', TRUE),
'#options' => array(1 => 'Yes', 0 => 'No'),
);
$commercial_collapsed = (variable_get('geonames_commercial_active', FALSE) == TRUE) ? FALSE : TRUE;
$form['commercial'] = array(
'#type' => 'fieldset',
'#title' => t('GeoNames Commercial Webservices'),
'#collapsible' => TRUE,
'#collapsed' => $commercial_collapsed
);
$form['commercial']['leadingtext'] = array(
'#type' => 'markup',
'#prefix' => '<div>',
'#markup' => t('You should always support developers of quality services. Increased performance is cheap, and you should afford it. Visit the !link page for more information', array('!link' => l(t('GeoNames Commercial Webservices'), 'http://www.geonames.org/professional-webservices.html'))),
'#suffix' => '</div>'
);
if (variable_get('geonames_commercial_active', FALSE) == TRUE) {
// Show the Status and Credits Counter (ick)
$since = variable_get('geonames_commercial_credits_since', 0);
$form['commercial']['counter'] = array(
'#type' => 'markup',
'#prefix' => '<div><p>',
'#markup' => '<b>' . t('Status') . ':</b><br />' . t('You have used @credits credits since %date. [!link]', array(
'@credits' => variable_get('geonames_commercial_credits', 0),
'%date' => $since ? format_date($since) : t('Unknown date'),
'!link' => l(t('Reset'), 'admin/config/geonames/reset_credits'),
)),
'#suffix' => '</p></div>'
);
}
$form['commercial']['geonames_commercial_active'] = array(
'#type' => 'radios',
'#title' => t('GeoNames Commercial Webservices'),
'#default_value' => variable_get('geonames_commercial_active', 0),
'#options' => array(1 => 'Enabled', 0 => 'Disabled'),
);
$form['commercial']['geonames_commercial_server'] = array(
'#type' => 'textfield',
'#title' => t('URL to Commercial Service Server'),
'#description' => 'Example: http://ws.geonames.net - without the trailing slash',
'#default_value' => variable_get('geonames_commercial_server', 'http://ws.geonames.net'),
);
$form['commercial']['geonames_commercial_username'] = array(
'#type' => 'textfield',
'#title' => t('Username'),
'#default_value' => variable_get('geonames_commercial_username', ''),
);
$updated = variable_get('geonames_metadata_updated', 0);
$values = array(
'!numcountries' => db_query('SELECT COUNT(*) FROM {geonames_countryinfo}')->fetchField(),
'!numfeaturecodes' => db_query('SELECT COUNT(*) FROM {geonames_featurecodes}')->fetchField(),
'!updated' => $updated ? t('Last run !interval ago', array('!interval' => format_interval(REQUEST_TIME - $updated))) : t('Never updated'),
);
// The state and title of the fieldset depend on whether the metadata is complete.
if ($values['!numcountries'] == 0 || $values['!numfeaturecodes'] == 0) {
$form['metadata'] = array(
'#type' => 'fieldset',
'#title' => t('Metadata - Incomplete'),
'#collapsible' => TRUE,
'#collapsed' => FALSE,
);
}
else {
$form['metadata'] = array(
'#type' => 'fieldset',
'#title' => t('Metadata'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
);
}
$form['metadata']['metadata_status'] = array(
'#type' => 'markup',
'#prefix' => '<div>',
'#markup' => t('There are currently !numcountries countries and !numfeaturecodes feature codes in the local tables. !updated.', $values),
'#suffix' => '</div>',
);
$form['metadata']['metadata_refresh'] = array(
'#type' => 'button',
'#value' => t('Refresh metadata from geonames.org'),
'#executes_submit_callback' => TRUE,
'#submit' => array('geonames_metadata_update'),
);
$form['licencing'] = array(
'#type' => 'markup',
'#prefix' => '<div>',
'#markup' => t('Note: You must give credit to !geonameslink if you are not using the commercial services, for example by including a link to !theirsitelink on your pages. The GeoNames geographical database is released under the !cclink.', array(
'!geonameslink' => l(t('GeoNames'), 'http://www.geonames.org/'),
'!theirsitelink' => l(t('their site'), 'http://www.geonames.org/'), // should be translated
'!cclink' => l(t('Creative Commons Attribution Licence 3.0'), 'http://creativecommons.org/licenses/by/3.0/'),
)),
'#suffix' => '</div>'
);
return system_settings_form($form);
}
/**
* Admin Settings Page : Validation
*/
function geonames_admin_settings_validate($form, &$form_state) {
$geonames_commercial_active = $form_state['values']['geonames_commercial_active'];
$geonames_commercial_server = $form_state['values']['geonames_commercial_server'];
$geonames_commercial_username = $form_state['values']['geonames_commercial_username'];
// have Commercial Services Changed?
$c = $form['commercial'];
$com_changed = $geonames_commercial_active != $c['geonames_commercial_active']['#default_value'];
$com_changed = $com_changed || ($geonames_commercial_server != $c['geonames_commercial_server']['#default_value']);
$com_changed = $com_changed || ($geonames_commercial_username != $c['geonames_commercial_username']['#default_value']);
// if active and changed, validate
if ($geonames_commercial_active && $com_changed) {
// verify that a username is set
if ($geonames_commercial_username == '') {
form_set_error('geonames_commercial_username', t('Commercial Webservices: You must provide a username.'));
}
else {
// verify if the service works
// Test using the search service
$url = $geonames_commercial_server . '/search?username=' . $geonames_commercial_username . '&name=nydalen';
$data = drupal_http_request($url);
if ($data->code != '200') {
form_set_error('geonames_commercial_server', t('There is a problem with the response from the URL you have specified.') . '<br />' . t('The server returned errorcode %code: %error', array('%code' => $data->code, '%error' => $data->error)));
}
else {
$xml = new SimpleXMLElement($data->data);
if ($xml->status['message']) {
form_set_error('geonames_commercial_server', t('GeoNames Service Response: %message (code: %code)', array('%message' => $xml->status['message'], '%code' => $xml->status['value'])));
}
else {
geonames_credits_pay(1); // use one credit! ;)
if ($xml->geoname[0]->name == 'Nydalen') {
drupal_set_message(t('Your account has been successfully tested and is properly configured!'));
}
else {
form_set_error('', t('Unknown Error'));
}
}
}
}
}
}
/**
* Clear the Results and Data Cache.
*/
function geonames_cache_clear($adminpage = TRUE) {
cache_clear_all(NULL, 'cache_geonames');
if ($adminpage) {
drupal_set_message(t('Cache cleared.'));
drupal_goto('admin/config/geonames');
}
}
/**
* Commercial Service: Reset Credits Counter
*/
function geonames_credits_reset($adminpage = TRUE) {
variable_set('geonames_commercial_credits', 0);
variable_set('geonames_commercial_credits_since', REQUEST_TIME);
if ($adminpage) {
drupal_set_message(t('Credits and time reset.'));
drupal_goto('admin/config/geonames');
}
}
<?php
// $Id$
/**
* @file
* The online help for GeoNames. TODO: convert to advanced help etc?
*/
/**
* Documentation pages is a form, stupid but it works for now :))
*/
function geonames_docs() {
$page = '<div>';
$page .= '<div class="messages">' . t('Syntax: $result = geonames_query($service, $query, $options)') . '</div>';
$page .= '</div>';
$element = array(
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#title' => t('Parameter: $service (string)'),
'#value' => '<div>The "Usage Instructions for Installed Services" below, lists all the currently installed services available on your system. Please look there for details on the various services.</div>',
);
$page .= theme('fieldset', $element);
$element = array(
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#title' => t('Parameter: $query (associative array)'),
'#value' => '<div>Queries (query parameters) are defined as associative arrays, as the one above. For a list of allowed query parameters, please see the specific service under "Usage Instructions for Installed Services".' . '<div class="messages">' . t('Example: $query = array(\'lat\' => 59.95, \'lng\' => 10.77)') . '</div>' . 'This query can be used with all services that require the parameters lat and lng, for example Find Nearby Place Name.<br /><br />
The query parameters are usually integers (numbers) or strings (text), but for a few services they are allowed to be arrays (multiple values) in order to be able to pass several values of the same type (for instance countries or featurecodes), in the example below we pass on two countries.' . '<div class="messages">' . t('Example: $query = array(\'name\' => \'Holmen\', \'country\' => array(\'NO\',\'SE\'))') . '</div>If you use this query with the \'search\' service (GeoNames Fulltext Search), you will find places with the name <i>Holmen</i> in <i>Norway</i> or <i>Sweden</i></div>',
);
$page .= theme('fieldset', $element);
$element = array(
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#title' => t('Parameter: $options (associative array) - optional'),
'#value' => t('<div>You may use the $option parameter to modify the results. Limit the number of fields returned, order the columns, or sort the rows. The options array has three optional properties: columns, sortby and sortorder (all of them may be used independently).<br /><br /><b>columns</b> is an array of fieldnames ') . '<div class="messages">' . t('Example: $options ' . "= array('columns' => array('countryname', 'countrycode') )") . '</div>' . t('By passing this option your results will only contain the two columns specified (countryname and countrycode). The result object will also be arranged with your results in the specified order.') . t('<br /><br /><b>sortby</b> is a fieldname (string) ') . '<div class="messages">' . t('Example: $options ' . "= array('sortby' => 'countryname')") . '</div>' . t('By passing this option your results will be ordered by the countryname.') . t('<br /><br /><b>sortorder</b> is either ASC or DESC (string) ') . '<div class="messages">' . t('Example: $options ' . "= array('sortorder' => 'DESC')") . '</div>' . t('By passing this option your results will be returned in a descending order (Your list of Countries would start with the letter Z).') . t('<br /><br /><div class="messages">') . t('Multiple Options Example: $options ' . "= array('sortby' => 'countryname', 'sortorder' => 'DESC')") . '</div>' . t('This option would return your results ordered by Country Name, descending.</div>'),
);
$page .= theme('fieldset', $element);
$element = array(
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#title' => t('Result: $result (object)'),
'#value' => '<div>The results object will look something like this: <br />
<pre>
$result->results = array(
[0] = array(\'name\' => \'Oslo\', ...)
[1] = array(\'name\' => \'Nydalen\', ...)
...
)
$result->total_results_count = integer, number of total results
$result->service = string service name
$result->request = array (
\'url\' = URL sent to GeoNames server
\'bytes\' = size of data requested from GeoNames server
\'seconds\' = time used for request to GeoNames server
\'cached\' = if the result is loaded from the cache, this variable is set to the cache type (result or data)
)
$result->query = array(
\'lat\' = 23
\'lng\' = 34
\'maxrows\' = 10
...
)
$result->pager = array() - associative array, only available for some services
$result->standalone = if set to <i>no</i>, the GeoNames commercial service is used
</pre></code>
</div>',
);
$page .= theme('fieldset', $element);
$page .= '<br /><div>' . t('In the usage instructions below, <b>bold</b> parameters are') . ' <b>' . t('mandatory') . '</b>' . t('. Parameters that are structured like \'key=value\' are default values for parameters, and may be overridden. Items in') . ' <i>' . t('italics') . '</i> ' . t('are') . ' <i>' . t('optional parameters') . '</i>. ' . t('Services with multiple bold parameters may be one out of two types; single or all - read the instructions carefully.') . '<br /><br /><h2>' . t('Usage Instructions for Installed Services') . '</h2></div>';
$services = geonames_config(); // geonames_config('services', 'keys');
// This function used to return the full configuration........ look into how to fix it (fix in other version as well)!
foreach ($services as $service => $sc) { // service configuration
$usage = sprintf("<div class=messages>Usage: \$result = geonames_query('%s', \$query, <i>\$options</i>)</div>", $service);
// Compile the $query part... this is tricky!
// First, check if the required parameters is an array of arrays (how many times do we have to loop?)
// count variations of required parameters combinations
$variations = (is_array($sc['required_parameters'][0])) ? count($sc['required_parameters']) : 1;
$usage_query = '';
$loops = 0;
while ($loops < $variations) {
// Get $rp
$rp = ($variations > 1) ? $sc['required_parameters'][$loops] : $sc['required_parameters'];
$usage_query .= ($usage_query) ? '<b>or</b><div style="height: 8px"></div>' : '';
$usage_query .= '$query = array(';
$numreqpar = 0; // Count number of request parameters -- used for displaying various strings later
if ($rp) {
foreach ($rp as $pmtr) {
$numreqpar++;
$usage_query .= '<b>' . $pmtr . '</b>, ';
}
}
if ($sc['query_defaults']) {
foreach ($sc['query_defaults'] as $key => $val) {
if ($key != 'type') {
$usage_query .= $key . '=' . $val . ', ';
}
}
}
if (is_array($sc['allowed_parameters'])) {
foreach ($sc['allowed_parameters'] as $key => $val) {
if ((!is_array($rp) || (is_array($rp) && !in_array($key, $rp))) && (!is_array($sc['query_defaults'] || (is_array($sc['query_defaults']) && !in_array($key, array_keys($sc['query_defaults'])))))) {
if ($key != 'type') {
$usage_query .= '<i>' . $key . '</i>, ';
}
}
}
}
$query_comments = '';
if (is_array($sc['array_parameters'])) {
// Some of the parameters are allowed to be arrays...
foreach ($sc['array_parameters'] as $arrpar) {
$query_comments .= sprintf('<li> %s is allowed to be an array of strings</li>', $arrpar);
}
}
// strip the last ', ' from the querystring
if (strstr($usage_query, ',')) {
$usage_query = drupal_substr($usage_query, 0, drupal_strlen($usage_query) - 2);
}
if ($sc['required_parameters_type'] == 'single') {
if ($numreqpar > 1) {
$query_comments .= '<li> just one of the bold parameters is required </li>';
}
}
if ($sc['required_parameters_type'] == 'all') {
if ($numreqpar == 2) {
$query_comments .= '<li> both bold parameters are required </li>';
}
elseif ($numreqpar > 2) {
$query_comments .= '<li> all bold parameters are required </li>';
}
}
// If no comments, add some space with br
$query_comments = ($query_comments) ? sprintf("<ul>%s</ul>", $query_comments) : '<div style="height: 6px"></div>';
$usage_query .= ($usage_query) ? ')' . $query_comments : '';
$loops++;
} // End while loop
$resultrows = '<div>$result->results = array(';
if ($sc['columns']) {
// Columns are defined -- use those
foreach ($sc['columns'] as $a) {
$resultrows .= $a . ', ';
}
$resultrows = drupal_substr($resultrows, 0, drupal_strlen($resultrows) -2) . ')';
}
else {
// Probably short/medium/long/full syntax... TODO this does not work... DEBUG
$gf = geonames_fields('full', TRUE);
foreach ($gf as $f) {
$resultrows .= $f . ', ';
}
$resultrows = drupal_substr($resultrows, 0, drupal_strlen($resultrows) -2) . ')';
$resultrows .= ' -- FULL style';
}
$resultrows .= '</div>';
$element = array(
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#title' => t($sc['service_full_name']),
'#value' => '<div>Purpose: ' . $sc['description'] . $usage . $usage_query . $resultrows . '</div>',
);
$page .= theme('fieldset', $element);
}
return $page;
}
; $id$
name = GeoNames API
description = The GeoNames API provides the programming framework for the GeoNames services.
description = The GeoNames API provides the programming framework for the GeoNames services.
package = Geonames
core = 6.x
php = 5.1
\ No newline at end of file
core = 7.x
; php = 5.1
files[] = geonames.admin.inc
files[] = geonames.doc.inc
files[] = geonames.install
files[] = geonames.module
files[] = geonames_config.inc
; files[] = geonames_tools.module
files[] = tests/geonames.test
<?php
// $Id
// $Id$
/**
* Implementation of hook_schema()
* @file
* Install, update and uninstall functions for the geonames module.
*
*/
/*
* @file
* Install and schema for geonames module
*/
/**
* Implements hook_schema().
*/
function geonames_schema() {
$schema['geonames_countryinfo'] = array(
'fields' => array(
'iso_alpha2' => array(
'type' => 'varchar',
'not null' => true,
'length' => 2,
),
'iso_alpha3' => array(
'type' => 'varchar',
'not null' => true,
'length' => 3,
),
'iso_numeric' => array(
'type' => 'int',
'not null' => true,
'size' => 'tiny',
'unsigned' => true,
),
'fips_code' => array(
'type' => 'varchar',
'not null' => true,
'length' => 3,
),
'name' => array(
'type' => 'varchar',
'not null' => true,
'length' => 60,
),
'capital' => array(
'type' => 'varchar',
'not null' => true,
'length' => 60,
),
'areainsqkm' => array(
'type' => 'varchar',
'not null' => true,
'length' => 11,
),
'population' => array(
'type' => 'varchar',
'not null' => true,
'length' => 11,
),
'continent' => array(
'type' => 'varchar',
'not null' => true,
'length' => 2,
),
'languages' => array(
'type' => 'varchar',
'not null' => true,
'length' => 100,
),
'currency' => array(
'type' => 'varchar',
'not null' => true,
'length' => 3,
),
'geonameid' => array(
'type' => 'int',
'not null' => true,
'unsigned' => true,
),
),
'indexes' => array(
'iso_alpha3' => array('iso_alpha3'),
'iso_numeric' => array('iso_numeric'),
'fips_code' => array('fips_code'),
'continent' => array('continent'),
'currency' => array('currency'),
'iso_alpha2' => array('iso_alpha2'),
),
'primary key' => array('geonameid'),
);
'description' => 'GeoNames.org Country Information',
'fields' => array(
'iso_alpha2' => array(
'type' => 'varchar',
'not null' => TRUE,
'length' => 2,
'description' => 'two-letter country code (ISO 3166-1-alpha-2)',
),
'iso_alpha3' => array(
'type' => 'varchar',
'not null' => TRUE,
'length' => 3,
'description' => 'three-letter country code (ISO 3166-1 alpha-3)',
),
'iso_numeric' => array(
'type' => 'int',
'not null' => TRUE, <