View source
<?php
function geocoder_drush_command() {
$items = array();
$items['geocoder-backfill'] = array(
'callback' => 'geocoder_drush_backfill',
'description' => 'Geocodes all nodes that have a geocoder widget but no geodata.',
'options' => array(
'force' => 'Force the geocode to run, even if there is already geodata',
'dry' => 'Collect entity ids, but do not update them.',
'entity_type' => 'An entity type. If none is specified, entities of all types are processed.',
'field_name' => 'A field name. If none is specified, all applicable fields are processed.',
'bundle' => 'A bundle name. If none is specified, entities of all bundles are processed.',
'entity_ids' => 'A list of entity ids, separated by comma (no space). If none are specified, all entities are processed. This requires that entity_type is defined, too.',
),
);
return $items;
}
function geocoder_drush_backfill() {
$force_reload = drush_get_option('force');
$dry_run = drush_get_option('dry');
$expected_entity_type = drush_get_option('entity_type');
$expected_field_name = drush_get_option('field_name');
$expected_bundle = drush_get_option('bundle');
$expected_entity_ids = drush_get_option_list('entity_ids');
if (!$expected_entity_type) {
if ($expected_bundle) {
drush_log('Cannot specify a bundle, if no entity type is specified.', 'error');
return;
}
if ($expected_entity_ids) {
drush_log('Cannot specify entity ids, if no entity type is specified.', 'error');
return;
}
$expected_bundle = NULL;
$expected_entity_ids = array();
}
foreach (field_info_instances() as $entity_type => $instances_by_bundle) {
if ($expected_entity_type && $entity_type !== $expected_entity_type) {
continue;
}
$entities_to_save = array();
foreach ($instances_by_bundle as $bundle => $instances_by_fieldname) {
if ($expected_bundle && $bundle !== $expected_bundle) {
continue;
}
foreach ($instances_by_fieldname as $dest_field_name => $field_instance) {
if ($expected_field_name && $dest_field_name !== $expected_field_name) {
continue;
}
if ($field_instance['widget']['type'] !== 'geocoder') {
continue;
}
if (empty($field_instance['widget']['settings']['geocoder_field'])) {
continue;
}
$source_field_name = $field_instance['widget']['settings']['geocoder_field'];
$q = db_select('field_data_' . $source_field_name, 'source');
$q
->condition('source.entity_type', $entity_type);
$q
->condition('source.bundle', $bundle);
if ($expected_entity_ids) {
$q
->condition('source.entity_id', $expected_entity_ids);
}
if (!$force_reload) {
$q
->leftJoin('field_data_' . $dest_field_name, 'dest', 'source.entity_type = dest.entity_type and source.entity_id = dest.entity_id');
$q
->isNull('dest.entity_id');
}
$q
->fields('source', array(
'entity_id',
));
$q
->groupBy('source.entity_id');
if (NULL === ($result = $q
->execute())) {
continue;
}
$etids_orig = $result
->fetchCol();
if (array() === $etids_orig) {
drush_log($entity_type . ': ' . $bundle . ': ' . $dest_field_name . ': -', 'ok');
continue;
}
$entities = entity_load($entity_type, $etids_orig);
$etids = array_keys($entities);
$etids_orphan = array_diff($etids, $etids_orig);
drush_log($entity_type . ': ' . $bundle . ': ' . $dest_field_name . ': ' . implode(', ', $etids), 'ok');
if (array() !== $etids_orphan) {
drush_log('Orphan etids: ' . implode(', ', $etids_orphan), 'warning');
}
$entities_to_save += $entities;
}
}
if (!$dry_run) {
foreach ($entities_to_save as $entity) {
entity_save($entity_type, $entity);
}
}
}
}