Open Data Catalog v2.0.0
WebServiceApi.php
Go to the documentation of this file.
1 <?php
2 
3 namespace Drupal\dkan_search;
4 
5 use Drupal\dkan_common\JsonResponseTrait;
7 use Drupal\search_api\Query\QueryInterface;
8 
13  use JsonResponseTrait;
14 
18  public function search() {
19  $storage = \Drupal::service("entity_type.manager")->getStorage('search_api_index');
20 
21  /* @var \Drupal\search_api\IndexInterface $index */
22  $index = $storage->load('dkan');
23 
24  if (!$index) {
25  return $this->getResponse((object) ['message' => "An index named [dkan] does not exist."], 500);
26  }
27 
28  $fields = array_keys($index->getFields());
29 
30  $params = $this->getParams();
31 
32  /* @var $qh \Drupal\search_api\Utility\QueryHelper */
33  $qh = \Drupal::service("search_api.query_helper");
34 
35  /* @var $query \Drupal\search_api\Query\QueryInterface */
36  $query = $qh->createQuery($index);
37 
38  $this->setFullText($query, $params, $index);
39 
40  $this->setFieldConditions($query, $fields, $params);
41 
42  $facets = $this->getFacets($query, $fields);
43 
44  $this->setSort($query, $params, $fields);
45 
46  $this->setRange($query, $params);
47 
48  /* @var $result ResultSet*/
49  $result = $query->execute();
50  $count = $result->getResultCount();
51 
52  $data = $this->getData($result);
53 
54  $responseBody = (object) [
55  'total' => $count,
56  'results' => $data,
57  'facets' => $facets,
58  ];
59 
60  return $this->getResponse($responseBody);
61  }
62 
66  private function getData($result) {
67  /* @var $metastore Service */
68  $metastore = \Drupal::service("dkan_metastore.service");
69 
70  return array_filter(array_map(function ($item) use ($metastore) {
71  $id = $item->getId();
72  $id = str_replace("dkan_dataset/", "", $id);
73  try {
74  return json_decode($metastore->get("dataset", $id));
75  }
76  catch (\Exception $e) {
77  return NULL;
78  }
79  }, $result->getResultItems()));
80  }
81 
85  private function setRange(QueryInterface $query, $params) {
86  $end = ($params['page'] * $params['page-size']);
87  $start = $end - $params['page-size'];
88  $query->range($start, $params['page-size']);
89  }
90 
94  private function getParams() {
95  $defaults = [
96  "page-size" => 10,
97  "page" => 1,
98  ];
99 
100  /* @var $requestStack RequestStack */
101  $requestStack = \Drupal::service('request_stack');
102  $request = $requestStack->getCurrentRequest();
103  $params = $request->query->all();
104 
105  foreach ($defaults as $param => $default) {
106  $params[$param] = isset($params[$param]) ? $params[$param] : $default;
107  }
108 
109  if ($params["page-size"] > 100) {
110  $params["page-size"] = 100;
111  }
112 
113  return $params;
114  }
115 
119  private function setFullText(QueryInterface $query, $params, $index) {
120  if (!isset($params['fulltext'])) {
121  return;
122  }
123 
124  $fulltextFields = $index->getFulltextFields();
125  if (empty($fulltextFields)) {
126  return;
127  }
128 
129  $values = [];
130  foreach ($fulltextFields as $field) {
131  $values[$field][] = $params['fulltext'];
132  }
133 
134  $this->createConditionGroup($query, $values, 'OR');
135  }
136 
140  private function setFieldConditions(QueryInterface $query, $fields, $params) {
141  foreach ($fields as $field) {
142  if (isset($params[$field])) {
143  $values[$field] = $this->getValuesFromCommaSeparatedString($params[$field]);
144  $this->createConditionGroup($query, $values);
145  }
146  }
147  }
148 
152  private function getValuesFromCommaSeparatedString($string) {
153  $values = [];
154  foreach (explode(",", $string) as $value) {
155  $values[] = trim($value);
156  }
157  return $values;
158  }
159 
163  private function getFacets(QueryInterface $query, $fields) {
164  $facetsTypes = ['theme', 'keyword', 'publisher__name'];
165  $facets = [];
166 
167  foreach ($facetsTypes as $type) {
168  if (in_array($type, $fields)) {
169  $facets = array_merge($facets, $this->getFacetsForType($query, $type));
170  }
171  }
172 
173  return $facets;
174  }
175 
179  private function getFacetsForType(QueryInterface $query, $type) {
180  $facets = [];
181  $field = '';
182 
183  /* @var $metastore Service */
184  $metastore = \Drupal::service("dkan_metastore.service");
185 
186  // Prepare facets for fields that correspond to objects.
187  $matches = [];
188  if (preg_match('/(.*)__(.*)/', $type, $matches)) {
189  $schema = $matches[1];
190  $field = $matches[2];
191  }
192  else {
193  $schema = $type;
194  }
195  foreach ($metastore->getAll($schema) as $thing) {
196  $facet_name = empty($field) ? $thing->data : $thing->data->{$field};
197  $facets[] = $this->getFacetHelper($query, $type, $facet_name);
198  }
199 
200  return $facets;
201  }
202 
206  private function getFacetHelper(QueryInterface $query, $type, $facet_name) {
207  $myquery = clone $query;
208  $myquery->addCondition($type, $facet_name);
209  $result = $myquery->execute();
210  return [
211  'type' => $type,
212  'name' => $facet_name,
213  'total' => $result->getResultCount(),
214  ];
215  }
216 
220  private function setSort(QueryInterface $query, $params, $fields) {
221  if (isset($params['sort']) && in_array($params['sort'], $fields)) {
222  $query->sort($params['sort'], $this->getSortOrder($query, $params));
223  return;
224  }
225 
226  $query->sort('search_api_relevance', $query::SORT_DESC);
227  }
228 
232  private function getSortOrder(QueryInterface $query, $params) {
233  $default = $query::SORT_ASC;
234  if (!isset($params['sort-order'])) {
235  return $default;
236  }
237  if ($params['sort-order'] != 'asc' && $params['sort-order'] != 'desc') {
238  return $default;
239  }
240  return ($params['sort-order'] == 'asc') ? $query::SORT_ASC : $query::SORT_DESC;
241  }
242 
246  private function createConditionGroup(QueryInterface $query, $array, $conjuction = 'AND') {
247  $cg = $query->createConditionGroup($conjuction);
248  foreach ($array as $field => $values) {
249  foreach ($values as $value) {
250  $cg->addCondition($field, $value);
251  }
252  }
253  $query->addConditionGroup($cg);
254  }
255 
256 }
Drupal\dkan_search\WebServiceApi\search
search()
Definition: WebServiceApi.php:18
Drupal\dkan_search
Drupal\dkan_metastore\Service
Definition: Service.php:20
Drupal\dkan_search\WebServiceApi
Definition: WebServiceApi.php:12