5 use Drupal\dkan_common\JsonResponseTrait;
7 use Drupal\search_api\Query\QueryInterface;
13 use JsonResponseTrait;
19 $storage = \Drupal::service(
"entity_type.manager")->getStorage(
'search_api_index');
22 $index = $storage->load(
'dkan');
25 return $this->getResponse((
object) [
'message' =>
"An index named [dkan] does not exist."], 500);
28 $fields = array_keys($index->getFields());
30 $params = $this->getParams();
33 $qh = \Drupal::service(
"search_api.query_helper");
36 $query = $qh->createQuery($index);
38 $this->setFullText($query, $params, $index);
40 $this->setFieldConditions($query, $fields, $params);
42 $facets = $this->getFacets($query, $fields);
44 $this->setSort($query, $params, $fields);
46 $this->setRange($query, $params);
49 $result = $query->execute();
50 $count = $result->getResultCount();
52 $data = $this->getData($result);
54 $responseBody = (object) [
60 return $this->getResponse($responseBody);
66 private function getData($result) {
68 $metastore = \Drupal::service(
"dkan_metastore.service");
70 return array_filter(array_map(
function ($item) use ($metastore) {
72 $id = str_replace(
"dkan_dataset/",
"", $id);
74 return json_decode($metastore->get(
"dataset", $id));
76 catch (\Exception $e) {
79 }, $result->getResultItems()));
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']);
94 private function getParams() {
101 $requestStack = \Drupal::service(
'request_stack');
102 $request = $requestStack->getCurrentRequest();
103 $params = $request->query->all();
105 foreach ($defaults as $param => $default) {
106 $params[$param] = isset($params[$param]) ? $params[$param] : $default;
109 if ($params[
"page-size"] > 100) {
110 $params[
"page-size"] = 100;
119 private function setFullText(QueryInterface $query, $params, $index) {
120 if (!isset($params[
'fulltext'])) {
124 $fulltextFields = $index->getFulltextFields();
125 if (empty($fulltextFields)) {
130 foreach ($fulltextFields as $field) {
131 $values[$field][] = $params[
'fulltext'];
134 $this->createConditionGroup($query, $values,
'OR');
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);
152 private function getValuesFromCommaSeparatedString($string) {
154 foreach (explode(
",", $string) as $value) {
155 $values[] = trim($value);
163 private function getFacets(QueryInterface $query, $fields) {
164 $facetsTypes = [
'theme',
'keyword',
'publisher__name'];
167 foreach ($facetsTypes as $type) {
168 if (in_array($type, $fields)) {
169 $facets = array_merge($facets, $this->getFacetsForType($query, $type));
179 private function getFacetsForType(QueryInterface $query, $type) {
184 $metastore = \Drupal::service(
"dkan_metastore.service");
188 if (preg_match(
'/(.*)__(.*)/', $type, $matches)) {
189 $schema = $matches[1];
190 $field = $matches[2];
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);
206 private function getFacetHelper(QueryInterface $query, $type, $facet_name) {
207 $myquery = clone $query;
208 $myquery->addCondition($type, $facet_name);
209 $result = $myquery->execute();
212 'name' => $facet_name,
213 'total' => $result->getResultCount(),
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));
226 $query->sort(
'search_api_relevance', $query::SORT_DESC);
232 private function getSortOrder(QueryInterface $query, $params) {
233 $default = $query::SORT_ASC;
234 if (!isset($params[
'sort-order'])) {
237 if ($params[
'sort-order'] !=
'asc' && $params[
'sort-order'] !=
'desc') {
240 return ($params[
'sort-order'] ==
'asc') ? $query::SORT_ASC : $query::SORT_DESC;
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);
253 $query->addConditionGroup($cg);