Bagaimana saya bisa menghapus item dari daftar nilai yang diizinkan dari bidang pilih yang memiliki data untuk nilai-nilai itu?

16

Saya telah membuat tipe konten yang memiliki bidang opsi daftar / pilih, dan saya telah memasukkan pasangan kunci nilai yang diperlukan untuk daftar pilih berfungsi.

Data telah dimasukkan, dan diputuskan bahwa istilah-istilah tertentu tidak lagi berlaku dan harus dihapus.

Namun, ketika mencoba menghapus istilah tersebut, saya mendapatkan kesalahan berikut:

Allowed values list: some values are being removed while currently in use.

Jelas, dalam kehidupan proyek, nilai-nilai akan berubah. Apa cara praktis untuk menghapus item setelah simpul dikaitkan dengan persyaratan yang tercantum?

Ini tentang hal terdekat yang bisa saya temukan:

https://drupal.org/node/1653012

Itu referensi plugin d6 dan beberapa tipu daya patch saya lebih suka tidak harus menggunakan. Jika saya benar-benar terpaksa menggunakan tambalan untuk menghapus pemeriksaan validasi pada bidang itu, apakah ada salahnya membiarkan barang-barang itu menjadi yatim pada simpul yang terkait dengan mereka?

Pembaruan, saya telah membahas masalah ini lagi dengan klien pemerintah yang, selama 7 tahun terakhir memiliki situs Drupal telah memiliki 50 negara bagian dan teritori dalam daftar pilih. Sekarang, kebijakan telah berubah dan wilayah tidak lagi perlu dimasukkan. Mampu menghapus item dari daftar pilih adalah penting, dan karenanya saya menawarkan hadiah.

Saya mencari solusi yang aman untuk dapat menghapus item dari daftar pilih. Apa yang saya tidak tahu adalah apakah solusi itu harus memperbarui salah satu node karena saya tidak yakin bagaimana nilai-nilai bidang disimpan dalam kaitannya dengan konten total node.

Saya senang dengan solusi SQL murni untuk dijalankan di MySQL; atau, saya sedang mencari modul.

blue928
sumber
3
Jelas, dalam kehidupan proyek, nilai-nilai akan berubah. Saya akan membantah bahwa - nilai-nilai untuk daftar pilih statis harus ditentukan pada awal proyek. Jika Anda perlu fleksibel, Anda harus menggunakan referensi istilah daripada daftar statis. Daftar statis adalah untuk hal-hal seperti seks (pria / wanita) yang, kecuali kita memiliki perubahan serius dalam hal-hal, tidak mungkin berubah dalam waktu dekat. Dan jika ya, itu akan ditambahkan , tidak dihapus . Setiap kali saya membuat 'kesalahan' ini, saya selalu menemukan cara terbaik untuk mundur adalah dengan menjalankan kueri manual pada data
Clive
1
Apakah Anda ingin menjadikan daftar ini dinamis? menjadi dinamis dalam penciptaan dan penghapusan.
M ama D
1
Ya saya kira itu hanya karena pendapat kemudian - produsen mobil akan selalu menjadi tipe simpul atau kosa kata untuk situs apa pun yang akan saya bangun. Karena pabrikan adalah kategori mobil (atau kategori mobil yang diperbaiki seseorang), masuk akal sebagai taksonomi bagi saya daripada tipe konten. Tapi saya tahu itu tidak membantu ... Saya akan berhati-hati meninggalkan data anak yatim di DB, sangat sulit untuk mengatakan apa efek yang bisa terjadi tanpa mengetahui persis apa yang diinstal di situs Anda dan bagaimana hal itu dikonfigurasi
Clive
1
Apa yang salah dengan views_bulk_operations?
donquixote
1
heh, belum ada jawaban yang memiliki
upvote

Jawaban:

7

Saya melakukan sesuatu seperti ini baru-baru ini dengan pendekatan berikut.

  1. Tambahkan nilai yang diizinkan baru.
  2. Tambahkan pengaturan untuk mengonfigurasi nilai "aktif".
  3. Memfilter nilai "tidak aktif" dari tampilan di formulir.

misalnya:

/**
 * Admin settings form
 */
