Nhảy đến nội dung

[Thủ Thuật Drupal] Hướng dẫn sử dụng EntityQuery Drupal

Nội Dung Bài Viết

EntityQuery là gì ?

Phương thức Drupal :: entityQuery là cách thức lấy các node trong Drupal 8 và Drupal 9 bằng query giống câu lệnh SQL thông thường.

Cách lấy một node đơn giản bằng EntityQuery 

$query = \Drupal::entityQuery('node')
  ->condition('type', 'page')
  ->condition('field_some_field', 14, '>')
$results = $query->execute();

Giải thích:

Đây là ví dụ lấy tất cả các node có kiểu là 'page' và trường 'field_some_field' lớn hơn '14' và sau đó thực hiện query bằng execute().

Ngoài ra chúng ta có thể thêm range và sort như 

$query = \Drupal::entityQuery('node')
  ->condition('type', 'page')
  ->condition('field_some_field', 14, '>')
  ->sort('nid', ASC)
  ->range(0, 10);
$results = $query->execute();

Cách lấy node bằng nhóm câu điều kiện với entityQuery

Hãy xem xét trường hợp chúng ta muốn tìm tất cả người dùng có tài khoản được tạo trước năm 2010 hoặc kể từ ngày 1 tháng 1 năm 2020.

Lúc này ta cần một group condition như :

$query = \Drupal::entityQuery('user');
$group = $query
  ->orConditionGroup()
  ->condition('created', '1262304000', '<')     // Jan 1, 2010
  ->condition('created', '1577836800', '>');    // Jan 1, 2020
$results = $query->condition($group)
  ->condition('status', 1)
  ->sort('created', DESC)
  ->execute();

Chú ý: thời gian chuyển về dạng timestamp

Lấy node thông qua reference field

Ví dụ bạn có hai kiểu node Event và Location, trong node Event có location là một reference field tới node Location

Event :

  • Node ID
  • Name
  • Date
  • Location (reference field)

Location : 

  • Node ID
  • Name
  • Address
  • Venue type - List (text) field

Bạn có thể sử dụng entityQuery để trả về tất cả các node Event có Venue type của node Localion là 'boat'.

$results = \Drupal::entityQuery('node')
  ->condition('type', 'event')
  ->condition('field_location.entity:node.field_venue_type', 'boat')
  ->execute();

Hiển thị câu SQL 

Đôi khi bạn muốn hiển thị câu query trừ result của entityQuery thì hãy sử dụng __toString()

$results = \Drupal::entityQuery('node')
  ->condition('type', 'event')
  ->condition('field_location.entity:node.field_venue_type', 'boat')
  ->__toString();

Kết quả :

SELECT base_table.vid AS vid, base_table.nid AS nid
FROM
node base_table
INNER JOIN node_field_data node_field_data ON node_field_data.nid = base_table.nid
INNER JOIN node__field_location node__field_location ON node__field_location.entity_id = base_table.nid
LEFT OUTER JOIN node node ON node.nid = node__field_location.field_location_target_id
INNER JOIN node__field_venue_type node__field_venue_type ON node__field_venue_type.entity_id = node.nid
WHERE (node_field_data.type = 'event') AND (node__field_venue_type.field_venue_type_value = 'boat')

Lấy node bằng câu query phức tạp hơn ?

Nếu trong trường hợp như trên, bạn cần lấy tất cả node Event có reference node Location mà có term là "sailboat", bạn có thể làm như sau :

$results = \Drupal::entityQuery('node')
  ->condition('type', 'event')
  ->condition('field_location.entity:node.field_tags.entity:taxonomy_term.name', 'sailboat')
  ->execute();

Chú ý :Drupal :: entityQuery chỉ được dùng khi người dùng đăng nhập, để bỏ tính năng đăng nhập bạn cần sử dụng :

$query->accessCheck(FALSE);