Bir alanı düğümden programlı olarak nasıl kaldırırım?


16

Bir alan bir düğümden programsal olarak nasıl kaldırılır? hook_update_Nİçinde bir alandan özel bir tabloya taşır bir geçiş var . Bu geçişten sonra, aynı işlevdeki alanı kaldırmak istiyorum.

Kaldırma alanlarını sağlayan herhangi bir alan API'sı var mı?

Düzenleme, Çözüm : Cevaplar gerçek kod eksik olduğundan, İşte $ kullanıcı alanlarını kendi kayıtları içine taşımak ve daha sonra alan veritabanından kaldırmak için yaptım;

function my_module_update_7005(&$sandbox) {
  $slice = 100;
  //Fetch users from database;
  if (!isset($sandbox['progress'])) {
    $sandbox['progress'] = 0;
    $sandbox['current_uid'] = 0;
    // We'll -1 to disregard the uid 0...
    $sandbox['max'] = db_query('SELECT COUNT(DISTINCT uid) FROM {users}')->fetchField() - 1;
  }
  if (empty($users)) {
    $sandbox["current_uid"] += $slice;
  }
  $users = db_select('users', 'u')
    ->fields('u', array('uid', 'name'))
    ->condition('uid', $sandbox['current_uid'], '>')
    ->range(0, $slice)
    ->orderBy('uid', 'ASC')
    ->execute();
  //Loop trough users;
  foreach ($users as $user) {
    $foo = new Foo();
    // Warning: drupal's fields return mixed values; e.g. NULL versus an int.
    $foo->debits = (int) $user->user()->field_credits["und"][0]["value"];
    $foo->save();

    $sandbox['progress']++;
    $sandbox['current_uid'] = $user->uid;
  }

  $sandbox['#finished'] = empty($sandbox['max']) ? 1 : ($sandbox['progress'] / $sandbox['max']);

  // Remove the field.
  field_delete_field("field_credits"); //note that the name for Foo is field_foo
  field_purge_batch($sandbox['max']+1);//Drupal seems to have an offbyone problem.
}

Yanıtlar:


29

field_delete_field($field_name)işaretler $field_namesonraki cron kaçak silinmek üzere.

Eğer field_purge_batchcron koşusunda yapmak istemiyorsanız, silme işlemini yapmak için kullanabilirsiniz .

EDIT: field_delete_field() alanı diğer paketlerden de silmeniz gerektiğinde kullanılmalıdır. Alanı yalnızca belirli bir field_delete_instance()paketten silmek istiyorsanız @Clive tarafından belirtildiği şekilde kullanmalısınız .


4
Dikkatli, bu da bağlı olabileceği diğer paketlerden alanı kaldıracak :) field_purge_batchGerçi bilmek iyi
Clive

@Clive: doğru, tüm paketlerden alan siler. Düzelttiğiniz için teşekkür ederim :) Cevabı düzenledim.
AjitS

Alanı tamamen kaldırmak istedim, yani tüm demetlerden. Ancak uyarı iyidir. Teşekkürler.
Berkes

1
field_delete_instance () yolu bu.
Ryan McVeigh

field_purge_batch () aslında yalnızca kendisine iletilen toplu iş boyutu kadar alan öğesini siler. Bu, alanın yalnızca birkaç öğesi olduğunda yardımcı olabilir, böylece alan örneğinden tamamen kurtulmak için, cron'un onu temizlemesini beklemenize gerek yoktur. Alanda çok fazla değeriniz varsa, toplu iş boyutunu çok fazla artırmak için cazip olmayın (adındaki "toplu iş", herhangi bir toplu iş yapacağını göstermez, sadece tek bir toplu iş yaptığı anlamına gelir İstediğiniz kadar öğeden); sonunda PHP belleğine veya zaman sınırına girebilirsiniz.
Eelke Blok

24

Bir alanı belirli bir paketten kaldırmak için şunları kullanabilirsiniz: field_delete_instance()

Bir alan örneğini ve verilerini silinmek üzere işaretler.

Misal:

function my_module_update_7001() {
  if ($instance = field_info_instance('node', 'field_name', 'page'))  {
    field_delete_instance($instance, TRUE);
    field_purge_batch(1);
  }
}

Bir alanı sistemden tamamen kaldırmak için şunu kullanabilirsiniz: field_delete_field()

Bir alanı ve örneklerini ve silinecek verileri işaretler.

