Bir objedeki bir alandan bir girişi programlı olarak sil


13

Çok girişli bir alan için belirli bir alan girişini belirli bir varlıktan programlı olarak silmenin doğru yolu nedir? (bu, alan türleri veya örnekler ve varlık türleri değil, belirli alanlar ve belirli öğelerdir)

İşte içinde çalışmadığım bazı olasılıklar:

  • Varlığı ile yükleme, entity_load()alan girişini = null veya = array () olarak ayarlayıp ardından ile kaydedin field_attach_update(). Bulduğum en yakın ama form kaydedilene ve formları hook_field_is_empty()tekmeleyene kadar formlarda boş bir satır olarak görünen veritabanında bir zombi boş alan girişi bırakır ( hook_field_is_empty()= null veya = array () işaretlenecek şekilde yapılandırılır) boş olarak).
  • entity_load()Varlığı ile yükleme, alan girişini anahtarla ayırma ve sonra ile kaydetme field_attach_update(). Bu hiçbir şey yapmıyor gibi görünüyor - Drupal, orada bulunmayan girişi değiştirmemek için bir işaret olarak yorumluyor. (garip bir şekilde bu yaklaşımı denerken bazen maksimum sorgu süresi sona erme zaman aşımı da alıyorum)
  • field_attach_delete() - bu çok künt: varlık için tüm alanları öldürüyor
  • field_purge_data() - daha iyi, ama yine de çok künt: alanın tüm girişlerini öldürür, belirli girişleri değil

Açıklığa kavuşturmak için, birden fazla girişi olan bir alana sahip olan ve bu alanda kaldırılması gereken belirli bir girişi bulan (ve yükleyen) bir kod buldum. Varlık üzerindeki diğer girişlere veya diğer alanlara dokunmadan bu girişi tamamen kaldırmak istiyorum.

Yanıtlar:


24

Varlık API modülüne güvenebiliyorsanız , aşağıdakine benzer bir kod kullanabilmeniz gerekir:

// 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
Bu işe yaradı! Teşekkürler, zombi sorunum artık çözüldü. Başkalarına zaman kazandırabilecek birkaç not: Api varlığını RC2'ye güncellemem gerekiyordu; dinamik bir alan adı kullandığım için, unset satırının unset ($ entity -> {$ field_name} [LANGUAGE_NONE] [$ index]) gibi parantezlere ihtiyacı vardı; ve bir uyarıyı önlemek için if (! empty (...)) {}
user56reinstatemonica8

Bu, yalnızca tüm alanı temizlemek istiyorsanız ve "Dürüstlük kısıtlaması ihlali: 1048 Sütunu" field_duty_user_target_id "boş olamaz" gibi kötü durumlardan kaçınmak için de işe yarar.
Darrell Duane

Çok teşekkürler! node_load ile alan değerini değiştirmeye çalıştı, ancak çalışmadı. Bu nedenle varlık alanı değerini değiştirmek kesinlikle işe yarıyor!
Артем Ильин

1

Bunu bir Drupal8 geçiş temizliğinin parçası olarak yapmam gerekiyordu.

Bazı deneylerden sonra, yinelemenin ve daha sonra delta üzerinde unset () kullanmanın onu öldürebileceğini buldum. Örneğim bir etiketi kaldırıyordu (bu nedenle diğer alanlar için yaptığınız gibi 'değer' değil, 'hedef_kimliği' için arama yapıyorum.

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

Ve daha sonra, eğer başarılı olursa, $object->save();


0

Drupal 8 için, bir varlıktan bir alanı silmek için:

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

Bu, ContentEntityBase öğesinden __unset () sihirli yöntemini çağırır:

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

Unutmayın, değişikliklerinizi devam ettirmek için aramanız gerekir

$entity->save();

Tüm değişikliklerinizi yaptıktan sonra.


-1

Bu daha iyi bir yol:

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

-2

tercih edilen mevcut yöntem entity_metadata_wrapper öğesini kullanır

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

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

Bu gördüğüm EMW en iyi öğretici http://deeson-online.co.uk/labs/programatically-access-field-data-using-entitymetadatawrapper-drupal


bu işe yaramadı. Hatta hiç şans olmadan böyle denedim; $ wrapper = entity_metadata_wrapper ('düğüm', $ görev); unset ($ wrapper-> field_duty_user); $ wrapper-> save (); node_save ($ görev);
Darrell Duane

1
Doğru yol $ node_wrapped-> field_name-> set (""); sonra $ wrapper-> save ()
chadpeppers
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.