7 use Symfony\Component\DependencyInjection\ContainerInterface;
8 use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
9 use Drupal\dkan_common\JsonResponseTrait;
17 use JsonResponseTrait;
28 private $endpointsToKeep = [
29 'metastore/schemas/dataset/items/{identifier}' => [
'get'],
30 'datastore/sql' => [
'get'],
38 private $docsController;
45 private $metastoreService;
50 public static function create(ContainerInterface $container) {
52 $container->get(
"dkan_api.docs"),
53 $container->get(
"dkan_metastore.service"),
54 $container->get(
'plugin.manager.dkan_common.data_modifier')
69 $this->docsController = $docsController;
70 $this->metastoreService = $metastoreService;
71 $this->pluginManager = $pluginManager;
73 $this->plugins = $this->discover();
86 $fullSpec = $this->docsController->getJsonFromYmlFile();
89 unset($fullSpec[
'components'][
'securitySchemes']);
92 $fullSpec[
'tags'] = [];
94 $pathsAndOperations = $fullSpec[
'paths'];
95 $pathsAndOperations = $this->keepDatasetSpecificEndpoints($pathsAndOperations);
96 $pathsAndOperations = $this->modifyDatasetEndpoints($pathsAndOperations, $identifier);
97 $pathsAndOperations = $this->modifySqlEndpoints($pathsAndOperations, $identifier, $fullSpec[
'components'][
'parameters']);
99 $fullSpec[
'paths'] = $pathsAndOperations;
100 return $this->getResponse($fullSpec);
112 private function keepDatasetSpecificEndpoints(array $pathsAndOperations) {
113 $keepPaths = array_keys($this->endpointsToKeep);
115 $paths = array_keys($pathsAndOperations);
117 $pathsToKeepPaths = array_combine($paths, array_map(
function ($path) use ($keepPaths) {
118 foreach ($keepPaths as $keepPath) {
119 if (substr_count($path, $keepPath) > 0 && substr_count($path, $keepPath .
"/") == 0) {
126 foreach ($pathsAndOperations as $path => $operations) {
127 if (is_null($pathsToKeepPaths[$path])) {
128 unset($pathsAndOperations[$path]);
131 $pathsAndOperations[$path] = array_filter($operations,
function ($operation) use ($path, $pathsToKeepPaths) {
132 return in_array($operation, $this->endpointsToKeep[$pathsToKeepPaths[$path]]);
133 }, ARRAY_FILTER_USE_KEY);
137 return $pathsAndOperations;
151 private function modifyDatasetEndpoints(array $pathsAndOperations,
string $identifier) {
153 foreach ($pathsAndOperations as $path => $operations) {
155 $newOperations = $operations;
156 unset($pathsAndOperations[$path]);
157 [$newPath, $newOperations] = $this->modifyDatasetEndpoint($newPath, $newOperations, $identifier);
158 $pathsAndOperations[$newPath] = $newOperations;
161 return $pathsAndOperations;
167 private function modifyDatasetEndpoint($path, $operations, $identifier) {
168 $newOperations = $this->getModifyDatasetEndpointNewOperations($operations, $identifier);
170 if (!isset($newOperations)) {
171 return [$path, $operations];
174 $newPath = str_replace(
"{identifier}", $identifier, $path);;
176 return [$newPath, $newOperations];
182 private function getModifyDatasetEndpointNewOperations($operations, $identifier) {
184 foreach ($operations as $operation => $info) {
185 $newParameters = $this->getModifyDatasetEndpointNewParameters($info[
'parameters'], $identifier);
186 if ($newParameters) {
187 $operations[$operation][
'parameters'] = $newParameters;
192 return ($modified) ? $operations : NULL;
198 private function getModifyDatasetEndpointNewParameters(array $parameters, $identifier): ?array {
200 foreach ($parameters as $key => $parameter) {
201 if (isset($parameter[
'name']) && $parameter[
'name'] ==
"identifier" && isset($parameter[
'example'])) {
202 $parameters[$key][
'example'] = $identifier;
206 return ($modified) ? $parameters : NULL;
222 private function modifySqlEndpoints(array $pathsAndOperations,
string $identifier, array $parameters) {
223 if ($this->modifyData($identifier)) {
224 return $this->removeSqlEndpointPaths($pathsAndOperations);
227 $query = $parameters[
'query'];
229 foreach ($this->getSqlPathsAndOperations($pathsAndOperations) as $path => $operations) {
231 foreach ($this->getDistributions($identifier) as $dist) {
232 list($newPath, $newOperations) = $this->modifySqlEndpoint($path, $operations, $dist, $query);
233 $pathsAndOperations[$newPath] = $newOperations;
236 unset($pathsAndOperations[$path]);
239 return $pathsAndOperations;
245 private function getSqlPathsAndOperations($pathsAndOperations) {
246 foreach ($pathsAndOperations as $path => $operations) {
247 if (substr_count($path,
'sql') == 0) {
248 unset($pathsAndOperations[$path]);
251 return $pathsAndOperations;
257 private function removeSqlEndpointPaths($pathsAndOperations) {
258 foreach ($pathsAndOperations as $path => $operations) {
259 if (substr_count($path,
'sql') > 0) {
261 unset($pathsAndOperations[$path]);
264 return $pathsAndOperations;
270 private function modifySqlEndpoint($path, $operations, $distribution, $query) {
271 $newPath =
"{$path}?query=[SELECT * FROM {$distribution->identifier}];";
273 $query[
'example'] =
"[SELECT * FROM {$distribution->identifier}];";
274 $operations[
'get'][
'parameters'] = [$query];
276 return [$newPath, $operations];
290 private function modifyData(
string $identifier) {
291 foreach ($this->plugins as $plugin) {
292 if ($plugin->requiresModification(
'distribution', $identifier)) {
308 private function getDistributions(
string $identifier) {
310 if (function_exists(
'drupal_static')) {
314 $data = json_decode($this->metastoreService->get(
"dataset", $identifier));
317 if (isset($data->distribution)) {
318 return $data->distribution;