it-swarm.com.de

Wie lösche ich Felder programmgesteuert richtig?

Ich habe zwei Inhaltstypen auf meiner Site und habe gerade alle Knoten mit $node->delete() gelöscht.

Bei einem der Inhaltstypen habe ich festgestellt, dass die Knotenkörperfelder nicht gelöscht wurden und auch keines der benutzerdefinierten Felder, die ich für den Inhaltstyp erstellt habe. Alle Felder für meinen anderen Inhaltstyp wurden gelöscht.

Also habe ich recherchiert und die Funktion field_purge_field() gefunden. Ich bin nicht sicher, wie ich die Funktion verwenden soll, die als function field_purge_field(FieldConfigInterface $field) definiert ist.
Kann jemand beschreiben, wie ich ein Feld tatsächlich laden und dann auf diese Weise (oder besser) löschen würde?

Könnte ich die Tabellen einfach abschneiden?

3
Brian Huether

field_purge_field() wird wie folgt beschrieben:

Diese Funktion setzt voraus, dass alle Daten für das Feld bereits gelöscht wurden und nur von field_purge_batch() aufgerufen werden sollten.

In Drupal werden Felder bei Cron-Aufgaben effektiv entfernt. Tatsächlich wird field_purge_batch() von field_cron() aufgerufen, der Implementierung von hook_cron() aus dem Field-Modul. Sie müssen weder field_purge_field() noch field_purge_batch() aufrufen.

Wenn Sie Code schreiben möchten, um Felder für ein Knotenpaket zu löschen, ähnelt dieser Code dem folgenden. (Siehe die Notizen nach dem Code, dachte.)

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

Anmerkungen

  • Es wird angenommen, dass das Löschen der Felder während Cron-Aufgaben ausgeführt wird. Aus diesem Grund benötigt Drupal::entityManager()->getStorage()->purgeFieldData() die Stapelgröße als Argument. Ich habe einen Wert von 100 verwendet, der es dem Code möglicherweise ermöglichen würde, alle Felder für diesen Inhaltstyp zu löschen, aber es könnte auch einen Timeout-Fehler von PHP] verursachen. Es wäre besser, den Code auszuführen from PHP CLI, um ein Zeitlimit für die Ausführung zu vermeiden.
  • Sie sollten diesen Code nicht verwenden müssen. In den meisten Fällen sollten Sie die Cron-Tasks ausführen (wenn Drupal löscht die Felder eines gelöschten Bundles) oder Drush verwenden, um die Felder zu löschen, indem Sie entweder hook_cron() ausführen damit oder Ausführen eines bestimmten Drush-Befehls (falls vorhanden).

Das Abschneiden der Tabellen ist der falsche Weg. Es würde nicht zulassen, dass Drupal und Module von Drittanbietern die Daten löschen, die sie für die Felder haben, selbst wenn Sie wissen, welche Tabellen Drupal verwendet), könnten Sie vergessen Eine Tabelle, die von Modulen von Drittanbietern verwendet wird.

5
kiamlaluno

Die aktualisierte Version für Drupal 8.3.x mit nicht veralteten Funktionen:

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

Ersetzen Sie Folgendes:

  1. ENTITY_TYPE nach Entitätstyp, z. B.: 'taxonomy_term', 'node'...
  2. BUNDLE durch das Bündel, z. B.: 'article', 'tags'...
  3. field_MY_FIELD_NAME durch den Feldmaschinennamen, z. B.: 'field_description'...
4
Dakwamine

Im Folgenden werden Inhalt und Konfiguration eines Felds an allen Stellen gelöscht, die für denselben Entitätstyp verwendet werden. HINWEIS: In D7 können Felder für alle Entitätstypen verwendet werden (d. H. Dasselbe Feld, das für verschiedene Bundles desselben Entitätstyps verwendet wird). In D8 ist dies jedoch nicht zulässig:

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

Wie bei den anderen oben genannten Methoden führt dies dazu, dass Feldreste in den Tabellen key_value und cachetags zurückbleiben. CRON-Läufe entfernen Reste aus der key_value-Tabelle, aber ich habe noch keine Möglichkeit gefunden, Reste aus der Cachetags-Tabelle zu entfernen (ohne einfach direkte Datenbankaufrufe zu verwenden).

[EDIT] Ich habe angegeben, dass Feldreste aus der Tabelle key_value während CRON entfernt werden. Tatsächlich tritt dies jedoch nur auf, wenn Daten in diesem Feld vorhanden waren. Ich bin mir nicht sicher, warum dies anders ist, aber wahrscheinlich ein Kernfehler.

1
liquidcms

Ich habe diesen Code für drupal 8 gefunden, der hier sehr gut für mich funktioniert hat https://Gist.github.com/jacerider/78b926acbb201666a0fc3a1f8102cb44

Dies leert das Feld, sie entfernen das Feld aus dem Bündel

Ich habe gerade ein hook_update_N () hinzugefügt 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();
  }
}
0
Carlos