function MODULE_admin_settings(){

  $form = array();

  // Select active preferences for display
  $field = field_info_field('field_preferences');
  $preferences = list_allowed_values($field);
  $form['field_preferences_active'] = array(
    '#type' => 'checkboxes',
    '#title' => t('Active preferences'),
    '#options' => $preferences,
    '#description' => t('Select the preferences available for user selection.'),
    '#default_value' => variable_get('field_preferences_active', array()),
  );

  return system_settings_form($form);

}

/**
 * Implements hook_field_attach_form
 */
function MODULE_field_attach_form($entity_type, $entity, &$form, &$form_state, $langcode) {

  // Filter out inactive preferences
  if(isset($form['field_preferences'])){
    $preferences = variable_get('field_preferences_active', array());
    foreach($preferences as $key => $preference){
      // If this preference isn't checked, but is set in the field values, unset it.
      if(empty($preference) && isset($form['field_preferences'][LANGUAGE_NONE]['#options'][$key])){
        unset($form['field_preferences'][LANGUAGE_NONE]['#options'][$key]);
      }
    }
  }

}

Dengan cara ini data lawas disimpan untuk referensi, formulir divalidasi, dan integritas data utuh.

David Thomas
sumber
1
Opsi ini pada dasarnya non-destruktif (yaitu, menyembunyikan barang daripada menghapus), dan mungkin merupakan titik awal terbaik sampai Anda dapat menentukan tindakan terbaik untuk bagaimana menangani entitas apa pun yang memiliki opsi yang ketinggalan zaman.
mpdonadio
3

Seperti yang saya tahu, semua data bidang disimpan dalam 2 tabel: field_data_field_FIELDNAME dan field_revision_field_FIELDNAME. Dan saya menemukan konfirmasi pemikiran saya di sini: /programming//a/7773117/1300562

Jadi untuk menghapus nilai bidang yang tidak perlu, Anda perlu menghapus nilai-nilai ini dari tabel yang disebutkan di atas dan kemudian menghapusnya dari daftar nilai yang diizinkan.

Langkah 1.

$values_to_remove = array('value1', 'value2'); // an array of unnecessary values
$fieldname = 'FIELDNAME'; // name of your field. For example,
                          // 'territory' for field with machine name 'field_territory'
$entity_type = 'node'; // it's 'node' in your case, but it can be 'taxonomy_term' or something else

db_delete('field_data_field_' . $fieldname)
  ->condition('entity_type', $entity_type)
  ->condition('field_' . $fieldname . '_value', $values_to_remove)
  ->execute();

db_delete('field_revision_field_' . $fieldname)
  ->condition('entity_type', $entity_type)
  ->condition('field_' . $fieldname . '_value', $values_to_remove)
  ->execute();

Langkah 2.
Hapus pasangan kunci yang tidak perlu | nilai pada halaman pengaturan bidang dan kirim formulir untuk menyimpan perubahan.
Tembolok harus dihapus secara otomatis setelah itu, tetapi jika Anda masih bisa melihat nilai bidang yang dihapus pada halaman simpul, bersihkan cache secara manual.

PS Baru-baru ini saya dihadapkan dengan masalah yang sama, dan sekarang saya lebih suka menggunakan bidang tipe "Referensi jangka" atau (bahkan lebih baik) "Referensi entitas" daripada daftar nilai teks. Saat menggunakan bidang referensi, Anda dapat membuat kosakata terpisah untuk setiap bidang dan cukup membuat / mengedit / menghapus istilah kapan saja.

kutipanBro
sumber
Jika bidang berulang, maka kueri itu tidak akan menyesuaikan delta untuk data yang tersisa.
mpdonadio
1

Pertama-tama periksa apakah Anda memiliki nilai yang diizinkan ditentukan di bidang? Jika Anda melakukannya, maka opsi lain tidak akan divalidasi. Jadi cobalah untuk menghapus nilai dari tab Pengaturan Lapangan terlebih dahulu.

Atau Anda memiliki 2 opsi:


1.

Hapus semua nilai yang Anda masukkan ke dalam daftar nilai yang diizinkan yang sedang digunakan oleh akun pengguna. Misalnya, Anda dapat menjalankan kueri SQL untuk menemukan ini:

