it-swarm.com.de

Löschen Sie programmgesteuert einen Eintrag aus einem Feld einer Entität

Wie kann ein bestimmter Feldeintrag für ein Feld mit mehreren Einträgen aus einer bestimmten Entität programmgesteuert gelöscht werden? (das sind bestimmte Felder und bestimmte Entitäten, keine Feldtypen oder Instanzen und Entitätstypen)

Hier sind einige Möglichkeiten, die ich untersucht habe und die nicht funktionieren:

  • Laden der Entität mit entity_load(), Setzen des Feldeintrags auf = null oder = array () und Speichern mit field_attach_update(). Es ist das nächste, das ich gefunden habe, aber es hinterlässt einen Zombie-Nullfeldeintrag in der Datenbank, der in Formularen als leere Zeile angezeigt wird, bis das Formular gespeichert wird und hook_field_is_empty() einspringen kann (hook_field_is_empty() ist so konfiguriert, dass = null oder = array () als leer markiert werden).
  • Laden der Entität mit entity_load(), Deaktivieren des Feldeintrags per Schlüssel und Speichern mit field_attach_update(). Dies scheint nichts zu bewirken - es scheint, dass Drupal interpretiert den Eintrag, der nicht vorhanden ist, als Zeichen, um ihn nicht zu ändern. (Seltsamerweise erhalte ich manchmal auch maximale Ablaufzeiten für die Abfragezeit, wenn ich diesen Ansatz versuche)
  • field_attach_delete() - das ist viel zu stumpf: Es werden alle Felder für die Entität gelöscht
  • field_purge_data() - besser, aber immer noch zu stumpf: Es werden alle Einträge des Feldes gelöscht, nicht bestimmte Einträge

Zur Verdeutlichung habe ich Code, der eine Entität mit einem Feld mit mehreren Einträgen findet (und lädt) und einen bestimmten Eintrag in diesem Feld findet, der entfernt werden muss. Ich möchte diesen Eintrag vollständig entfernen, ohne andere Einträge oder andere Felder in der Entität zu berühren.

Wenn Sie sich auf das Entity API-Modul verlassen können, sollten Sie Code ähnlich dem folgenden verwenden können:

// Load some entity.
$entity = entity_load_single($entity_type, $id);

// Remove the field value.
unset($entity->field_FIELD_NAME[LANGUAGE_NONE][$index]);

// Reset the array to zero-based sequential keys.
$entity->field_FIELD_NAME[LANGUAGE_NONE] = array_values($entity->field_FIELD_NAME[LANGUAGE_NONE]);

// Save the entity.
entity_save($entity_type, $entity);
24
Clive

Ich musste dies im Rahmen einer Drupal8-Migrationsbereinigung tun.

Nach einigen Experimenten stellte ich fest, dass das Iterieren und anschließende Verwenden von unset () für das Delta es töten könnte. Mein Beispiel war das Entfernen eines Tags (daher suche ich nach 'target_id', nicht nach 'value', wie Sie es oft für andere Felder tun würden.

/**
 * Removes a term from a field.
 *
 * @return bool
 *   success
 */
private function removeTerm(\Drupal\node\NodeInterface $object, \Drupal\taxonomy\TermInterface $term, $field_name) {
  // Check if tag value exists already.
  // Remember they may be multiples.
  /** @var @var \Drupal\Core\Field\FieldItemList $field_values */
  $field_values = $object->get($field_name);
  foreach ($field_values as $delta => $field_value) {
    if ($field_value->getValue()['target_id'] == $term->id()) {
      unset($field_values[$delta]);
      return TRUE;
    }
  }
  return FALSE;
}

Und danach, wenn Erfolg, dann $object->save();

1
dman

Für Drupal 8, um ein Feld aus einer Entität zu löschen:

$entity = Node::load($nid);
unset($entity->field_name);

Dadurch wird die magische Methode __unset () von ContentEntityBase aufgerufen:

public function __unset($name) {
    // Unsetting a field means emptying it.
    if ($this->hasField($name)) {
        $this->get($name)->setValue([]);
    }
    // For non-field properties, unset the internal value.
    else {
        unset($this->values[$name]);
    }
}

Vergessen Sie nicht, dass Sie anrufen müssen, um Ihre Änderungen beizubehalten

$entity->save();

Nachdem Sie alle Änderungen vorgenommen haben.

0