Değerler için veri içeren bir seçim alanının izin verilen değerler listesinden öğeleri nasıl kaldırabilirim?


16

Liste / seçim seçenek alanına sahip bir içerik türü oluşturdum ve seçim listesinin çalışması için gerekli anahtar | değer çiftlerini girdim.

Veriler girildi ve bazı terimlerin artık geçerli olmadığına ve silinmeleri gerektiğine karar verildi.

Ancak, belirtilen terimleri kaldırmaya çalışırken, aşağıdaki hatayı alıyorum:

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

Açıkçası, bir projenin yaşamında, değerler değişecektir. Düğümler listelenen terimlerle ilişkilendirildikten sonra öğeleri kaldırmanın pratik yolu nedir?

Bu, bulabildiğim en yakın şeyle ilgili:

https://drupal.org/node/1653012

Bir d6 eklentisi ve başvurmak istemem bazı yama hile referans. Sonunda o alandaki doğrulama denetimini kaldırmak için düzeltme ekini kullanmaya başvurmam gerekiyorsa, bu öğeleri ilişkili oldukları düğümlere yetim bırakmada herhangi bir zarar var mı?

Güncelleme, bir Drupal sitesine sahip olmanın son 7 yıldır 50 eyalet ve bölgeyi seçilmiş bir listeye sahip olan bir hükümet müşterisi ile tekrar bu konuyla karşılaştım. Artık politika değişti ve artık bölgelerin dahil edilmesi gerekmiyor. Seçme listelerinden öğeleri kaldırabilmeniz önemlidir ve bu yüzden bir ödül teklif ediyorum.

Öğeleri bir seçim listesinden kaldırabilmek için güvenli bir çözüm arıyorum. Ne bilmiyorum bu çözüm düğümlerin toplam içeriği ile ilgili olarak depolanan alan değerleri nasıl emin değilim olarak herhangi bir düğüm güncelleme gerekir.

MySQL'de çalışmak için saf bir SQL çözümü ile mutluyum; veya bir modül arıyorum.


3
Açıkçası, bir projenin yaşamında, değerler değişecektir. Ben - statik bir seçim listesi için değerler projenin başında tanımlanması gerektiğini itiraz ediyorum. Esnek olması gerekiyorsa, statik liste yerine bir terim başvurusu kullanmalısınız. Statik listeler, seks (erkek / kadın) gibi şeylere yöneliktir; bu, şeylerde ciddi bir değişiklik yapmazsak, yakında değişmeyecektir. Ve eğer öyleyse, kaldırılmaz , eklenecektir . Ne zaman bu 'hata' yaptığım zaman her zaman en iyi yolu buldum veri manuel sorguları çalıştırmaktır
Clive

1
Bu listeyi dinamik hale getirmek istiyor musunuz? yaratma ve silme konusunda dinamik olmak.
M ama D

1
Evet, sanırım bu sadece o zaman - otomobil üreticisi inşa edeceğim herhangi bir site için her zaman bir düğüm tipi veya kelime bilgisi olurdu. Üretici bir araba kategorisi (veya birinin tamir ettiği bir araba kategorisi) olduğundan, bir içerik türü yerine benim için bir sınıflandırma olarak mantıklı geliyor. Ama bunun yardımcı olmadığını biliyorum ... DB'de yetim veri bırakmaktan kaçınırım, sitenizde tam olarak neyin yüklü olduğunu ve nasıl yapılandırıldığını bilmeden hangi etkinin olabileceğini söylemek çok zor
Clive

1
Views_bulk_operations ile ilgili sorun nedir?
donquixote

1
heh, bu cevapların hiçbirinin henüz oyu yok: /
tenken

Yanıtlar:


7

Son zamanlarda aşağıdaki yaklaşımla böyle bir şey yaptım.

  1. İzin verilen yeni değerleri ekleyin.
  2. "Etkin" değerleri yapılandırmak için bir ayar ekleyin.
  3. Formda görüntülenen "etkin olmayan" değerleri filtreleyin.

Örneğin:

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

}

Bu şekilde eski veriler referans olarak korunur, form doğrulanır ve veri bütünlüğü bozulmaz.