SELECT * FROM field_data_field_MYFIELDNAME WHERE entity_type = 'user' and value = 'MY VALUE'

atau buat tampilan pengguna yang menunjukkan kepada Anda akun pengguna apa yang memiliki nilai yang ingin Anda hapus dari daftar nilai yang diizinkan.


2.

Jika Anda tidak ingin menghapus nilai dari bidang, ini dapat dicapai dengan meretas.

Peringatan, ini bukan solusi yang disarankan untuk produksi dan Anda harus tahu apa yang Anda lakukan!

  1. Temukan dan edit modul / bidang / bidang.module
  2. Temukan fungsi field_has_data () dan tambahkan return TRUE;fungsi baris pertama.

    function field_has_data($field) {
      return FALSE; // HACK !!!
      $query = new EntityFieldQuery();
  3. Simpan ulang bidang dengan nilai yang Anda inginkan.
  4. Hapus retasan segera setelah Anda melakukannya.
kenorb
sumber
0

Saya pikir Anda benar-benar dapat melakukan ini dengan menggunakan modul Operasi Massal Views .

  1. tambahkan opsi baru pada bidang yang ingin Anda ganti. misalnya: na | NA
  2. buat tampilan ke daftar node berisi dengan bidang itu
  3. tambahkan bidang "Operasi massal: Konten" pada tampilan itu
  4. centang "Ubah nilai entitas" dan "tampilkan token yang tersedia" (pilih Semua pada nilai tampilan)
  5. Tambahkan bidang yang ingin Anda ubah pada Kriteria Filter dan "buka" filter itu
  6. setel Path url pada Tampilan itu
  7. Buka halaman tampilan itu dan ubah
  8. Sekarang, gunakan fitur eksposur dan operasi untuk mengubah opsi bidang
  9. Selesai
CocoSkin
sumber
0

Inilah perbaikan untuk jawaban HL yang menurut saya adalah yang terbaik:

Singkatnya, Anda perlu menetapkan nilai baru untuk konten yang memiliki nilai "lama" yang ditetapkan untuk bidang pilihan Anda.

Terlepas dari Operasi Massal Views , Anda perlu menginstal dan mengaktifkan modul Administrasi Views . Dengan modul ini, Anda sudah memiliki tampilan out-of-the-box dengan operasi massal diaktifkan (lihat admin / konten sekali diaktifkan). Kemudian:

1) Buka admin / struktur / tampilan edit "Administrasi: Node" tampilan

2) Tambahkan tampilan halaman baru untuk tampilan menggunakan tombol "Tambah -> Halaman" di atas

3) Tetapkan jalur ke tampilan baru: Contoh admin / konten / custom

4) Tambahkan filter baru untuk bidang pilihan Anda: Pilih operator "adalah salah satu" lalu pilih semua opsi yang ingin Anda hapus

5) Simpan tampilan

6) Pergi ke admin / konten / kustom Sekarang Anda melihat semua konten yang perlu Anda sunting secara massal (ubah nilai untuk bidang pilihan Anda)

7) Pilih semua baris dengan mengklik kotak centang pertama di sebelah kiri tabel (jika ada lebih dari satu halaman, juga pilih tombol yang akan mengatakan "Pilih semua baris X dalam tampilan ini")

8) Pilih operasi "ubah nilai" dan tekan "Jalankan"

9) Untuk bidang pilih Anda, pilih nilai baru untuk menimpa yang ingin Anda hapus

10) Pilih kotak centang untuk bidang pilih itu

11) Klik Next dan Anda selesai

Roger
sumber
0

Sepertinya masalah Drupal Anda didasarkan pada masalah data yang lebih dalam: Apa yang terjadi pada entitas yang saat ini menggunakan nilai daftar yang disusutkan? Pertanyaan ini adalah akar dari pesan kesalahan yang dikirimkan Drupal kepada Anda.

