ลบรายการหนึ่งโดยทางโปรแกรมจากเขตข้อมูลหนึ่งโดยทางโปรแกรมหนึ่ง


13

วิธีใดที่เหมาะสมในการลบรายการฟิลด์หนึ่งรายการสำหรับฟิลด์หลายรายการโดยทางโปรแกรม (นั่นคือฟิลด์เฉพาะและเอนทิตีเฉพาะไม่ใช่ประเภทฟิลด์หรืออินสแตนซ์และประเภทเอนทิตี)

นี่คือความเป็นไปได้บางอย่างที่ฉันได้พิจารณาแล้วว่าไม่ได้ผล:

  • โหลดนิติบุคคลที่มีentity_load()การตั้งค่ารายการสนาม = โมฆะหรือ = array () field_attach_update()แล้วประหยัด มันเป็นเรื่องที่ใกล้เคียงที่สุดที่ฉันได้พบ แต่ใบรายการฟิลด์ผีดิบ null ในฐานข้อมูลซึ่งแสดงให้เห็นถึงเป็นแถวว่างเปล่าในรูปแบบจนกว่าฟอร์มถูกบันทึกไว้และhook_field_is_empty()สามารถเตะใน ( hook_field_is_empty()มีการกำหนดค่าดังกล่าวว่า = โมฆะหรือ = array () จะธง ว่างเปล่า)
  • โหลดนิติบุคคลที่มีentity_load(), unsetting field_attach_update()รายการข้อมูลโดยคีย์แล้วประหยัด ดูเหมือนว่าจะไม่ทำอะไรเลย - ดูเหมือนว่า Drupal จะตีความรายการที่ไม่ได้มีไว้เป็นสัญญาณเพื่อไม่แก้ไข (แปลกบางครั้งฉันยังได้รับเวลาหมดเวลาสอบถามสูงสุดเมื่อลองวิธีนี้)
  • field_attach_delete() - นี่มันทื่อมากเกินไป: มันฆ่าทุกฟิลด์สำหรับเอนทิตี
  • field_purge_data() - ดีกว่า แต่ก็ยังทื่อเกินไป: มันฆ่ารายการทั้งหมดของฟิลด์ไม่ใช่เฉพาะรายการ

เพื่อชี้แจงฉันได้รับรหัสที่พบ (และโหลด) เอนทิตีที่มีฟิลด์ที่มีหลายรายการและค้นหารายการเฉพาะในฟิลด์นั้นที่จำเป็นต้องลบออก ฉันต้องการลบรายการนั้นอย่างสมบูรณ์โดยไม่ต้องแตะรายการอื่นใดหรือฟิลด์อื่น ๆ ในเอนทิตี

คำตอบ:


24

หากคุณสามารถพึ่งพาโมดูลเอนทิตี APIคุณควรจะสามารถใช้รหัสที่คล้ายกับรายการต่อไปนี้:

// 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
สิ่งนี้ได้ผล! ขอบคุณปัญหาซอมบี้ของฉันถูกกำจัดไปแล้ว หมายเหตุเล็กน้อยที่อาจช่วยประหยัดเวลาอื่น ๆ : ฉันต้องการอัปเดตเอนทิตี api เป็น RC2; เนื่องจากฉันใช้ชื่อฟิลด์แบบไดนามิกบรรทัดที่ไม่ได้กำหนดให้ใช้วงเล็บปีกกาเช่น unset ($ entity -> {$ field_name} [LANGUAGE_NONE] [$ index]); และเพื่อหลีกเลี่ยงคำเตือนฉันจำเป็นต้องล้อม array_values ​​() ในถ้า (! ว่าง (... )) {}
user56reinstatemonica8

วิธีนี้ใช้ได้ผลถ้าคุณต้องการล้างข้อมูลในฟิลด์ทั้งหมดและหลีกเลี่ยงการ "จำกัด การละเมิดข้อ จำกัด ด้านความน่ากลัว: คอลัมน์ 1048 คอลัมน์ 'field_duty_user_target_id' ไม่สามารถเป็นโมฆะ"
Darrell Duane

ขอบคุณมาก! พยายามเปลี่ยนค่าฟิลด์ผ่าน node_load แต่มันไม่ทำงาน ดังนั้นการเปลี่ยนค่าฟิลด์เอนทิตีแบบนี้จะได้ผลแน่นอน!
АртемИльин

1

ฉันต้องทำสิ่งนี้เป็นส่วนหนึ่งของการล้างข้อมูลการโยกย้าย Drupal8

หลังจากการทดลองบางอย่างฉันพบว่าการวนซ้ำแล้วใช้ unset () บนเดลต้าสามารถฆ่าได้ ตัวอย่างของฉันคือการลบแท็ก (ดังนั้นฉันค้นหา 'target_id' ไม่ใช่ 'ค่า' ตามที่คุณต้องการสำหรับฟิลด์อื่น

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

และหลังจากนั้นหากประสบความสำเร็จแล้ว $object->save();


0

สำหรับ Drupal 8 เพื่อลบฟิลด์จากเอนทิตี:

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

สิ่งนี้จะเรียกเมธอดเวทมนต์ __unset () จาก ContentEntityBase:

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

อย่าลืมสิ่งนั้นเพื่อยืนยันการเปลี่ยนแปลงของคุณคุณต้องโทรหา

$entity->save();

หลังจากที่คุณทำการเปลี่ยนแปลงทั้งหมดแล้ว



-2

วิธีที่ต้องการในปัจจุบันจะใช้ entity_metadata_wrapper

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

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

นี่เป็นบทแนะนำที่ดีที่สุดเกี่ยวกับ EMW ที่ฉันได้เห็นhttp://deeson-online.co.uk/labs/programatically-access-field-data-using-entitymetadatawrapper-data


สิ่งนี้ไม่ทำงาน ฉันลองทำแบบนี้โดยไม่มีโชค $ wrapper = entity_metadata_wrapper ('node', $ duty); unset ($ wrapper-> field_duty_user); $ wrapper-> บันทึก (); node_save ($ หน้าที่);
Darrell Duane

1
วิธีที่ถูกต้องจะเป็น $ node_wrapped-> field_name-> set (""); จากนั้น $ wrapper-> save ()
chadpeppers
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.