Open Data Catalog v2.0.0
DatasetApiDocs.php
Go to the documentation of this file.
1 <?php
2 
3 namespace Drupal\metastore;
4 
6 
11 
12  const SPEC_PARAMETERS = [
13  'datasetUuid',
14  'showReferenceIds',
15  'datastoreDistributionUuid',
16  'datastoreQueryProperties',
17  'datastoreQueryConditions',
18  'datastoreQueryLimit',
19  'datastoreQueryOffset',
20  'datastoreQuerySorts',
21  'datastoreQueryCount',
22  'datastoreQueryResults',
23  'datastoreQuerySchema',
24  'datastoreQueryKeys',
25  'datastoreQueryFormat',
26  'datastoreQueryRowIds',
27  'datastoreDatasetUuid',
28  'datastoreDistributionIndex',
29  ];
30 
31  const SPEC_SCHEMAS = [
32  'dataset',
33  'errorResponse',
34  'datastoreResourceQuery',
35  'datastoreQueryResource',
36  'datastoreQueryProperty',
37  'datastoreQueryExpression',
38  'datastoreQueryCondition',
39  'datastoreQueryConditionGroup',
40  'datastoreQuerySort',
41  'datastoreQueryResourceProperty',
42  'datastoreQuery',
43 
44  ];
45 
46  const SPEC_RESPONSES = [
47  '404IdNotFound',
48  '200JsonOrCsvQueryOk',
49  '400BadJson',
50  ];
51 
57  private $docsGenerator;
58 
64  private $metastore;
65 
74  public function __construct(DkanApiDocsGenerator $docsGenerator, Service $metastore) {
75  $this->docsGenerator = $docsGenerator;
76  $this->metastore = $metastore;
77  }
78 
88  public function getDatasetSpecific(string $identifier) {
89  $specs = ['metastore_api_docs', 'datastore_api_docs'];
90  $fullSpec = $this->docsGenerator->buildSpec($specs)->{"$"};
91 
92  $datasetSpec = [
93  'openapi' => $fullSpec['openapi'],
94  'info' => $fullSpec['info'],
95  ];
96 
97  $metastorePath = $fullSpec['paths']['/api/1/metastore/schemas/dataset/items/{identifier}']['get'];
98  unset($metastorePath['parameters'][0]);
99  $metastorePath['parameters'] = array_values($metastorePath['parameters']);
100  $datasetSpec['paths']["/api/1/metastore/schemas/dataset/items/$identifier"]['get'] = $metastorePath;
101 
102  $datasetSpec['paths']["/api/1/datastore/query/$identifier/{index}"]
103  = $this->getDatastoreIndexPath($fullSpec, $identifier);
104 
105  $datasetSpec['paths']['/api/1/datastore/query/{distributionId}'] =
106  $fullSpec['paths']['/api/1/datastore/query/{distributionId}'];
107 
108  $datasetSpec['paths']['/api/1/datastore/sql'] =
109  $fullSpec['paths']['/api/1/datastore/sql'];
110 
111  $datasetSpec['components'] = $this->datasetSpecificComponents($fullSpec, $identifier);
112 
113  $this->alterDatastoreParameters($datasetSpec, $identifier);
114  $this->modifySqlEndpoints($datasetSpec, $identifier);
115 
116  return $datasetSpec;
117  }
118 
130  private function datasetSpecificComponents($fullSpec, $identifier) {
131  $components = [];
132  $components['parameters'] =
133  $this->datasetSpecificParameters($fullSpec['components']['parameters'], $identifier);
134  $components['schemas'] =
135  $this->datasetSpecificSchemas($fullSpec['components']['schemas']);
136  $components['responses'] =
137  $this->datasetSpecificResponses($fullSpec['components']['responses']);
138 
139  return $components;
140  }
141 
153  private function getDatastoreIndexPath($fullSpec, $identifier) {
154  $datastoreIndexPath = $fullSpec['paths']['/api/1/datastore/query/{datasetId}/{index}'];
155  unset($datastoreIndexPath['get']['parameters'][0]);
156  $datastoreIndexPath['get']['parameters'] = array_values($datastoreIndexPath['get']['parameters']);
157  unset($datastoreIndexPath['post']['parameters'][0]);
158  $datastoreIndexPath['post']['parameters'] = array_values($datastoreIndexPath['post']['parameters']);
159  return $datastoreIndexPath;
160  }
161 
171  private function datasetSpecificSchemas(array $schemas) {
172  $newSchemas = array_filter($schemas, function ($key) {
173  if (in_array($key, self::SPEC_SCHEMAS)) {
174  return TRUE;
175  }
176  return FALSE;
177  }, ARRAY_FILTER_USE_KEY);
178  return $newSchemas;
179  }
180 
192  private function datasetSpecificParameters(array $parameters, $identifier) {
193  $newParameters = array_filter($parameters, function ($key) {
194  if (in_array($key, self::SPEC_PARAMETERS)) {
195  return TRUE;
196  }
197  return FALSE;
198  }, ARRAY_FILTER_USE_KEY);
199  $newParameters['datasetUuid']['example'] = $identifier;
200  return $newParameters;
201  }
202 
212  private function datasetSpecificResponses(array $responses) {
213  $newResponses = array_filter($responses, function ($key) {
214  if (in_array($key, self::SPEC_RESPONSES)) {
215  return TRUE;
216  }
217  return FALSE;
218  }, ARRAY_FILTER_USE_KEY);
219  return $newResponses;
220  }
221 
230  private function alterDatastoreParameters(array &$spec, string $identifier) {
231  $spec['components']['parameters']['datastoreDatasetUuid']['example'] = $identifier;
232  foreach ($this->getDistributions($identifier) as $index => $dist) {
233  unset($spec['components']['parameters']['datastoreDistributionUuid']['example']);
234  $spec['components']['parameters']['datastoreDistributionUuid']['examples'][$dist['identifier']] = [
235  'value' => $dist['identifier'],
236  'summary' => $dist["data"]["title"] ?? $dist['identifier'],
237  ];
238  unset($spec['components']['parameters']['datastoreDistributionIndex']['example']);
239  $spec['components']['parameters']['datastoreDistributionIndex']['examples']["index{$index}"] = [
240  'value' => "$index",
241  'summary' => $dist["data"]["title"] ?? $dist['identifier'],
242  ];
243  }
244  }
245 
254  private function modifySqlEndpoints(array &$spec, string $identifier) {
255 
256  foreach ($this->getSqlPathsAndOperations($spec['paths']) as $path => $operations) {
257  foreach ($this->getDistributions($identifier) as $dist) {
258  $newOperations = $this->modifySqlEndpoint($operations, $dist);
259  $spec['paths'][$path] = $newOperations;
260  }
261  }
262  }
263 
267  private function getSqlPathsAndOperations($pathsAndOperations) {
268  foreach (array_keys($pathsAndOperations) as $path) {
269  if (substr_count($path, 'sql') == 0) {
270  unset($pathsAndOperations[$path]);
271  }
272  }
273  return $pathsAndOperations;
274  }
275 
279  private function modifySqlEndpoint($operations, $distribution) {
280  $distKey = isset($distribution['data']['title']) ? $distribution['data']['title'] : $distribution['identifier'];
281  unset($operations['get']['parameters'][0]['example']);
282  $operations['get']['parameters'][0]['examples'][$distKey] = [
283  "summary" => "Query distribution {$distribution['identifier']}",
284  "value" => "[SELECT * FROM {$distribution['identifier']}][LIMIT 2]",
285  ];
286  return $operations;
287  }
288 
298  private function getDistributions(string $identifier) {
299 
300  $data = $this->metastore->swapReferences($this->metastore->get("dataset", $identifier));
301 
302  return $data->{"$.distribution"} ?? [];
303  }
304 
305 }
Drupal\metastore
Drupal\metastore\Service
Definition: Service.php:21
Drupal\metastore\DatasetApiDocs\__construct
__construct(DkanApiDocsGenerator $docsGenerator, Service $metastore)
Definition: DatasetApiDocs.php:74
Drupal\metastore\DatasetApiDocs\SPEC_PARAMETERS
const SPEC_PARAMETERS
Definition: DatasetApiDocs.php:12
Drupal\metastore\DatasetApiDocs\SPEC_SCHEMAS
const SPEC_SCHEMAS
Definition: DatasetApiDocs.php:31
Drupal\metastore\DatasetApiDocs\getDatasetSpecific
getDatasetSpecific(string $identifier)
Definition: DatasetApiDocs.php:88
Drupal\common\DkanApiDocsGenerator
Definition: DkanApiDocsGenerator.php:11
Drupal\metastore\DatasetApiDocs\SPEC_RESPONSES
const SPEC_RESPONSES
Definition: DatasetApiDocs.php:46
Drupal\metastore\DatasetApiDocs
Definition: DatasetApiDocs.php:10