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:

  // 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:

  module_load_include('inc', 'content', 'includes/content.crud');
  content_module_delete($module);

The above example is equivalent to do the following:

  // 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:

  // 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:

  // 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.

Comments

asb’s picture

How and where do we have to use these code snippets?

Would it be possible to add some human-readable instructions for people that are not hacking Drupal core as a day job?

Thanks!
-asb

omigosh’s picture

I agree. I have better things to do than turn myself into a code geek. Drupal is supposed to help create web sites not make it more difficult.

rcross’s picture

Its the lowly code geeks that make it possible for you to make comments like this.

Drupal makes many things easier, but not all things are able to be accomplished without writing some code. It is worth your time to at least be respectful of the people who support it, and I would recommend to anyone working in this area to at least spend enough time to know enough to run some code (and hopefully try to understand it).

To get good support, see the tips at http://drupal.org/forum-posting#homework

poiu’s picture

I just pasted it into Devel's execute-php block (without the php tags) and it looks like it did the trick.

I think the second and third 'assetfield's in the snippet might be different than the module name (although in my case they weren't.) You should probably check by looking the content_node_field and content_node_field_instance db tables first.

If someone who knows what they're doing reads this, maybe edit the HOWTO to clarify?

coolest’s picture

Hi,
I have upgraded Drupal from 5 to 6.
I have some field with taxonomy super select ultra and I get the following message in the manage fields page of the node type:

studio_area (field_studio_area) is an inactive cck_taxonomy_ssu field that uses a cck_taxonomy_ssu_2 widget.

I would like to remove the widget (which is no longer supported in D6), is there a way to do so?

Thank you.
-- NS

faqing’s picture

1. Use PhpMyAdmin to brows your database
2. Brows "content_node_field_instance"
3. Find and delete "studio_area"

ggevalt’s picture

Thanks so much for this information. This is a totally, completely easy way to deal with this issue. Worked like a charm.
geoff

TwiiK’s picture

See here: http://drupal.org/node/144269#comment-780023

Not even sure if that completely removes an inactive field, but it at least shows you have to delete a lot more columns, rows and tables in the database than just one to remove the field.

Øyvind Strømsvik
Tech lead | Frontkom AS
https://frontkom.com/