Mari kita lihat lebih dekat contoh negara bagian / teritori Anda. Klien Anda telah menggunakan sistem yang memperlakukan negara bagian dan teritori dengan cara yang sama selama bertahun-tahun dan telah membangun sekelompok besar simpul yang berisi negara bagian dan teritori. Kemudian suatu hari, kekuasaan yang memutuskan bahwa wilayah perlu ditangani secara berbeda dan bahwa drop-down untuk menetapkan wilayah tidak boleh lagi berisi wilayah. Bagus. Cukup buat tampilan yang menggunakan filter standar untuk membuat daftar semua node wilayah dan gunakan Operasi Massal Tampilan untuk mengubah semua nilai wilayah mereka menjadi ... apa ... beberapa negara ke-51 yang disebut lainnya mungkin? Nasib wilayah adalah pertanyaan yang sangat serius. Solusi Anda harus mencakup metode untuk melestarikan atau memindahkan status wilayah. Anda mungkin perlu membuat bidang daftar baru yang disebut 'Wilayah'

Anda perlu menggunakan Aturan dengan Operasi Massal Lihat untuk melakukan perubahan ini. Jika Anda tidak tahu banyak tentang aturan, silakan luangkan waktu untuk mempelajari cara kerjanya. Aturan memberi Anda kemampuan untuk memanipulasi informasi berdasarkan pemicu, kondisi, dan tindakan. Setelah mempelajari tentang aturan, Anda mungkin menemukan bahwa jawaban yang Anda cari akan muncul dengan sendirinya. Pada dasarnya, Anda perlu membuat aturan, yang dipicu oleh Operasi Massal, yang akan menargetkan semua wilayah dan menghapus, menetapkan kembali, mengganti nama atau memisahkannya dari bagian utama informasi. Peraturan harus dapat menyimpan status wilayah dengan beberapa cara sementara pada saat yang sama, mengatur status dropdown ke status 'lain' atau 'N / A'. Ini mungkin yang dibutuhkan. Jika tidak...

Setelah pengalihan tugas dilakukan, itu harus menjadi operasi sederhana untuk mengubah bidang daftar asli dan menghapus nama wilayah. Namun, jika sistem masih tidak memungkinkan Anda untuk mengubah daftar, Anda mungkin perlu membuat bidang daftar baru, kemudian gunakan Operasi dan Aturan Massal Tampilan untuk meninjau semua nilai keadaan saat ini dan menugaskan mereka kembali ke daftar baru. Aturan dapat bekerja dengan Operasi Massal Views untuk menargetkan semua node yang relevan dan menindaklanjutinya berdasarkan nilai-nilai bidang. Menetapkan nilai bidang daftar baru berdasarkan nilai bidang daftar yang ada untuk sekelompok node mudah ketika Anda menggunakan Aturan.

Juga ingat, jika Drupal memberi Anda masalah dengan operasi, selalu siram cache sebelum mempertimbangkan alternatif yang sulit.

Hoytman
sumber
0

Saya menganggap klien Anda menginginkan konten lawas untuk mempertahankan nilai aslinya, yang berarti mengubah daftar pilih akan secara efektif menghancurkan data sebelumnya. Jika itu bukan masalah, maka jawaban yang lain mungkin akan berhasil. Namun jika demikian, Anda tidak dapat benar-benar mengubah daftar pilih tanpa kehilangan riwayat data itu. Saya mungkin pergi dengan rute yang lebih sederhana, untuk memungkinkan data historis, sementara membuat situs sedikit lebih tahan di masa depan - Saya sarankan menggunakan izin lapangan:

* mengatur bidang baru untuk daftar pilih itu menggunakan taksonomi alih-alih data statis

* atur izin bidang untuk daftar pilih yang ada sebagai LIHAT, tetapi bukan EDIT oleh siapa pun kecuali admin

Dengan ini, bidang lama harus tetap dapat dilihat dan dicari (tambahkan judul baru yang mencerminkannya sebagai warisan saja) tetapi tidak dapat diedit. Ini tentu saja sangat bergantung pada pencarian kustom, tampilan, dll yang mungkin perlu disesuaikan.

Saya menyarankan ini (serapik mungkin kedengarannya) karena menghapus data itu, menghapus histori, dan yang akhirnya bisa menghancurkan dalam jangka panjang. Anda bahkan dapat menggunakan css untuk menyembunyikan bidang lama di simpul edit, dan sebuah kait untuk menyembunyikannya untuk konten baru (di mana ia tidak memiliki nilai yang ditetapkan). Dengan cara ini, itu hanya akan ditampilkan untuk konten lawas itu.