1
Bu seçenek esasen yapıcı değildir (yani, silmek yerine bir şeyleri gizle) ve eski seçeneklere sahip varlıklarla nasıl başa çıkılacağına ilişkin en iyi hareket yolunu belirleyene kadar muhtemelen en iyi başlangıç ​​noktasıdır.
mpdonadio

3

Bildiğim gibi, tüm alan verileri 2 tabloda saklanır: field_data_field_FIELDNAME ve field_revision_field_FIELDNAME. Düşüncemin onayını burada buldum: /programming//a/7773117/1300562

Bu nedenle, gereksiz alan değerlerini kaldırmak için bu değerleri yukarıda belirtilen tablolardan silmeniz ve sonra bunları izin verilen değerler listesinden kaldırmanız gerekir.

Aşama 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();

Adım 2.
Alan ayarları sayfasındaki gereksiz anahtar | değer çiftlerini kaldırın ve değişiklikleri kaydetmek için formu gönderin.
Bundan sonra önbellek otomatik olarak temizlenmelidir, ancak düğüm sayfalarında kaldırılan alan değerlerini hala görebiliyorsanız, önbelleği manuel olarak temizleyin.

PS Son zamanlarda benzer bir sorunla karşı karşıya kaldım ve şimdi metin değerleri listesi yerine "Terim referansı" veya (hatta daha iyi) "Varlık referansı" türündeki alanları kullanmayı tercih ediyorum. Referans alanını kullanırken, her alan için ayrı kelimeler oluşturabilir ve istediğiniz zaman terimler oluşturabilir / düzenleyebilirsiniz / silebilirsiniz.


Alan tekrarlanıyorsa, bu sorgular kalan veriler için deltaları ayarlamaz.
mpdonadio

1

Öncelikle, alanda izin verilen değer olup olmadığını kontrol edin. Bunu yaparsanız, başka bir seçenek doğrulanmaz. Bu yüzden önce Alan Ayarları sekmesinden değerleri kaldırmayı deneyin.

Alternatif olarak 2 seçeneğiniz vardır:


1.

Kullanıcı hesapları tarafından kullanılmakta olan izin verilen değerler listesine koyduğunuz tüm değerleri kaldırın. Örneğin, bunları bulmak için bir SQL sorgusu çalıştırabilirsiniz:

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

veya hangi kullanıcı hesaplarının izin verilen değerler listesinden kaldırmak istediğiniz değere sahip olduğunu gösteren bir kullanıcı görünümü oluşturun.


2.

Alanlardan değerleri kaldırmak istemiyorsanız, bu saldırı hack yoluyla gerçekleştirilebilir.

Uyarı, bu üretim için önerilen bir çözüm değildir ve ne yaptığınızı bilmelisiniz!

  1. Modülleri / alanı / alanı bulun ve düzenleyin.
  2. Field_has_data () işlevini bulun ve işlevin return TRUE;ilk satırına ekleyin .

    function field_has_data($field) {
      return FALSE; // HACK !!!
      $query = new EntityFieldQuery();
  3. Alanı istediğiniz değerlerle yeniden kaydedin.
  4. Bunu yaptıktan sonra kesmek kaldırın.

0

Bence bunu Views Bulk Operations modülünü kullanarak yapabilirsiniz .

  1. değiştirmek istediğiniz alana yeni bir seçenek ekleyin. örneğin: na | NA
  2. bu alana sahip bir Listeye görünüm düğümü oluştur
  3. bu Görünüm'e "Toplu işlemler: İçerik" alanları ekleyin
  4. "Varlık değerlerini değiştir" ve "kullanılabilir jetonları göster" i işaretleyin (görüntüleme değerlerinde Tümü'nü seçin)
  5. Filtre Ölçütlerine değiştirmek istediğiniz alanı ekleyin ve bu filtreleri "göster"
  6. bu Görünümde url Yolunu ayarla
  7. Bu görünüm sayfasına gidin ve değiştirin
  8. Şimdi, alan seçeneğini değiştirmek için pozlama ve işlem özelliklerini kullanın
  9. Bitti

0

İşte en iyi olduğunu düşündüğüm HL cevabı için bir gelişme geliyor:

Özetlemek gerekirse, seçim alanınız için "eski" değerler atanmış içeriğe yeni değerler atamanız gerekir.

Views Toplu İşlemleri dışında Yönetim Görünümleri modülünü kurmanız ve etkinleştirmeniz gerekir . Bu modülle, toplu işlemlerin etkinleştirildiği halihazırda kullanıma hazır bir görünümünüz var (etkinleştirildikten sonra yönetici / içeriğe bakın). Sonra:

1) Yönetici / yapıya / düzenleme "Yönetim: Düğüm" görünümüne gidin

2) Üstteki "Ekle -> Sayfa" düğmesini kullanarak görünüm için yeni bir sayfa görüntüleme ekleyin

