<?php namespace SmartDataContext\Controller; use SmartDataContext\Persistence\SmartDataContextCrud; use SmartDataContext\Persistence\DBManager; use SmartDataContext\Domain\SmartDataContext; use Slim\Psr7\Request; use Slim\Psr7\Response; use OpenApi\Attributes as OA; class Crud { private function _basicValidation($params, $request, $response) { # Basic validation $body = $request->getParsedBody(); $errors = []; if (! $body) { $errors[] = "missing body"; } $domain = $this->_get_value_or_default($params, 'domain', null); if (! $domain) { $errors[] = "missing domain"; } return [$domain, $body, $errors]; } function create(Request $request, Response $response, array $params) { # Basic validation [$domain, $body, $errors] = $this->_basicValidation($params, $request, $response); if ($errors) { return $this->return_error($response, $errors, 400); } # Parameters $content = $this->_get_value_or_default($body, 'content', []); $features = $this->_get_value_or_default($body, 'features', []); $t0 = $this->_get_value_or_default($body, 't0', -1); $t1 = $this->_get_value_or_default($body, 't1', -1); $smartDataSources = $this->_get_value_or_default($body, 'smartDataSources', []); $smartDataUnits = $this->_get_value_or_default($body, 'smartDataUnits', []); # Validate parameters $errors = array_merge( SmartDataContext::ValidateContent($content), SmartDataContext::ValidateFeatures($features), SmartDataContext::ValidateTimestamp($t0,$t1), SmartDataContext::ValidateContent($content), SmartDataContext::ValidateFeatures($features), SmartDataContext::ValidateTimestamp($t0,$t1), SmartDataContext::ValidateSmartDataSources($smartDataSources), SmartDataContext::ValidateSmartDataUnits($smartDataUnits)); if ($errors) { return $this->return_error($response, $errors, 400); } # Create new SmartDataContext $persistence = new SmartDataContextCrud($this->_get_db()); $result = $persistence->create(domain: $domain, t0: $t0, t1: $t1, content: $content, features: $features, smartDataSources: $smartDataSources, smartDataUnits: $smartDataUnits); if ($result['success']) { return $this->return_json($response, $result["contents"]); } else { return $this->return_error($response, $result["errors"], 400); } } function associate(Request $request, Response $response, array $params) { # Basic validation [$domain, $body, $errors] = $this->_basicValidation($params, $request, $response); if ($errors) { return $this->return_error($response, $errors, 400); } $smartdatacontextids = $this->_get_value_or_default($body, 'smartDataContextIds', null); if (! isset($smartdatacontextids)) { return $this->return_error($response, ['Missing smartDataContextIds'], 400); } if (! is_array($smartdatacontextids)) { $smartdatacontextids = [$smartdatacontextids]; } $smartDataSources = $this->_get_value_or_default($body, 'smartDataSources', []); $smartDataUnits = $this->_get_value_or_default($body, 'smartDataUnits', []); $errors = array_merge( SmartDataContext::ValidateSmartDataSources($smartDataSources), SmartDataContext::ValidateSmartDataUnits($smartDataUnits)); if ($errors) { return $this->return_error($response, $errors, 400); } $persistence = new SmartDataContextCrud($this->_get_db()); $fullResult = []; foreach ($smartdatacontextids as $id) { $fullResult[] = $persistence->associate($domain, $id, $smartDataSources, $smartDataUnits); } return $this->return_json($response, $fullResult); } function unassociate(Request $request, Response $response, array $params) { # Basic validation [$domain, $body, $errors] = $this->_basicValidation($params, $request, $response); if ($errors) { return $this->return_error($response, $errors, 400); } $smartdatacontextids = $this->_get_value_or_default($body, 'smartDataContextIds', null); if (! isset($smartdatacontextids)) { return $this->return_error($response, ['Missing smartDataContextIds'], 400); } if (! is_array($smartdatacontextids)) { $smartdatacontextids = [$smartdatacontextids]; } $smartDataSources = $this->_get_value_or_default($body, 'smartDataSources', []); $smartDataUnits = $this->_get_value_or_default($body, 'smartDataUnits', []); $errors = array_merge( SmartDataContext::ValidateSmartDataSources($smartDataSources), SmartDataContext::ValidateSmartDataUnits($smartDataUnits)); if ($errors) { return $this->return_error($response, $errors, 400); } $persistence = new SmartDataContextCrud($this->_get_db()); $fullResult = []; foreach ($smartdatacontextids as $id) { $fullResult[] = $persistence->unassociate($domain, $id, $smartDataSources, $smartDataUnits); } return $this->return_json($response, $fullResult); } function get(Request $request, Response $response, array $params) { $domain = $this->_get_value_or_default($params, 'domain', null); $id = $this->_get_value_or_default($params, 'id', null); if (isset($domain) && isset($id)) { $persistence = new SmartDataContextCrud($this->_get_db()); $result = $persistence->get(domain: $domain, id: $id); if ($result['success']) { return $this->return_json($response, $result["contents"]); } else { return $this->return_error($response, $result["errors"], 400); } } elseif (! $id) { return $this->return_error($response, ["missing SmartDataContextID"], 400); } elseif (! $domain) { return $this->return_error($response, ["missing domain"], 400); } } function contexts(Request $request, Response $response, array $params) { # Basic validation [$domain, $body, $errors] = $this->_basicValidation($params, $request, $response); if ($errors) { return $this->return_error($response, $errors, 400); } $smartDataSources = $this->_get_value_or_default($body, 'smartDataSources', []); $smartDataUnits = $this->_get_value_or_default($body, 'smartDataUnits', []); if (count($smartDataSources) + count($smartDataUnits) == 0) { return $this->return_error($response, ["at least one smartDataSource or smartDataUnit must be provided"], 400); } $t0 = $this->_get_value_or_default($body, 't0', -1); $t1 = $this->_get_value_or_default($body, 't1', -1); $sourceFilter = []; foreach ($smartDataUnits as $smartDataUnit) { $sourceFilter[] = ["smartDataUnits" => $smartDataUnit]; } foreach ($smartDataSources as $smartDataSource) { $sourceFilter[] = ["smartDataSources" => $smartDataSource]; } $sourceFilter = ['$or' => $sourceFilter]; $timeFilter = []; if (isset($t0) && isset($t1)) { $timeFilter = ['$and' => [['t0' => ['$lte' => $t0]], ['$or' => [['t1' => ['$gte' => $t1]], ["t1" => -1]]]]]; } if ($timeFilter) { $filter = ['$and' => [$sourceFilter, $timeFilter]]; } else { $filter = $sourceFilter; } $persistence = new SmartDataContextCrud($this->_get_db()); $result = $persistence->query(domain: $domain, query: $filter); if ($result['success']) { return $this->return_json($response, $result["contents"]); } else { return $this->return_error($response, $result["errors"], 400); } } function query(Request $request, Response $response, array $params) { # Basic validation [$domain, $query, $errors] = $this->_basicValidation($params, $request, $response); if ($errors) { return $this->return_error($response, $errors, 400); } $persistence = new SmartDataContextCrud($this->_get_db()); $result = $persistence->query(domain: $domain, query: $query); if ($result['success']) { return $this->return_json($response, $result["contents"]); } else { return $this->return_error($response, $result["errors"], 400); } } private function _get_db() { return DBManager::GetMongoDBConnection(); } private function return_json(Response $response, mixed $object, $status = 200) { $result = array("result" => $object); $response = $response->withAddedHeader("Content-Type", "application/json")->withStatus($status); $response->getBody()->write(json_encode($result)); return $response; } private function return_error(Response $response, mixed $errorList, $status = 200) { $result = array("errors" => $errorList); $response = $response->withAddedHeader("Content-Type", "application/json")->withStatus($status); $response->getBody()->write(json_encode($result)); return $response; } private function _get_value_or_default($body, $key, $default) { if (! array_key_exists($key, $body)) { return $default; } else { return $body[$key]; } } function update(Request $request, Response $response, array $params) { // Basic validation [$domain, $body, $errors] = $this->_basicValidation($params, $request, $response); if ($errors) { return $this->return_error($response, $errors, 400); } $id = $this->_get_value_or_default($params, 'id', null); if (!$id) { return $this->return_error($response, ["missing SmartDataContextID"], 400); } // Validate properties only present in the request body $updateData = []; if (isset($body['content'])) { $contentErrors = SmartDataContext::ValidateContent($body['content']); if ($contentErrors) { $errors = array_merge($errors, $contentErrors); } $updateData['content'] = $body['content']; } if (isset($body['features'])) { $featuresErrors = SmartDataContext::ValidateFeatures($body['features']); if ($featuresErrors) { $errors = array_merge($errors, $featuresErrors); } $updateData['features'] = $body['features']; } $t0Set = isset($body['t0']); $t1Set = isset($body['t1']); if ($t0Set && $t1Set) { $timestampErrors = SmartDataContext::ValidateTimestamp($body['t0'], $body['t1']); if ($timestampErrors) { $errors = array_merge($errors, $timestampErrors); } $updateData['t0'] = $body['t0']; $updateData['t1'] = $body['t1']; } elseif ($t0Set || $t1Set) { // Error if only one of t0 or t1 is set $errors[] = "Both t0 and t1 must be provided together."; } if (isset($body['smartDataSources'])) { $smartDataSourcesErrors = SmartDataContext::ValidateSmartDataSources($body['smartDataSources']); if ($smartDataSourcesErrors) { $errors = array_merge($errors, $smartDataSourcesErrors); } $updateData['smartDataSources'] = $body['smartDataSources']; } if (isset($body['smartDataUnits'])) { $smartDataUnitsErrors = SmartDataContext::ValidateSmartDataUnits($body['smartDataUnits']); if ($smartDataUnitsErrors) { $errors = array_merge($errors, $smartDataUnitsErrors); } $updateData['smartDataUnits'] = $body['smartDataUnits']; } if ($errors) { return $this->return_error($response, $errors, 400); } // Call the update method from SmartDataContextCrud $persistence = new SmartDataContextCrud($this->_get_db()); $result = $persistence->update($domain, $id, $updateData); if ($result['success']) { return $this->return_json($response, $result['contents']); } else { return $this->return_error($response, $result['errors'], 400); } } }