From 898009b5f3f7b175ec1bd32cfdb3e445a63b5a0a Mon Sep 17 00:00:00 2001 From: Sukhwinder Dhillon Date: Wed, 3 Jul 2024 15:43:44 +0200 Subject: [PATCH] Introduce api endpoint `channels` --- .../controllers/ApiV1ChannelsController.php | 136 ++++++++++++++++++ run.php | 13 ++ 2 files changed, 149 insertions(+) create mode 100644 application/controllers/ApiV1ChannelsController.php diff --git a/application/controllers/ApiV1ChannelsController.php b/application/controllers/ApiV1ChannelsController.php new file mode 100644 index 00000000..7c5e974b --- /dev/null +++ b/application/controllers/ApiV1ChannelsController.php @@ -0,0 +1,136 @@ +assertPermission('notifications/api/v1'); + + $request = $this->getRequest(); + if (! $request->isApiRequest()) { + $this->httpBadRequest('No API request'); + } + + $method = $request->getMethod(); + if ($method !== 'GET') { + $this->httpBadRequest('Only GET method supported'); + } + + $db = Database::get(); + + /** @var ?string $identifier */ + $identifier = $request->getParam('identifier'); + + if ($identifier && ! Uuid::isValid($identifier)) { + $this->httpBadRequest('The given identifier is not a valid UUID'); + } + + $filter = FilterProcessor::assembleFilter( + QueryString::fromString(rawurldecode(Url::fromRequest()->getQueryString())) + ->on( + QueryString::ON_CONDITION, + function (Filter\Condition $condition) { + $column = $condition->getColumn(); + if (! in_array($column, ['id', 'name', 'type'])) { + $this->httpBadRequest(sprintf( + 'Invalid filter column %s given, only id, name and type are allowed', + $column + )); + } + + if ($column === 'id') { + if (! Uuid::isValid($condition->getValue())) { + $this->httpBadRequest('The given filter id is not a valid UUID'); + } + + $condition->setColumn('external_uuid'); + } + } + )->parse() + ); + + $stmt = (new Select()) + ->distinct() + ->from('channel ch') + ->columns([ + 'channel_id' => 'ch.id', + 'id' => 'ch.external_uuid', + 'name', + 'type', + 'config' + ]); + + if ($identifier !== null) { + $stmt->where(['external_uuid = ?' => $identifier]); + + /** @var stdClass|false $result */ + $result = $db->fetchOne($stmt); + + if ($result === false) { + $this->httpNotFound('Channel not found'); + } + + unset($result->channel_id); + + $this->getResponse() + ->setHttpResponseCode(200) + ->json() + ->setSuccessData((array) $result) + ->sendResponse(); + } else { + if ($filter !== null) { + $stmt->where($filter); + } + + $stmt->limit(500); + $offset = 0; + + ob_end_clean(); + Environment::raiseExecutionTime(); + + $this->getResponse() + ->setHeader('Content-Type', 'application/json') + ->setHeader('Cache-Control', 'no-store') + ->sendResponse(); + + echo '['; + + $res = $db->select($stmt->offset($offset)); + do { + /** @var stdClass $row */ + foreach ($res as $i => $row) { + if ($i > 0 || $offset !== 0) { + echo ",\n"; + } + + unset($row->channel_id); + + echo Json::sanitize($row); + } + + $offset += 500; + $res = $db->select($stmt->offset($offset)); + } while ($res->rowCount()); + + echo ']'; + } + + exit; + } +} diff --git a/run.php b/run.php index 6e610b85..fd185e72 100644 --- a/run.php +++ b/run.php @@ -47,3 +47,16 @@ 1 => 'identifier' ] )); + +$this->addRoute('notifications/api-v1-channels', new Zend_Controller_Router_Route_Regex( + 'notifications/api/v1/channels(?:\/(.+)|\?(.+))?', + [ + 'controller' => 'api-v1-channels', + 'action' => 'index', + 'module' => 'notifications', + 'identifier' => null + ], + [ + 1 => 'identifier' + ] +));