4

We have a situation where in different environments we have to manually delete fields. Rather than manually doing that, we want to programmatically deploy the changes. The idea that is being is discussed is to use a custom module which calls the hook_field_delete_instance() hook.

The issue we are having is how to best pass in the content type machine name and the machine name for a single content type. We are understanding that when we reused the field on a separate content type, we are essentially creating an alias on the current content type that points to the original content type holding the field name.

Using the situation below, what is the best way to delete the two fields on the on the basic page only using the hook_field_delete_instance() on a custom module?

Situation:

We have two content types: article and basic page. We created several fields on the article content type that we ended up reusing on the basic page.

Article:

  1. field_art_original_publish_date
  2. field_art_country_tag
  3. field_art_image

Basic Page:

  1. field_art_image (reused from article content type)
  2. field_art_country_tag (reused from article content type)

Update:

So now that i am thinking further on this, i would like 1 hook update for 1 field deletion so that if a hook update fails then i know which fields need attention.

Here is what i have come up with using what @Clive has suggested.

function mymodule_update_7001(&$sandox) {
     mymodule_delete_field('field_art_image', 'page' );
}

function mymodule_update_7002(&$sandox) {
    mymodule_delete_field('field_art_country_tag', 'page');
}

function mymodule_delete_field($field_mn, $ct_mn) {
    $entity_type = "node";

    $field_instance = field_info_instances($entity_type, $field_mn, $ct_mn);
    field_delete_instance($field_instance);

    //setting the batch size to a large number resolves my prior issues
    $batch_size = 20000;
    field_purge_batch($batch_size);
}
1
  • field_purge_batch($batch_size), $batch_size - The maximum number of field data records to purge before returning. So try to set big value for $batch_size, field won't be removed while it has any data.
    – skorzh
    Commented Apr 6, 2016 at 5:15

2 Answers 2

4

We are understanding that when we reused the field on a separate content type, we are essentially creating an alias on the current content type that points to the original content type holding the field name.

Not quite - each instance exists in its own right, unaffected by any other instance of the same field on another entity type/bundle. Removing it from one bundle (content type) won't touch it on another bundle, regardless of which one it was originally attached to.

You won't need hook_field_delete_instance() for this, just a combination of field_info_instance() and field_delete_instance() in an update hook. Something like this:

/**
 * Remove old fields from the Basic Page content type.
 */
function MYMODULE_update_7100() {
  $field_art_image = field_info_instance('node', 'field_art_image', 'page');
  field_delete_instance($field_art_image);

  $field_art_country_tag = field_info_instance('node', 'field_art_country_tag', 'page');
  field_delete_instance($field_art_country_tag);

  return 'Fields deleted, data will be cleared up on cron.';
}
2
  • this helps, but for some reason the field is still there on the content type. I have updated the question with my latest code. Not sure if i am not waiting long enough for cron to finish or if the code is wrong. Commented Apr 6, 2016 at 1:03
  • so when i updated the batch size to a large number, your suggestions worked flawlessly! thank you again! Commented Apr 8, 2016 at 0:54
0

I found this code for drupal 8 that worked very good for me here https://gist.github.com/jacerider/78b926acbb201666a0fc3a1f8102cb44

This empty the field, them remove field from bundle

I just added in a hook_update_N() [https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Extension%21module.api.php/function/hook_update_N/8.2.x][1]

use Drupal\field\Entity\FieldStorageConfig;
use Drupal\field\Entity\FieldConfig;

$bundles = ['user'];

$fields['user_picture'] = [
  'entity_type' => 'user',
];

foreach ($bundles as $bundle) {
  foreach ($fields as $field_name => $config) {
    $field = FieldConfig::loadByName($config['entity_type'], $bundle, $field_name);
    if (!empty($field)) {
      $field->delete();
    }
  }
}

foreach ($fields as $field_name => $config) {
  $field_storage = FieldStorageConfig::loadByName($config['entity_type'], $field_name);
  if (!empty($field_storage)) {
    $field_storage->delete();
  }
}

[1]: https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Extension%21module.api.php/function/hook_update_N/8.2.x "hook_update_N"strong text

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.