Tentu saja, Anda kemudian dapat mengambil langkah lebih jauh dengan modul satu kali kustom untuk menyalin data dari daftar pilih lama ke taksonomi baru.

Geoff
sumber
0

Script drush sederhana untuk menyelamatkan! Kami memperbarui data bidang dan tabel revisi bidang dan mengganti nilai lama dengan yang baru sebelum mengubah pengaturan bidang secara manual.

Jika kami memiliki sesuatu seperti ini di pengaturan bidang kami saat ini:

&date=today|today
&date=last2days|last2days

dan ingin menggantinya dengan yang berikut:

date=today|today
date=last2days|last2days

Kami menjalankan skrip drush terlebih dahulu dan kemudian mengubah pengaturan bidang di UI admin.

Catatan: Kode ini untuk bidang dengan nama mesin field_foo_bar.

    $field_name = 'foo_bar';

    print "for {$field_name}...\n";

    replace_field("&date=today", "date=today", $field_name);

    replace_field("&date=last2days", "date=last2days", $field_name);

    function replace_field($old_value, $new_value, $field_name, $entity_type='node') {
      print "Replacing {$old_value} with {$new_value}...\n";
      $data_count = replace_options_data_field($field_name, $entity_type, $old_value, $new_value);
      $revision_count = replace_options_revision_field($field_name, $entity_type, $old_value, $new_value);
      print $data_count + $revision_count . " entries replaced.\n";
    }

    function replace_options_data_field($field_name, $entity_type, $old_value, $new_value) {
      $num_updated = db_update('field_data_field_' . $field_name)
        ->fields(array(
                   'field_' . $field_name . '_value' => $new_value,
                 ))
        ->condition('entity_type', $entity_type)
        ->condition('field_' . $field_name . '_value', $old_value)
        ->execute();
      return $num_updated;
    }

function replace_options_revision_field($field_name, $entity_type, $old_value, $new_value) {
  $num_updated = db_update('field_revision_field_' . $field_name)
    ->fields(array(
               'field_' . $field_name . '_value' => $new_value,
             ))
    ->condition('entity_type', $entity_type)
    ->condition('field_' . $field_name . '_value', $old_value)
    ->execute();
  return $num_updated;
}
Badri
sumber
0

Saya menggunakan saran ke-2 Kenorb dan bekerja untuk memperbarui daftar nilai dalam bidang Drupal 7.52, Profile2 7.x-1.3. Jadi, jika Anda mendapatkan peringatan drupal: "Daftar nilai yang diizinkan: beberapa nilai sedang dihapus saat sedang digunakan." Berikut ini memungkinkan saya untuk menghapus nilai dari bidang (profil2), tanpa menghapus atau mengganti mereka dalam database.

Di direktori root Drupal core, ada folder bernama modules, dan file yang akan diedit terletak di: modules / field / field.module. INI ADALAH FILE INTI, Anda harus benar-benar mengembalikan perubahan saat selesai memperbarui nilai. Saya mengambil situs secara offline, untuk sementara waktu mengganti kode berikut di dalam (drupal root) /modules/field/field.module

function field_has_data($field) {
  $query = new EntityFieldQuery();
  $query = $query->fieldCondition($field)
    ->range(0, 1)
    ->count()
    // Neutralize the 'entity_field_access' query tag added by
    // field_sql_storage_field_storage_query(). The result cannot depend on the
    // access grants of the current user.
    ->addTag('DANGEROUS_ACCESS_CHECK_OPT_OUT');

  return (bool) $query
    ->execute() || (bool) $query
    ->age(FIELD_LOAD_REVISION)
    ->execute();
}

DENGAN PERSIS

function field_has_data($field) { 
    return FALSE; // hack 
    $query = new EntityFieldQuery();
}

Dan drupal berhenti mengeluh dan saya dapat mengubah daftar. (Dalam kasus saya, ini adalah fakultas dalam daftar nilai-nilai yang telah meninggalkan universitas, tetapi masih terkait dengan catatan siswa, sebagai penasihat, pembimbing, dll.)

Michael Martelle
sumber