Versi Drupal: 7.21
Versi modul koleksi lapangan: 7.x-1.0-beta5
Penjelasan singkat : Saya sibuk mencoba mengimpor koleksi lapangan secara terprogram tetapi ketika menghapus beberapa dari mereka selalu ada beberapa koleksi bidang 'palsu' yang tersisa.
Penjelasan panjang : Pengguna saya memiliki bidang koleksi bidang di profil mereka. Koleksi bidang ini berisi 3 bidang teks. Saya ingin mengimpor data dari database sql khusus ke dalam kumpulan bidang pengguna. Koleksi bidang ini dapat memiliki beberapa nilai. Saat saya mengimpor data untuk pertama kalinya semuanya berfungsi dengan baik, saya melihat data di bidang kumpulan bidang. Bagus.
Tapi inilah bagian yang sulit. Katakanlah saya mengimpor untuk satu pengguna tertentu 5 baris dari database khusus. Mereka ditambahkan ke koleksi bidang, jadi koleksi bidang ini memiliki 5 item masing-masing berisi 3 bidang. Lalu saya menghapus beberapa baris dari basis data khusus saya sehingga saya hanya memiliki 3 baris tersisa untuk pengguna ini. Saya menjalankan impor lagi, memperbarui 3 item pertama dari koleksi bidang, tapi kemudian saya pergi dengan 2 item dari impor sebelumnya. Mereka harus dihapus karena saya hanya memiliki 3 baris yang diimpor tetapi masih 5 item koleksi lapangan.
Jadi saya mencoba menghapus item kumpulan bidang ini, tetapi selalu ada satu atau lebih item yang tersisa. Kolom kosong ketika saya melihat profil pengguna tetapi masih ada sesuatu di sana. Katakanlah pada titik ini saya menambahkan 5 baris baru untuk pengguna di basis data khusus saya, jadi saya memiliki total 8 baris untuk pengguna ini. Lalu saya menjalankan impor lagi. 3 item pertama diperbarui, tetapi kemudian ketika saya mencoba menambahkan baris ke-4 ia masih mendapatkan id entitas dari item koleksi bidang ke-4, mencoba untuk memperbaruinya tetapi gagal dan mengembalikan kesalahan ini:
Fatal error: Call to undefined method stdClass::save()
Saya mencoba menghapus item kumpulan bidang dengan masing-masing metode berikut:
// Method 1
entity_delete_multiple('field_collection_item', array($fc_id));
// Method 2
$field_collection_item = field_collection_item_load($fc_id);
$field_collection_item->delete();
// Method 3
$field_collection_item = field_collection_item_load($fc_id);
$field_collection_item->deleteRevision();
Ini kode lengkap saya:
function import_user_field_collection(&$user, $old_user_id) {
// I do a query to get the rows I want to import for this specific user.
db_set_active('custom_sql_database');
$result = db_query("SELECT * FROM {users} WHERE user_id = :user_id", array(':user_id' => $old_user_id));
db_set_active('default');
$i = 0; // Keep count of how many rows I imported.
foreach($result as $row) {
// Check if the field collection item already exists.
if(!empty($user->field_profile_diploma_opleiding[LANGUAGE_NONE][$i]['value'])) {
// If it does exists, update this particular field collection item.
$fc_id = $user->field_profile_diploma_opleiding[LANGUAGE_NONE][$i]['value'];
$field_collection_item = entity_load('field_collection_item', array($fc_id));
// These 3 text fields are children of the field collection field.
$field_collection_item[$fc_id]->field_profile_diploma_instituut[LANGUAGE_NONE][0]['value'] = $row->instituut;
$field_collection_item[$fc_id]->field_profile_diploma_vakgebied[LANGUAGE_NONE][0]['value'] = $row->vakgebied;
$field_collection_item[$fc_id]->field_profile_diploma_jaar[LANGUAGE_NONE][0]['value'] = $row->jaar_diploma;
$field_collection_item[$fc_id]->save(TRUE);
} else {
// If the field collection item doesn't exist I want to create a new field collection item.
$field_collection_item = entity_create('field_collection_item', array('field_name' => 'field_profile_diploma_opleiding'));
$field_collection_item->setHostEntity('user', $user);
$field_collection_item->field_profile_diploma_instituut[LANGUAGE_NONE][0]['value'] = $row->instituut;
$field_collection_item->field_profile_diploma_vakgebied[LANGUAGE_NONE][0]['value'] = $row->vakgebied;
$field_collection_item->field_profile_diploma_jaar[LANGUAGE_NONE][0]['value'] = $row->jaar_diploma;
$field_collection_item->save(TRUE);
}
$i++;
}
$fc_fields = field_get_items('user', $user, 'field_profile_diploma_opleiding');
// Check if there are more field collection items than imported rows
if(count($fc_fields) > $i) {
for($i; $i <= count($fc_fields); $i++) {
// Run through each field collection item that's left from the previous import and delete it.
if(!empty($user->field_profile_diploma_opleiding[LANGUAGE_NONE][$i]['value'])) {
// Method 1
$fc_id = $user->field_profile_diploma_opleiding[LANGUAGE_NONE][$i]['value'];
entity_delete_multiple('field_collection_item', array($fc_id));
// Method 2
//$field_collection_item = field_collection_item_load($fc_id);
//$field_collection_item->delete();
// Method 3
//$field_collection_item = field_collection_item_load($fc_id);
//$field_collection_item->deleteRevision();
}
}
}
}
Jadi pertanyaan saya adalah: Bagaimana cara saya menghapus item koleksi kolom sehingga mereka benar-benar hilang?
entity_delete_multiple
adalah 100% jelas cara yang tepat untuk melakukannya - lihatfield_collection_field_delete
fungsinya, yang digunakan oleh Field Collection untuk membersihkan item ketika bidang yang direferensikan dihapusentity_delete_multiple()
. Anda mungkin perlu menjalankan cron beberapa kali setelah Anda menghapus bidang (data bidang dibersihkan pada jadwal agar tidak membebani satu halaman memuat dengan semua pemrosesan yang harus dilakukan)Jawaban:
Saya mengalami kasus penggunaan serupa di mana saya ingin memetakan beberapa data ke dalam kumpulan bidang selama hook_feeds_presave () karena struktur sumber terlalu kompleks untuk Feed. Saya menemukan entitas_delete_multiple () menghapus item koleksi lapangan, tetapi ketika saya mengedit node, masih ada banyak kumpulan field kosong di sana. Mengecek dan menghapus berhasil, yang saya temukan di sini: https://drupal.stackexchange.com/a/31820/2762
Jika sumber umpan telah berubah, saya menghapus semua item koleksi bidang dan membuat ulang. Semoga ini bermanfaat.
sumber
node_save($node)
simpul Anda.node_save($node)
,DrupalEntityController
akan melakukan pekerjaan iniCara terbaik untuk melakukan ini sekarang adalah panggilan
$field_collection->delete()
dan itu akan menangani semuanya.sumber
Jawaban di atas bukanlah cara terbaik, dengan menghapus semua item lainnya menghilang dari koleksi bidang, dan cara lain dengan
->delete()
melempar bug dengan modul Entity.Jalan yang benar. Yang saya lakukan adalah ini:
Dalam kasus saya, saya ingin menghapus item terakhir dalam koleksi bidang
lihat kode ini, (untuk pemula: "ingat bahwa Anda harus sudah memiliki $ entitas")
itu saja! cara lainnya adalah
Cara di atas baik menggunakan
entity_metadata_wrapper
fungsi tetapi dengan cara itu ada bug kompleks yang saya tidak tahu bagaimana menyelesaikannya, Anda dapat memeriksanya di https://drupal.org/node/1880312 dan setelah menerapkan tambalan di # 9 Anda mendapatkan masalah berikutnya, periksa di sini https://drupal.org/node/2186689 bug ini juga jika Anda menggunakan->delete()
fungsi.Semoga ini bisa membantu seseorang.
sumber
menggunakan vbo untuk menghapus item koleksi bidang. itu akan otomatis menghapus relasi bidang dengan entitas host item koleksi bidang.
sumber
Saya memiliki masalah serupa, di mana saya mengimpor data dari umpan ke item FC. Ketika pembaruan ke entitas host dibuat dari umpan, dan saya mengimpor perubahan itu, saya ingin memastikan bahwa setiap item FC yang ada yang tidak lagi ada dari sumber umpan dihapus.
Solusi saya:
Dan itu saja. Hook_field_update Field Collection (
field_collection_field_update
) akan benar-benar menghapus semua item FC yang ada yang telah di-referensikan.Satu-satunya downside ke ini adalah jika tidak ada perubahan dalam data FC, itu tetap dihapus dan dibuat kembali. Tapi itu bukan masalah besar bagi saya.
sumber