Misal:

function my_module_update_7001() {
  field_delete_field('field_name');
  field_purge_batch(1);
}

Alanlar / örnekler yalnızca silinmek üzere işaretlenir, veriler sonraki cron çalışmalarında temizlenir. Manuel olarak temizlemek için:

field_purge_batch(1);

1
Arama yaparken field_delete_field()ve çalışırken field_purge_batch(), kayıtları field_config_instanceve içinde tutar field_config. Neden?
Berkes

Oldukça neden 1 değeri ile field_purge_batch çağırmak tüm alan verilerinden kurtulacak anlamıyorum. Kodu doğru anlarsam, $ batchsize varlıkları için alan verilerini alır ve bunu bırakır (yani işlevi özyinelemeli çağırma veya herhangi bir şey); tüm verilerin gidip gitmediğini kontrol etmek arayana kalmış gibi görünüyor ve eğer değilse, fonksiyonu çağırmaya devam edin. Ama belki temelde bir şeyi yanlış anlıyorum.
Eelke Blok

Aslında, field_ui.admin.inc'deki bu yorum bunu açıklamak için çok yol kat ediyor: // Alanlar cron üzerinde temizleniyor. Ancak saha modülü, sağladıkları alan türleri tamamen // temizlenene kadar bir alanda kullanıldığında modüllerin // devre dışı bırakılmasını engeller. Bir alanın çok az içeriğe sahip olması veya hiç içeriği olmaması durumunda, tek bir // / field_purge_batch () çağrısı alanı sistemden kaldıracaktır. Bu ölçütleri karşılayan örnekleri kaldırırken yöneticilerin cron çalışmalarını beklemelerini önlemek için // // toplu iş sınırı ile çağırın.
Eelke Blok

@Clive, tavsiyenin dolaylı olarak olduğuna inanıyorum, ancak if durumunda bir bildirimde bulunmanın bana ne kadar garip geldiğini anlayamıyorum. Bu bilerek mi? Ben atıfta bulunuyorum $instance = field_info_instance('node', 'field_name', 'page'). Bunun yerine $instance = field_info_instance('node', 'field_contact', 'job');if ifadesini bırakmalı mı?
cdmo

1
@cdmo "durumdaki atama" olarak adlandırılır ve evet problemleri vardır . Ancak Drupal core, en son sürümde bile liberal olarak kullanıyor, bu yüzden en azından emsali var. Dürüst olmak gerekirse, bu 5 yıl önceydi ve şimdi biraz daha akıllıyım, ya kullanmıyorum ya da herhangi bir nedenden ötürü, ödevi sarıyorum (örneğin if ( ($foo = $bar) ) {, niyet açık ve potansiyel if ifadesinin kendisi gereklidir çünkü field_delete_instancenull olup olmadığını kontrol etmez
Clive

5

@Berkes sorusunu cevaplamak için:

field_delete_field()alanı silinmek üzere işaretler, böylece bir sonraki cron koşusunda temizlenmesine neden olur. Ancak öyle üzerinde izin verilerini field_config_instancedüştü alanıyla ilgili. Silinen sütun alan için olarak ayarlanmış olsa bile cron çalıştırılırsa veya field_purge_batch()bu veriler field_config_instancetablodan kaldırılmaz 1.

Benim için her bir temizlenmiş alan için field_delete_instance()bir takip etti - benim field_purge_batch()için her iki alanı da veritabanından (cron gerektirmeden) hemen kaldırmanın yanı sıra field_config_instanceherhangi bir alan verisi tablosunu (silinen alan için) temizlemek .

İşte çözüm:

/**
 * Implements hook_uninstall().
 */
function hook_uninstall() {
  // Delete all fields for all xyz entity bundles.

  // Retrieve all bundles for an entity.
  $bundles = field_info_bundles('XYZ'); // The name of your entity type, for example, 'node'.
  foreach ($bundles as $bundle => $properties) {

    // Retrieve all the fields for a given bundle.
    $instances = field_info_instances('XYZ', $bundle);
    foreach ($instances as $instance) {
      field_delete_instance($instance, TRUE);
      field_purge_batch(1);
    }
  }
}

Not Do TRUEüzerinde field_delete_instance()o Saha API temizleme işlemleri gerçekleştirmek gerektiğini gösterir gibi.


Bu kod nasıl kullanılır? Bir içerik türünden başlık alanını silmek istiyorum
Umair
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.