From 68016e37983b882c51c6ac92da6f6cc1250676e5 Mon Sep 17 00:00:00 2001 From: ArthurHoaro Date: Thu, 5 Jan 2017 15:58:24 +0100 Subject: REST API: implement POST link service --- application/api/ApiUtils.php | 35 +++++++++++++++++++-- application/api/controllers/ApiController.php | 10 ++++++ application/api/controllers/Links.php | 44 ++++++++++++++++++++++++++- 3 files changed, 86 insertions(+), 3 deletions(-) (limited to 'application/api') diff --git a/application/api/ApiUtils.php b/application/api/ApiUtils.php index d4015865..b8155a34 100644 --- a/application/api/ApiUtils.php +++ b/application/api/ApiUtils.php @@ -12,7 +12,7 @@ class ApiUtils /** * Validates a JWT token authenticity. * - * @param string $token JWT token extracted from the headers. + * @param string $token JWT token extracted from the headers. * @param string $secret API secret set in the settings. * * @throws ApiAuthorizationException the token is not valid. @@ -50,7 +50,7 @@ class ApiUtils /** * Format a Link for the REST API. * - * @param array $link Link data read from the datastore. + * @param array $link Link data read from the datastore. * @param string $indexUrl Shaarli's index URL (used for relative URL). * * @return array Link data formatted for the REST API. @@ -77,4 +77,35 @@ class ApiUtils } return $out; } + + /** + * Convert a link given through a request, to a valid link for LinkDB. + * + * If no URL is provided, it will generate a local note URL. + * If no title is provided, it will use the URL as title. + * + * @param array $input Request Link. + * @param bool $defaultPrivate Request Link. + * + * @return array Formatted link. + */ + public static function buildLinkFromRequest($input, $defaultPrivate) + { + $input['url'] = ! empty($input['url']) ? cleanup_url($input['url']) : ''; + if (isset($input['private'])) { + $private = filter_var($input['private'], FILTER_VALIDATE_BOOLEAN); + } else { + $private = $defaultPrivate; + } + + $link = [ + 'title' => ! empty($input['title']) ? $input['title'] : $input['url'], + 'url' => $input['url'], + 'description' => ! empty($input['description']) ? $input['description'] : '', + 'tags' => ! empty($input['tags']) ? implode(' ', $input['tags']) : '', + 'private' => $private, + 'created' => new \DateTime(), + ]; + return $link; + } } diff --git a/application/api/controllers/ApiController.php b/application/api/controllers/ApiController.php index 1dd47f17..f35b923a 100644 --- a/application/api/controllers/ApiController.php +++ b/application/api/controllers/ApiController.php @@ -51,4 +51,14 @@ abstract class ApiController $this->jsonStyle = null; } } + + /** + * Get the container. + * + * @return Container + */ + public function getCi() + { + return $this->ci; + } } diff --git a/application/api/controllers/Links.php b/application/api/controllers/Links.php index d4f1a09c..0db10fd0 100644 --- a/application/api/controllers/Links.php +++ b/application/api/controllers/Links.php @@ -97,11 +97,53 @@ class Links extends ApiController */ public function getLink($request, $response, $args) { - if (! isset($this->linkDb[$args['id']])) { + if (!isset($this->linkDb[$args['id']])) { throw new ApiLinkNotFoundException(); } $index = index_url($this->ci['environment']); $out = ApiUtils::formatLink($this->linkDb[$args['id']], $index); + return $response->withJson($out, 200, $this->jsonStyle); } + + /** + * Creates a new link from posted request body. + * + * @param Request $request Slim request. + * @param Response $response Slim response. + * + * @return Response response. + */ + public function postLink($request, $response) + { + $data = $request->getParsedBody(); + $link = ApiUtils::buildLinkFromRequest($data, $this->conf->get('privacy.default_private_links')); + // duplicate by URL, return 409 Conflict + if (! empty($link['url']) && ! empty($dup = $this->linkDb->getLinkFromUrl($link['url']))) { + return $response->withJson( + ApiUtils::formatLink($dup, index_url($this->ci['environment'])), + 409, + $this->jsonStyle + ); + } + + $link['id'] = $this->linkDb->getNextId(); + $link['shorturl'] = link_small_hash($link['created'], $link['id']); + + // note: general relative URL + if (empty($link['url'])) { + $link['url'] = '?' . $link['shorturl']; + } + + if (empty($link['title'])) { + $link['title'] = $link['url']; + } + + $this->linkDb[$link['id']] = $link; + $this->linkDb->save($this->conf->get('resource.page_cache')); + $out = ApiUtils::formatLink($link, index_url($this->ci['environment'])); + $redirect = $this->ci->router->relativePathFor('getLink', ['id' => $link['id']]); + return $response->withAddedHeader('Location', $redirect) + ->withJson($out, 201, $this->jsonStyle); + } } -- cgit v1.2.3