3) Yeni ekrana bir yol atayın: Örnek admin / content / custom

4) Seçim alanınız için yeni bir filtre ekleyin: Operatör seçin "biridir" ve ardından silmek istediğiniz tüm seçenekleri belirleyin

5) Görünümü kaydedin

6) admin / content / custom adresine gidin Şimdi toplu olarak düzenlemek istediğiniz tüm içeriği görüyorsunuz (seçim alanınız için değeri değiştirin)

7) Tablonun solundaki ilk onay kutusunu tıklayarak tüm satırları seçin (birden fazla sayfa varsa, "Bu görünümdeki tüm X satırlarını seç" diyen bir düğme seçin)

8) "Değeri değiştir" işlemini seçin ve "Execute" tuşuna basın

9) Seçim alanınız için silmek istediğiniz değerlerin üzerine yazmak için yeni bir değer seçin

10) Bu seçim alanı için onay kutusunu seçin

11) İleri'ye tıklayın ve işiniz bitti


0

Drupal sorununuz daha derin bir veri sorununa dayanıyor gibi görünüyor: Şu anda amortismana tabi liste değerlerini kullanan varlıklara ne oluyor? Bu soru, Drupal'ın size gönderdiği hata mesajının kökenindedir.

Eyalet / bölge örneğinize daha yakından bakalım. Müşteriniz yıllardır eyaletlere ve bölgelere aynı şekilde davranan bir sistem kullanıyor ve hem eyaletleri hem de bölgeleri içeren dev bir düğüm grubu oluşturuyor. Sonra bir gün, bölgelerin farklı ele alınması gerektiğine ve bölge atamak için açılan listenin artık bölge içermemesine karar veren yetkiler. Harika. Tüm bölge düğümlerinin bir listesini oluşturmak için standart filtreler kullanan bir görünüm oluşturun ve tüm bölge değerlerini ... ... ... belki 51. durum olarak adlandırılan bazı eyaletlerini değiştirmek için Görüntüleme Toplu İşlemlerini kullanın. Bölgelerin kaderi çok ciddi bir sorudur. Çözümünüz, bölge durumunu korumak veya yerini değiştirmek için bir yöntem içermelidir. 'Bölge' adında yeni bir liste alanı oluşturmanız gerekebilir

Bu değişiklikleri gerçekleştirmek için Toplu İşlemleri Görüntüle ile Kurallar kullanmanız gerekecektir . Kurallar hakkında fazla bilginiz yoksa, nasıl çalıştıklarını öğrenmek için lütfen biraz zaman ayırın. Kurallar, bilgileri tetikleyicilere, koşullara ve işlemlere göre değiştirme olanağı verir. Kuralları öğrendikten sonra, aradığınız cevapların sezgisel olarak kendilerini sunacağını görebilirsiniz. Temel olarak, Toplu Operasyon tarafından tetiklenen ve tüm bölgeleri hedefleyecek ve bunları ana bilgi gövdesinden kaldıracak, yeniden atayacak, yeniden adlandıracak veya başka bir şekilde ayıracak bir kural oluşturmanız gerekecektir. Kural, bölge durumunu bir şekilde depolayabilmeli, aynı zamanda eyalet açılır menüsünü 'diğer' veya 'Yok' durumuna ayarlamalıdır. Tek gereken bu olabilir. Aksi takdirde...

