it-swarm.com.de

Wie entferne ich programmgesteuert ein Feld von einem Knoten?

Wie entfernt man programmgesteuert ein Feld von einem Knoten? Ich habe eine Migration in hook_update_N, das den Inhalt aus einem Feld in eine benutzerdefinierte Tabelle verschiebt. Nach dieser Migration möchte ich das Feld in derselben Funktion entfernen.

Gibt es Feld-APIs, die das Entfernen von Feldern ermöglichen?

Bearbeiten, Lösung: Da die Antworten keinen tatsächlichen Code enthalten, habe ich Folgendes getan, um Felder von den $ -Nutzern in meine eigenen Datensätze zu verschieben und anschließend das Feld aus der Datenbank zu entfernen.

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) markiert den $field_name zum Löschen beim nächsten Cron-Lauf.

Sie können field_purge_batch verwenden, um das Löschen durchzuführen, wenn Sie dies beim Cron-Lauf nicht möchten.

EDIT: field_delete_field() sollte verwendet werden, wenn Sie das Feld auch aus anderen Bundles löschen müssen. Wenn Sie nur das Feld aus einem bestimmten Bundle löschen möchten, sollten Sie field_delete_instance() verwenden, wie von @Clive erwähnt.

29
AjitS

Um ein Feld aus einem bestimmten Bundle zu entfernen, können Sie field_delete_instance() verwenden

Markiert eine Feldinstanz und ihre Daten zum Löschen.

Beispiel:

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

Um ein Feld vollständig aus dem System zu entfernen, können Sie field_delete_field() verwenden

Markiert ein Feld und seine Instanzen und Daten zum Löschen.

Beispiel:

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

Die Felder/Instanzen sind nur zum Löschen markiert, die Daten werden bei nachfolgenden Cron-Läufen tatsächlich gelöscht. Um es manuell zu löschen, führen Sie Folgendes aus:

field_purge_batch(1);
24
Clive

Um die Frage von @berkes zu beantworten:

field_delete_field() markiert das zu löschende Feld und wird beim nächsten Cron-Lauf gelöscht. Jedoch tut es Daten auf field_config_instance Bezüglich des abgelegten Feldes belassen. Wenn Sie cron oder field_purge_batch() ausführen, werden diese Daten nicht aus der Tabelle field_config_instance Entfernt, selbst wenn die gelöschte Spalte für das Feld auf 1 Gesetzt ist.

Für mich hat die Verwendung von field_delete_instance() gefolgt von einer field_purge_batch() für jedes gelöschte Feld funktioniert - sofortiges Entfernen des Felds aus der Datenbank (ohne Cron erforderlich) sowie Löschen des field_config_instance Tabelle aller Felddaten (für das gelöschte Feld).

Hier ist die Lösung:

/**
 * 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);
    }
  }
}

Beachten Sie das TRUE auf field_delete_instance(), da es angibt, dass die Feld-API Bereinigungsvorgänge ausführen soll.

5
amateur barista