3

I have two content types on my site and I just deleted all the nodes using $node->delete().

For one of the content types, I noticed that the node body fields did not get deleted, nor did one of the custom fields I made for the content type. All the fields for my other content type were deleted .

So I researched and found the field_purge_field() function. I am not sure how to actually use the function, which is defined as function field_purge_field(FieldConfigInterface $field).
Can someone describe how I would actually load a field and then delete it in this manner (or in a better manner)?

Could I just truncate the tables?

5

field_purge_field() is described as follows:

This function assumes all data for the field has already been purged and should only be called by field_purge_batch().

On Drupal, fields are effectively removed during cron tasks; in fact, field_purge_batch() is called from field_cron(), the implementation of hook_cron() done from the Field module. There is no need for you to call neither field_purge_field() nor field_purge_batch().

If you want to write code to purge fields for a node bundle, that code would be similar to the following one. (See the notes after the code, thought.)

  $properties = array(
    'entity_type' => 'node',
    'bundle' => 'Your bundle (a.k.a. content type)',
    'include_deleted' => TRUE,
  );

  $entity_manager = \Drupal::entityTypeManager();

  $fields = $entity_manager->getStorage('field_config')->loadByProperties($properties);

  $info = $entity_manager->getDefinitions();
  foreach ($fields as $field) {
    $entity_type = $field->getTargetEntityTypeId();

    // Proceed only if the module implementing the entity has not been uninstalled already.
    if (isset($info[$entity_type])) {
      $entity_manager->getStorage($entity_type)->purgeFieldData($field, 100);
      field_purge_field($field);
    }
  }

Notes

  • Purging the fields is thought to be ran during cron tasks; that is why Drupal::entityManager()->getStorage()->purgeFieldData() requires the batch size as argument. I used a value of 100, which would possibly allow the code to purge all the fields for that content type, but it could also cause a PHP timeout error. It would be better to run the code from PHP CLI, in order to avoid any execution time out.
  • You should not need to use this code; in most of the cases, you should execute the cron tasks (which is when Drupal purges the fields of a deleted bundle), or use Drush to purge the fields, either running hook_cron() with it, or executing a specific Drush command (if it exists).

As for truncating the tables, that is the wrong way to proceed. It would not allow Drupal and third-party modules to delete the data they have for the fields; even if you know which tables Drupal uses, you could forget a table used by third-party modules.

  • Thanks for this info. Where does $fields come from? Is it the output of the loadByProperties() function? – Brian Huether Oct 11 '15 at 18:23
  • Yes, it is. I forgot a part while replacing a function used by Drupal code. – kiamlaluno Oct 11 '15 at 18:27
  • what about locked fields, I need to delete just one field that is locked, I tried that solution but i didn't catch the field to delete – Mohammed Gomma Apr 27 '16 at 6:29
  • @MohammedGomma It is probable that locked fields cannot be deleted, so you cannot even purge them. – kiamlaluno Sep 28 '18 at 7:40
3

The updated version for Drupal 8.3.x using non deprecated functions:

/**
 * Removes field_MY_FIELD_NAME.
 */
function MYMODULE_update_8001() {
  /* @var $entityFieldManager Drupal\Core\Entity\EntityFieldManager */
  $entityFieldManager = Drupal::service('entity_field.manager');

  $fields = $entityFieldManager->getFieldDefinitions('ENTITY_TYPE', 'BUNDLE');

  if (isset($fields['field_MY_FIELD_NAME'])) {
    $fields['field_MY_FIELD_NAME']->delete();
  }
}

Replace the following:

  1. ENTITY_TYPE by the entity type, e.g.: 'taxonomy_term', 'node'...
  2. BUNDLE by the bundle, e.g.: 'article', 'tags'...
  3. field_MY_FIELD_NAME by the field machine name, e.g.: 'field_description'...
  • Thank you, this actually deleted the field instances for me. I don't know why purge_field didn't work, maybe it's because I'm using a custom entity? – RaisinBranCrunch Aug 23 '17 at 14:52
  • The delete() method is undefined in Drupal 8.6 – Shaun Dychko Jan 15 at 19:00
1

The following will delete content and config of a field in all places used on the same entity type. NOTE: in D7 fields could be used across entity types (i.e. same field used on different bundles of same entity type) but in D8, this is not allowed:

use Drupal\field\Entity\FieldStorageConfig;
FieldStorageConfig::loadByName(ENTITY_TYPE_NAME, FIELD_NAME)->delete();

As with the other methods above, this will result in field remnants being left behind in the key_value and cachetags tables. CRON runs will remove remnants from the key_value table but I have not yet found a way to remove remnants from the cachetags table (short of simply using direct db calls).

[EDIT] I stated that field remnants from key_value table would be removed during CRON; but in fact this only occurs if there had been data in that field. Not sure why this is different but likely a core bug.

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

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();
  }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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