Yeniden atama tamamlandıktan sonra, orijinal liste alanını değiştirmek ve bölge adlarını kaldırmak basit bir işlem olmalıdır. Ancak, sistem hala listeyi değiştirmenize izin vermiyorsa, yeni bir liste alanı oluşturmanız ve ardından geçerli durum değerlerinin tümünü incelemek ve bunları yeni listeye yeniden atamak için Toplu İşlem ve Kuralları Görüntüle'yi kullanmanız gerekebilir. Kurallar, ilgili düğümlerin tümünü hedeflemek ve alan değerlerine göre bunlara göre hareket etmek için Toplu İşlemler Görünümü ile birlikte çalışabilir. Kurallar'ı kullandığınızda, bir grup düğüm için var olan bir liste alanının değerine dayalı olarak yeni bir liste alanının değerini ayarlamak kolaydır.

Ayrıca, Drupal size bir işlemle ilgili sorun çıkarsa, zor bir alternatif düşünmeden önce önbelleği her zaman yıkayın.


0

Müşterinizin eski içeriğin orijinal değerinde kalmasını istediğini varsayıyorum, yani seçim listesini değiştirmek önceki verileri etkili bir şekilde yok edecektir. Bu bir endişe değilse, diğer cevaplardan herhangi biri muhtemelen işe yarayacaktır. Öyleyse, veri geçmişini kaybetmeden seçim listesini gerçekten değiştiremezsiniz. Siteyi biraz daha geleceğe dönük hale getirirken geçmiş verilere izin vermek için çok daha basit bir rotaya gidebilirim - alan izinlerini kullanmanızı öneririm:

* statik veri yerine bir sınıflandırma kullanarak bu seçim listesi için yeni bir alan ayarlama

* mevcut seçim listesinin alan iznini GÖRÜNÜM olarak ayarlayın, ancak yönetici dışındaki herkes tarafından DÜZENLEME seçeneğini belirleyin

Bununla, eski alan görüntülenebilir ve aranabilir kalmalıdır (yalnızca eski olarak yansıtan yeni bir başlık ekleyin), ancak düzenlenemez. Bu elbette büyük ölçüde ayarlanması gerekebilecek özel aramalara, görünümlere vb. Bağlıdır.

Bunu öneririm (kulağa geldiği kadar dağınık) çünkü bu verileri kaldırmak, geçmişi kaldırır ve bu uzun vadede yıkıcı olabilir. Düzenleme düğümündeki eski alanı gizlemek için css ve yeni içerik (değer kümesi bulunmayan) için gizlemek için bir kanca bile kullanabilirsiniz. Bu şekilde, yalnızca bu eski içerik için gösterilir.

Elbette, verileri eski seçim listesinden yeni sınıflandırmaya kopyalamak için özel bir kerelik modülle bir adım daha ileri gidebilirsiniz.


0

Kurtarmak için basit bir drush script! Alan ayarlarını ve alan revizyon tablolarını güncelliyoruz ve alan ayarlarını manuel olarak değiştirmeden önce eski değerleri yenileriyle değiştiriyoruz.

Mevcut alan ayarlarımızda böyle bir şey varsa:

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

ve aşağıdakilerle değiştirmek istersiniz:

date=today|today
date=last2days|last2days

Önce drush komut dosyasını çalıştırırız ve ardından yönetici arayüzünde alan ayarlarını değiştiririz.

Not: Bu kod, makine adı olan bir alan içindir 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;
}

0

Kenorb'un 2. önerisini kullandım ve Drupal 7.52, Profile2 7.x-1.3 alanındaki değer listesini güncellemeye çalıştı. Böylece drupal uyarısı alıyorsanız: “İzin verilen değerler listesi: şu anda kullanımda olan bazı değerler kaldırılıyor.” Aşağıdakiler, veritabanından kaldırmadan veya değiştirmeden değerleri (profile2) alanından kaldırmama izin verdi.

Drupal çekirdeğinin kök dizininde modüller adı verilen bir klasör vardır ve düzenlenecek dosya: modules / field / field.module konumunda bulunur. BU BİR ÇEKİRDEK DOSYADIR, değerleri güncellerken yaptığınız değişiklikleri kesinlikle geri almalısınız. Siteyi çevrimdışına aldım, geçici olarak (drupal root) /modules/field/field.module içindeki şu kod bloğunu değiştirdim

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

TAM OLARAK

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

Ve drupal şikayet etmeyi bıraktı ve listeyi değiştirebildim. (Benim durumumda, üniversiteden ayrılan, ancak danışmanı, akıl hocası vb.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.