HOW TO: Remove inactive fields

Last modified: November 1, 2009 - 17:21

While working on the migration of CCK fields from D5 to D6, you may find that once you have finished upgrading the modules and data to the new version, there are still a few fields that were part of an old version that does not exist in your new D6 installation, and you may now need to remove these fields. Please, read related discussion in the CCK issue queue: #258458: Can't delete inactive fields through the API.

If you need to remove a field instance from the system, you should use content_field_instance_delete(). However, this function can only be used to process active fields (more about this later). Here's an example:

<?php
 
// Load the file that implements CRUD (Create, Read, Update and Delete) methods in CCK.
 
module_load_include('inc', 'content', 'includes/content.crud');

 
// Delete a field instance.
 
content_field_instance_delete($field_name, $type_name);
?>

Here's an example to delete all the fields implemented by a particular module:

<?php
  module_load_include
('inc', 'content', 'includes/content.crud');
 
content_module_delete($module);
?>

The above example is equivalent to do the following:

<?php
 
// This deletes all fields implemented by $module from the content tables.
 
content_notify('uninstall', $module);
?>

Note that the above example is used in the implementation of hook_uninstall() of all modules that implement CCK fields.

It works as long as $module is enabled. But if it isn't, then you'll have to enable $module before that. Example:

<?php
 
// This updates the inactive flag of fields created by $module.
 
content_notify('enable', $module);

 
// This deletes all fields implemented by $module from the content tables.
 
content_notify('uninstall', $module);
?>

Now, the problem may come when $module cannot be enabled, maybe because there's no version of that module ready for D6. ie. we cannot do content_notify('enable', $module). Ok, so here's what we can do in this case:

<?php
 
// Prepare the list of modules and their fields and widgets that we
  // want to remove from the system.
 
$modules_info = array(
   
'assetfield' => array(
     
'fields' => array('assetfield'),
     
'widgets' => array('assetfield'),
    ),
  );

  foreach (
$modules_info as $module => $module_info) {
   
$affected_total = 0;

   
// Enable the fields implemented by $module that we want to remove.
   
foreach ($module_info['fields'] as $field_type) {
     
db_query("UPDATE {". content_field_tablename() ."} SET module = '%s', active = %d WHERE type = '%s'", $module, 1, $field_type);
     
$affected = db_affected_rows();
      if (
$affected > 0) {
       
watchdog('content', 'Updated field type %type with module %module.', array('%type' => $field_type, '%module' => $module));
       
$affected_total += $affected;
      }
    }

   
// Enable the widgets implemented by $module that we want to remove.
   
foreach ($module_info['widgets'] as $widget_type) {
     
db_query("UPDATE {". content_instance_tablename() ."} SET widget_module = '%s', widget_active = %d WHERE widget_type = '%s'", $module, 1, $widget_type);
     
$affected = db_affected_rows();
      if (
$affected > 0) {
       
watchdog('content', 'Updated widget type %type with module %module.', array('%type' => $widget_type, '%module' => $module));
       
$affected_total += $affected;
      }
    }

   
// If we have enabled fields and/or widgets implemented by $module, then
    // we can now proceed to tell CCK that we want to remove them.
   
if ($affected_total > 0) {
     
watchdog('content', 'Removing fields and widgets related to module %module.', array('%module' => $module));
     
content_notify('uninstall', $module);
    }
  }
?>

Note that removing fields from the system will delete the field structure from the content tables, but also user data. So be sure to have backups at hand before trying these code snippets.

 
 

Drupal is a registered trademark of Dries Buytaert.