Open Data Catalog v
QueryBuilderTrait.php
Go to the documentation of this file.
1 <?php
2 
4 
5 use Drupal\common\EventDispatcherTrait;
6 use Drupal\search_api\IndexInterface;
7 use Drupal\search_api\Query\Query;
8 use Drupal\search_api\Query\QueryInterface;
9 use Drupal\search_api\Utility\QueryHelperInterface;
10 
17  use EventDispatcherTrait;
18 
33  private function getQuery(array $params, IndexInterface $index, QueryHelperInterface $queryHelper): array {
34  $query = $queryHelper->createQuery($index);
35 
36  list($query, $activeFullText) = $this->setFullText($query, $params, $index);
37  list($query, $activeCondition) = $this->setFieldConditions($query, $params, $index);
38  $query = $this->setSort($query, $params, $index);
39  $query = $this->setRange($query, $params, $index);
40 
41  return [$query, $activeFullText || $activeCondition];
42  }
43 
58  private function setFullText(QueryInterface $query, array $params, IndexInterface $index): array {
59  if (!isset($params['fulltext']) || empty($params['fulltext'])) {
60  return [$query, FALSE];
61  }
62 
63  $fulltextFields = $index->getFulltextFields();
64 
65  if (empty($fulltextFields)) {
66  return [$query, FALSE];
67  }
68 
69  $conditions = [];
70  foreach ($fulltextFields as $field) {
71  $conditions[$field][] = $params['fulltext'];
72  }
73 
74  $query = $this->createConditionGroup($query, $conditions, 'OR');
75 
76  return [$query, TRUE];
77  }
78 
92  private function createConditionGroup(QueryInterface $query, array $conditions, string $conjunction = 'AND'): QueryInterface {
93  $conditionGroup = $query->createConditionGroup($conjunction);
94 
95  foreach ($conditions as $field => $values) {
96  foreach ($values as $value) {
97  $conditionGroup->addCondition($field, $value);
98  }
99  }
100 
101  $query->addConditionGroup($conditionGroup);
102 
103  return $query;
104  }
105 
120  private function setFieldConditions(QueryInterface $query, array $params, IndexInterface $index): array {
121  $active = FALSE;
122 
123  $fields = array_keys($index->getFields());
124 
125  foreach ($fields as $field) {
126  if (isset($params[$field])) {
127 
128  $info = $this->dispatchEvent(Search::EVENT_SEARCH_QUERY_BUILDER_CONDITION,
129  [
130  'field' => $field,
131  'values' => $this->getValuesFromCommaSeparatedString($params[$field]),
132  'conjunction' => 'AND',
133  ]);
134 
135  $conditions = [];
136  $conditions[$info['field']] = $info['values'];
137  $query = $this->createConditionGroup($query, $conditions, $info['conjunction']);
138  $active = TRUE;
139  }
140  }
141 
142  return [$query, $active];
143  }
144 
158  private function setSort(QueryInterface $query, array $params, IndexInterface $index): QueryInterface {
159  $fields = array_keys($index->getFields());
160 
161  $sorts = $params['sort'] ?? [];
162  if (is_string($sorts)) {
163  // @todo Move this into Util class to share with FacetsCommonTrait.
164  $sorts = array_map('trim', str_getcsv($sorts));
165  }
166 
167  if (empty($sorts)) {
168  $query->sort('search_api_relevance', Query::SORT_DESC);
169  }
170  foreach ($sorts as $index => $sort) {
171  if (in_array($sort, $fields)) {
172  $query->sort($sort, $this->getSortOrder($params, $index));
173  }
174  }
175 
176  return $query;
177  }
178 
191  private function getSortOrder(array $params, int $index = 0) {
192  $allowed = [
193  strtolower(QueryInterface::SORT_ASC),
194  strtolower(QueryInterface::SORT_DESC),
195  ];
196  $default = QueryInterface::SORT_ASC;
197 
198  $orders = $params['sort-order'] ?? [];
199  if (is_string($orders)) {
200  $orders = array_map('trim', str_getcsv($orders));
201  }
202 
203  if (!isset($orders[$index]) || !in_array($orders[$index], $allowed)) {
204  return $default;
205  }
206 
207  return strtoupper($orders[$index]);
208  }
209 
221  private function setRange(QueryInterface $query, array $params): QueryInterface {
222  $defaults = [
223  'page' => 1,
224  'page-size' => 10,
225  ];
226  $params = $params + $defaults;
227 
228  $end = ($params['page'] * $params['page-size']);
229  $start = $end - $params['page-size'];
230  $query->range($start, $params['page-size']);
231 
232  return $query;
233  }
234 
235 }
Drupal\metastore_search\Search\EVENT_SEARCH_QUERY_BUILDER_CONDITION
const EVENT_SEARCH_QUERY_BUILDER_CONDITION
Definition: Search.php:29
Drupal\metastore_search
Drupal\metastore_search\QueryBuilderTrait
trait QueryBuilderTrait
Definition: QueryBuilderTrait.php:16