it-swarm-ja.com

1つのエンティティの1つのフィールドから1つのエントリをプログラムで削除する

1つの特定のエンティティからマルチエントリフィールドの1つの特定のフィールドエントリをプログラムで削除する適切な方法は何ですか? (それは特定のフィールドと特定のエンティティであり、フィールドタイプまたはインスタンスとエンティティタイプではありません)

私が調べたいくつかの可能性がありますが、うまくいきません:

  • entity_load()でエンティティを読み込み、フィールドエントリを= nullまたは= array()に設定してから、field_attach_update()で保存します。それは私が見つけた最も近いものですが、フォームが保存されてhook_field_is_empty()が起動するまで、フォームに空白行として表示されるゾンビnullフィールドエントリがデータベースに残ります(hook_field_is_empty()は、= nullまたは= array()が空としてフラグを立てるように構成されています)。
  • entity_load()でエンティティを読み込み、キーでフィールドエントリの設定を解除してから、field_attach_update()で保存します。これは何もしないようです-Drupalエントリが存在しないことを、それを変更しない兆候として解釈しているようです。(奇妙なことに、このアプローチを試みると、最大クエリ時間のタイムアウトが発生することがあります)
  • field_attach_delete()-率直に言って、エンティティのすべてのフィールドが削除されます
  • field_purge_data()-より良いですが、あまりにも率直です:特定のエントリではなく、フィールドのすべてのエントリを削除します

明確にするために、複数のエントリを持つフィールドを持つエンティティを検索(およびロード)し、そのフィールドで削除する必要のある特定のエントリを見つけるコードがあります。エンティティの他のエントリや他のフィールドに触れずに、そのエントリを完全に削除したいと思います。

エンティティAPIモジュール を信頼できる場合は、次のようなコードを使用できるはずです。

// 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

Drupal8移行クリーンアップの一環としてこれを行う必要がありました。

いくつかの実験を行った後、デルタで繰り返し、unset()を使用すると、デルタを強制終了できることがわかりました。私の例は、タグを削除することでした(したがって、他のフィールドの場合のように、「value」ではなく「target_id」を検索します。

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

その後、成功した場合は$object->save();

1
dman

Drupal 8の場合、エンティティからフィールドを削除するには:

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

これにより、ContentEntityBaseからマジックメソッド__unset()が呼び出されます。

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

忘れないでください。変更を永続化するには、

$entity->save();

すべての変更を行った後。

0