The right way of deploying the changes between the environment including delete operations can be achieved by drush
command or hook_update()
as part of your deployment, since auto-deletion of any content by Features module is not possible to avoid any content lost (which is the last thing that you want to do on your production). See: #649298 for further details.
hook_update
Here is example by using hook_update()
:
/**
* Deletes fields.
*/
function MYMODULE_update_7001() {
$fields = array(
'field_foo',
'field_bar',
);
foreach($fields as $field) {
if (field_info_field($field)) {
field_delete_field($field);
field_purge_batch(10);
drupal_is_cli() ? drush_log("Deleting field $field", "ok") : NULL;
};
}
}
?>
or this one posted at GH gist by insparrow:
<?php
/**
* Remove a shared field from a content type.
*/
function custom_module_update_7027() {
// Fetch instance info.
$entity_type = drush_field_get_entity_from_bundle('custom_content_type');
$instance = field_info_instance($entity_type, 'field_to_remove', 'custom_content_type');
// Mark field for deletion.
field_delete_instance($instance);
// Remove field marked for deletion.
field_purge_batch(10);
watchdog('custom_module', 'Removed field_to_remove instance from custom_content_type', array(), WATCHDOG_INFO);
}
field_delete_field
Marks a field and its instances and data for deletion.
field_purge_batch
This function will purge deleted field data in batches. If a deleted field instance with no remaining data records is found, the instance itself will be purged. If a deleted field with no remaining field instances is found, the field itself will be purged.
drush
Use drush
which can be invoked as part of your deployment process and its field-delete
command.
For example:
drush field-delete field_name
to delete a field and its instances.
To delete only instance attached to specific bundle, try:
field-delete field_name --bundle=bundle
Alternatively you can consider to implement your own drush
command which find all abandoned fields and removes them.
Here is example code posted by Chi:
<?php
/**
* @file
* Drush command to find all abandoned fields.
*
* @see http://drupal.org/node/649298
*/
/**
* Implements hook_drush_command().
*/
function abandoned_fields_drush_command() {
$items['abandoned-fields'] = array(
'description' => 'Find all abandoned fields',
'drupal dependencies' => array('features'),
'aliases' => array('af'),
);
return $items;
}
/**
* Drush command callback;
*/
function drush_abandoned_fields() {
module_load_include('inc', 'features', 'features.export');
$commited_fields = array();
foreach (features_get_default('field') as $id => $field) {
if (!in_array($field['field_config']['field_name'], $commited_fields)) {
$commited_fields[] = $field['field_config']['field_name'];
}
}
$rows[] = array('Field name', 'Location');
$rows[] = array('-------------', '----------');
foreach (field_info_fields() as $field_name => $field) {
if (!in_array($field_name, $commited_fields)) {
$bundle_strs = array();
foreach ($field['bundles'] as $entity_type => $bundles) {
$bundle_strs[] = $entity_type . ' (' . implode(',', $bundles) . ')';
}
$rows[]= array(
$field_name,
implode(' ', $bundle_strs),
);
}
}
drush_print_table($rows);
}
For further details, you may want to read Deleting a Drupal Field Saved in Features.