Convert country name to 2 letter country code with Google geocoding and migrate
You are browsing documentation for an older version of Drupal, which is not supported any longer, and the information may not be correct. See current documentation for Contributed modules
Here's a suggested starting point for someone migrating into Address Field with country names in the source. This does Google geocoding since Google can understand typos in the country name, returning DE for "ermany", "Gerany", and other typos. In the migrate constructor use $this->addFieldMapping('[my_destination_address_field]', 'country_code');
The following takes inspiration from the Geocoder module, and requires it to be enabled with a Google API key entered. It assumes a text field with one value in the source with machine name field_country. The error messages also assumes you're migrating Users, so change $row->uid to suit (probably for nodes: $row->nid)
if (!empty($row->field_country)) {
// Geocode the country name to the 2 letter country code expected by
// Address Field.
// Sleep between Google API requests to avoid being blocked by overuse.
$delay_trigger = &drupal_static(__METHOD__);
$delay = variable_get('geocoder_google_delay', 0);
if ($delay > 0 && $delay_trigger) {
usleep($delay * 1000);
}
// Get Google API key entered in the geocoder module.
$geocoder_settings = variable_get('geocoder_settings', array());
$query['key'] = $geocoder_settings['geocoder_apikey_google'];
// Use "components" rather than an "address" to prevent Google from
// mistaking an improperly typed country name as a city.
$query['components'] = 'country:' . $row->field_country[0];
$base_url = 'https://maps.googleapis.com/maps/api/geocode/json';
$url = url($base_url, array(
'query' => $query,
));
// Send the request.
$result = drupal_http_request($url);
$delay_trigger = TRUE;
if (isset($result->error)) {
$args = array(
'@code' => $result->code,
'@error' => $result->error,
'@uid' => $row->uid,
);
$msg = t('HTTP request to google API failed.\nCode: @code\nError: @error for user with source uid: @uid', $args);
drush_print($msg);
return FALSE;
}
$data = json_decode($result->data);
if ($data->status == 'ZERO_RESULTS') {
drush_print('zero results from geocoding country for source uid: ' . $row->uid);
return FALSE;
}
elseif ($data->status != 'OK') {
$args = array('@status' => $data->status, '@uid' => $row->uid);
$msg = t('Google API returned bad status.\nStatus: @status for source uid: @uid', $args);
drush_print($msg);
return FALSE;
}
$country_code = '';
// Find the "country" address_component
$address_components = $data->results[0]->address_components;
foreach ($address_components as $address_component) {
if (in_array('country', $address_component->types)) {
$country_code = $address_component->short_name;
}
}
if (empty($country_code)) {
$this->queueMessage('Empty country geocode result for country' . $country);
return FALSE;
}
$row->country_code = $country_code;
}
Help improve this page
You can:
- Log in, click Edit, and edit this page
- Log in, click Discuss, update the Page status value, and suggest an improvement
- Log in and create a Documentation issue with your suggestion