web-dev-qa-db-fra.com

Comment supprimer par programmation un champ d'un nœud?

Comment supprimer un champ d'un nœud par programme? J'ai une migration dans hook_update_N qui déplace le contenu d'un champ dans une table personnalisée. Après cette migration, je souhaite supprimer le champ dans cette même fonction.

Existe-t-il des API de champ qui permettent de supprimer des champs?

Edit, Solution: Parce que les réponses manquent de code réel, voici ce que j'ai fait pour déplacer les champs des utilisateurs $ dans mes propres enregistrements et supprimer ensuite le champ de la base de données;

function my_module_update_7005(&$sandbox) {
  $slice = 100;
  //Fetch users from database;
  if (!isset($sandbox['progress'])) {
    $sandbox['progress'] = 0;
    $sandbox['current_uid'] = 0;
    // We'll -1 to disregard the uid 0...
    $sandbox['max'] = db_query('SELECT COUNT(DISTINCT uid) FROM {users}')->fetchField() - 1;
  }
  if (empty($users)) {
    $sandbox["current_uid"] += $slice;
  }
  $users = db_select('users', 'u')
    ->fields('u', array('uid', 'name'))
    ->condition('uid', $sandbox['current_uid'], '>')
    ->range(0, $slice)
    ->orderBy('uid', 'ASC')
    ->execute();
  //Loop trough users;
  foreach ($users as $user) {
    $foo = new Foo();
    // Warning: drupal's fields return mixed values; e.g. NULL versus an int.
    $foo->debits = (int) $user->user()->field_credits["und"][0]["value"];
    $foo->save();

    $sandbox['progress']++;
    $sandbox['current_uid'] = $user->uid;
  }

  $sandbox['#finished'] = empty($sandbox['max']) ? 1 : ($sandbox['progress'] / $sandbox['max']);

  // Remove the field.
  field_delete_field("field_credits"); //note that the name for Foo is field_foo
  field_purge_batch($sandbox['max']+1);//Drupal seems to have an offbyone problem.
}
16
berkes

field_delete_field($field_name) marquera le $field_name pour suppression lors de la prochaine exécution cron.

Vous pouvez utiliser field_purge_batch pour effectuer la suppression, si vous ne voulez pas le faire lors de l'exécution cron.

EDIT: field_delete_field() doit être utilisé lorsque vous devez également supprimer le champ d'autres bundles. Si vous souhaitez uniquement supprimer le champ d'un bundle particulier, vous devez utiliser field_delete_instance() comme mentionné par @Clive.

29
AjitS

Pour supprimer un champ d'un bundle particulier, vous pouvez utiliser field_delete_instance()

Marque une instance de champ et ses données pour suppression.

Exemple:

function my_module_update_7001() {
  if ($instance = field_info_instance('node', 'field_name', 'page'))  {
    field_delete_instance($instance, TRUE);
    field_purge_batch(1);
  }
}

Pour supprimer complètement un champ du système, vous pouvez utiliser field_delete_field()

Marque un champ et ses instances et données pour suppression.

Exemple:

function my_module_update_7001() {
  field_delete_field('field_name');
  field_purge_batch(1);
}

Les champs/instances ne sont marqués que pour suppression, les données seront en fait purgées lors des exécutions de cron suivantes. Pour le purger manuellement, exécutez:

field_purge_batch(1);
24
Clive

Pour répondre à la question @berkes:

field_delete_field() marque le champ à supprimer, ce qui le purge lors de la prochaine exécution cron. Cependant c'est le cas laisser des données sur field_config_instance Concernant le champ supprimé. L'exécution de cron ou field_purge_batch() ne supprimera pas ces données de la table field_config_instance, Même si la colonne supprimée est définie sur 1 Pour le champ.

Pour moi, utiliser field_delete_instance() suivi d'une field_purge_batch() pour chaque champ purgé travaillé - supprimant instantanément le champ de la base de données (sans nécessiter de cron), ainsi que la purge du field_config_instance table de toutes les données de champ (pour le champ supprimé).

Voici la solution:

/**
 * Implements hook_uninstall().
 */
function hook_uninstall() {
  // Delete all fields for all xyz entity bundles.

  // Retrieve all bundles for an entity.
  $bundles = field_info_bundles('XYZ'); // The name of your entity type, for example, 'node'.
  foreach ($bundles as $bundle => $properties) {

    // Retrieve all the fields for a given bundle.
    $instances = field_info_instances('XYZ', $bundle);
    foreach ($instances as $instance) {
      field_delete_instance($instance, TRUE);
      field_purge_batch(1);
    }
  }
}

Notez la TRUE sur field_delete_instance(), car elle indique que l'API Field doit effectuer des opérations de nettoyage.

5
amateur barista