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