Lập trình xóa một mục từ một trường trên một thực thể


13

Cách thích hợp để lập trình xóa một mục nhập trường cụ thể cho trường đa mục từ một thực thể cụ thể là gì? (đó là các trường cụ thể và các thực thể cụ thể, không phải loại trường hoặc trường hợp và loại thực thể)

Đây là một số khả năng tôi đã xem xét mà không hoạt động:

  • Tải thực thể với entity_load(), đặt mục nhập trường thành = null hoặc = mảng (), sau đó lưu với field_attach_update(). Đó là lần gần nhất tôi tìm thấy nhưng nó để lại một mục nhập trường rỗng trong cơ sở dữ liệu hiển thị dưới dạng một hàng trống trên biểu mẫu cho đến khi biểu mẫu được lưu và hook_field_is_empty()có thể khởi động ( hook_field_is_empty()được định cấu hình sao cho = null hoặc = mảng () sẽ gắn cờ như trống rỗng).
  • Tải thực thể bằng entity_load(), bỏ đặt mục nhập trường bằng phím, sau đó lưu với field_attach_update(). Điều này dường như không làm gì cả - có vẻ như Drupal diễn giải mục nhập không ở đó như một dấu hiệu để không sửa đổi nó. (kỳ lạ là đôi khi tôi cũng nhận được thời gian hết hạn truy vấn tối đa khi thử phương pháp này)
  • field_attach_delete() - điều này quá cùn: nó giết tất cả các trường cho thực thể
  • field_purge_data() - tốt hơn, nhưng vẫn quá cùn: nó giết tất cả các mục của trường, không phải các mục cụ thể

Vì vậy, để làm rõ, tôi đã có mã tìm (và tải) một thực thể có một trường có nhiều mục và tìm một mục cụ thể trên trường đó cần phải xóa. Tôi muốn xóa hoàn toàn mục đó, mà không cần chạm vào bất kỳ mục nào khác hoặc bất kỳ trường nào khác trên thực thể.

Câu trả lời:


24

Nếu bạn có thể dựa vào mô-đun API thực thể, bạn sẽ có thể sử dụng mã tương tự như sau:

// 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
Điều này đã làm việc! Cảm ơn, vấn đề zombie của tôi đã bị xóa bỏ. Một vài lưu ý có thể giúp người khác tiết kiệm thời gian: Tôi cần cập nhật api thực thể lên RC2; vì tôi đang sử dụng tên trường động, dòng unset cần niềng răng như unset ($ entity -> {$ field_name} [LANGUAGE_NONE] [$ index]); và để tránh cảnh báo tôi cần phải bọc mảng_values ​​() trong if (!
blank

Điều này cũng hoạt động nếu bạn chỉ muốn xóa toàn bộ trường và tránh "Vi phạm ràng buộc toàn vẹn đáng sợ: 1048 Cột 'field_duty_user_target_id' không thể rỗng"
Darrell Duane

Cảm ơn rất nhiều! đã cố gắng thay đổi giá trị trường thông qua node_load, nhưng nó không hoạt động. Vì vậy, thay đổi giá trị trường thực thể như thế này chắc chắn hoạt động!
Tiếng Pháp

1

Tôi cần phải làm điều này như là một phần của việc dọn dẹp di chuyển Drupal8.

Sau một vài thử nghiệm, tôi thấy rằng việc lặp lại và sau đó sử dụng unset () trên delta có thể giết chết nó. Ví dụ của tôi là xóa thẻ (do đó tôi tìm kiếm 'target_id', không phải 'value' như bạn thường làm cho các trường khác.

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

Và sau đó, nếu thành công, thì $object->save();


0

Đối với Drupal 8, để xóa một trường khỏi một thực thể:

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

Điều này sẽ gọi phương thức ma thuật __unset () từ 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]);
    }
}

Đừng quên rằng, để tiếp tục thay đổi, bạn cần gọi

$entity->save();

Sau khi bạn thực hiện tất cả các thay đổi của bạn.


-1

Đây là cách tốt hơn:

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

-2

phương thức ưa thích hiện tại sẽ sử dụng entity_metadata_wrapper

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

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

đây là hướng dẫn tốt nhất về EMW mà tôi đã thấy http://deeson-online.co.uk/labs/programatically-access-field-data-USE-entitymetadatawrapper-drupal


việc này không hiệu quả. Tôi thậm chí đã thử nó như thế này mà không có may mắn; $ Wrapper = entity_metadata_wrapper ('nút', $ Duty); bỏ đặt ($ Wrapper-> field_duty_user); $ bao bọc-> lưu (); node_save ($ Duty);
Darrell Duane

1
Cách chính xác sẽ là $ node_wrapping-> field_name-> set (""); sau đó $ Wrapper-> save ()
chadpeppers
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.