Secara terprogram menghapus satu entri dari satu bidang pada satu entitas


13

Apa cara yang tepat untuk secara terprogram menghapus satu entri bidang tertentu untuk bidang multi-entri dari satu entitas tertentu? (itu bidang khusus dan entitas spesifik, bukan tipe bidang atau instance dan tipe entitas)

Berikut adalah beberapa kemungkinan yang saya perhatikan yang tidak berhasil:

  • Memuat entitas dengan entity_load(), mengatur entri bidang ke = null atau = array (), lalu menyimpan dengan field_attach_update(). Ini yang paling dekat yang saya temukan tetapi meninggalkan entri bidang nol zombie di database yang muncul sebagai baris kosong pada formulir sampai formulir disimpan dan hook_field_is_empty()dapat menendang ( hook_field_is_empty()dikonfigurasi sehingga = null atau = array () akan menandai kosong).
  • Memuat entitas dengan entity_load(), membuka kunci entri bidang dengan kunci, lalu menyimpan dengan field_attach_update(). Ini sepertinya tidak melakukan apa-apa - tampaknya Drupal menginterpretasikan entri yang tidak ada di sana sebagai tanda untuk tidak memodifikasinya. (Anehnya, saya juga terkadang mendapatkan batas waktu kedaluwarsa waktu permintaan maksimum saat mencoba pendekatan ini)
  • field_attach_delete() - ini terlalu tumpul: ini membunuh semua bidang untuk entitas
  • field_purge_data() - lebih baik, tetapi masih terlalu tumpul: itu membunuh semua entri bidang, bukan entri tertentu

Jadi untuk memperjelas, saya punya kode yang menemukan (dan memuat) entitas yang memiliki bidang yang memiliki banyak entri, dan menemukan entri khusus pada bidang itu yang perlu dihapus. Saya ingin menghapus entri itu sepenuhnya, tanpa menyentuh entri lain atau bidang lain pada entitas.

Jawaban:


24

Jika Anda dapat mengandalkan modul entitas API Anda harus dapat menggunakan kode yang mirip dengan yang berikut:

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

2
Ini berhasil! Terima kasih, masalah zombie saya sekarang telah terkikis. Beberapa catatan yang mungkin menghemat waktu orang lain: Saya perlu memperbarui entitas api ke RC2; karena saya menggunakan nama bidang dinamis, baris tidak disetel memerlukan kawat gigi seperti tidak disetel ($ entitas -> {$ field_name} [LANGUAGE_NONE] [$ index]); dan untuk menghindari peringatan saya perlu membungkus array_values ​​() di if (! empty (...)) {}
user56reinstatemonica8

Ini juga berfungsi jika Anda hanya ingin menghapus seluruh bidang, dan menghindari "Pelanggaran batasan integritas yang ditakuti: 1048 Kolom 'field_duty_user_target_id' tidak boleh nol"
Darrell Duane

Terima kasih banyak! mencoba mengubah nilai bidang melalui node_load, tetapi tidak berhasil. Jadi mengubah nilai bidang entitas seperti ini pasti berhasil!
Артем Ильин

1

Saya perlu melakukan ini sebagai bagian dari pembersihan migrasi Drupal8.

Setelah beberapa percobaan, saya menemukan bahwa iterasi dan kemudian menggunakan unset () pada delta dapat membunuhnya. Contoh saya menghapus tag (karenanya saya mencari 'target_id', bukan 'nilai' seperti yang sering Anda lakukan untuk bidang lain.

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

Dan sesudahnya, jika sukses, maka $object->save();


0

Untuk Drupal 8, untuk menghapus bidang dari suatu entitas:

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

Ini akan memanggil metode ajaib __unset () dari ContentEntityBase:

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

Jangan lupa bahwa, untuk bertahan pada perubahan Anda, Anda perlu menelepon

$entity->save();

Setelah Anda melakukan semua perubahan Anda.


-1

Ini cara yang lebih baik:

> $user = user_load($user->uid); 
> $user_wrp = entity_metadata_wrapper('user', $user);
> $user_wrp->{'field_data_multiple'} = array();

-2

metode yang disukai saat ini akan menggunakan entitas_metadata_wrapper

$node_wrapped = entity_metadata_wrapper('node', node_load($nid));

unset($node_wrapped->$field_name[$index];

ini adalah tutorial terbaik tentang EMW yang pernah saya lihat di http://deeson-online.co.uk/labs/programatically-access-field-data-using-entitymetadatawrapper-drupal


ini tidak berhasil. Saya bahkan mencobanya seperti ini tanpa hasil; $ wrapper = entity_metadata_wrapper ('node', $ duty); unset ($ wrapper-> field_duty_user); $ wrapper-> save (); node_save ($ duty);
Darrell Duane

1
Cara yang benar adalah $ node_wrapped-> field_name-> set (""); lalu $ wrapper-> save ()
chadpeppers
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.