From cf92b4dd1521241eefc58eaf6dcd202cd83969d8 Mon Sep 17 00:00:00 2001 From: ArthurHoaro Date: Sat, 25 May 2019 15:52:27 +0200 Subject: Apply the new system (Bookmark + Service) to the whole code base See https://github.com/shaarli/Shaarli/issues/1307 --- application/api/ApiMiddleware.php | 11 ++-- application/api/ApiUtils.php | 79 +++++++++++------------ application/api/controllers/ApiController.php | 8 +-- application/api/controllers/HistoryController.php | 2 +- application/api/controllers/Info.php | 5 +- application/api/controllers/Links.php | 79 +++++++++-------------- application/api/controllers/Tags.php | 44 ++++++++----- 7 files changed, 110 insertions(+), 118 deletions(-) (limited to 'application/api') diff --git a/application/api/ApiMiddleware.php b/application/api/ApiMiddleware.php index 2d55bda6..4745ac94 100644 --- a/application/api/ApiMiddleware.php +++ b/application/api/ApiMiddleware.php @@ -3,6 +3,7 @@ namespace Shaarli\Api; use Shaarli\Api\Exceptions\ApiAuthorizationException; use Shaarli\Api\Exceptions\ApiException; +use Shaarli\Bookmark\BookmarkFileService; use Shaarli\Config\ConfigManager; use Slim\Container; use Slim\Http\Request; @@ -117,7 +118,7 @@ class ApiMiddleware } /** - * Instantiate a new LinkDB including private links, + * Instantiate a new LinkDB including private bookmarks, * and load in the Slim container. * * FIXME! LinkDB could use a refactoring to avoid this trick. @@ -126,10 +127,10 @@ class ApiMiddleware */ protected function setLinkDb($conf) { - $linkDb = new \Shaarli\Bookmark\LinkDB( - $conf->get('resource.datastore'), - true, - $conf->get('privacy.hide_public_links') + $linkDb = new BookmarkFileService( + $conf, + $this->container->get('history'), + true ); $this->container['db'] = $linkDb; } diff --git a/application/api/ApiUtils.php b/application/api/ApiUtils.php index 5ac07c4d..5156a5f7 100644 --- a/application/api/ApiUtils.php +++ b/application/api/ApiUtils.php @@ -2,6 +2,7 @@ namespace Shaarli\Api; use Shaarli\Api\Exceptions\ApiAuthorizationException; +use Shaarli\Bookmark\Bookmark; use Shaarli\Http\Base64Url; /** @@ -54,28 +55,28 @@ class ApiUtils /** * Format a Link for the REST API. * - * @param array $link Link data read from the datastore. - * @param string $indexUrl Shaarli's index URL (used for relative URL). + * @param Bookmark $bookmark Bookmark 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. */ - public static function formatLink($link, $indexUrl) + public static function formatLink($bookmark, $indexUrl) { - $out['id'] = $link['id']; + $out['id'] = $bookmark->getId(); // Not an internal link - if (! is_note($link['url'])) { - $out['url'] = $link['url']; + if (! $bookmark->isNote()) { + $out['url'] = $bookmark->getUrl(); } else { - $out['url'] = $indexUrl . $link['url']; + $out['url'] = $indexUrl . $bookmark->getUrl(); } - $out['shorturl'] = $link['shorturl']; - $out['title'] = $link['title']; - $out['description'] = $link['description']; - $out['tags'] = preg_split('/\s+/', $link['tags'], -1, PREG_SPLIT_NO_EMPTY); - $out['private'] = $link['private'] == true; - $out['created'] = $link['created']->format(\DateTime::ATOM); - if (! empty($link['updated'])) { - $out['updated'] = $link['updated']->format(\DateTime::ATOM); + $out['shorturl'] = $bookmark->getShortUrl(); + $out['title'] = $bookmark->getTitle(); + $out['description'] = $bookmark->getDescription(); + $out['tags'] = $bookmark->getTags(); + $out['private'] = $bookmark->isPrivate(); + $out['created'] = $bookmark->getCreated()->format(\DateTime::ATOM); + if (! empty($bookmark->getUpdated())) { + $out['updated'] = $bookmark->getUpdated()->format(\DateTime::ATOM); } else { $out['updated'] = ''; } @@ -83,7 +84,7 @@ class ApiUtils } /** - * Convert a link given through a request, to a valid link for LinkDB. + * Convert a link given through a request, to a valid Bookmark for the datastore. * * If no URL is provided, it will generate a local note URL. * If no title is provided, it will use the URL as title. @@ -91,50 +92,42 @@ class ApiUtils * @param array $input Request Link. * @param bool $defaultPrivate Request Link. * - * @return array Formatted link. + * @return Bookmark instance. */ public static function buildLinkFromRequest($input, $defaultPrivate) { - $input['url'] = ! empty($input['url']) ? cleanup_url($input['url']) : ''; + $bookmark = new Bookmark(); + $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; + $bookmark->setTitle(! empty($input['title']) ? $input['title'] : ''); + $bookmark->setUrl($url); + $bookmark->setDescription(! empty($input['description']) ? $input['description'] : ''); + $bookmark->setTags(! empty($input['tags']) ? $input['tags'] : []); + $bookmark->setPrivate($private); + + return $bookmark; } /** * Update link fields using an updated link object. * - * @param array $oldLink data - * @param array $newLink data + * @param Bookmark $oldLink data + * @param Bookmark $newLink data * - * @return array $oldLink updated with $newLink values + * @return Bookmark $oldLink updated with $newLink values */ public static function updateLink($oldLink, $newLink) { - foreach (['title', 'url', 'description', 'tags', 'private'] as $field) { - $oldLink[$field] = $newLink[$field]; - } - $oldLink['updated'] = new \DateTime(); - - if (empty($oldLink['url'])) { - $oldLink['url'] = '?' . $oldLink['shorturl']; - } - - if (empty($oldLink['title'])) { - $oldLink['title'] = $oldLink['url']; - } + $oldLink->setTitle($newLink->getTitle()); + $oldLink->setUrl($newLink->getUrl()); + $oldLink->setDescription($newLink->getDescription()); + $oldLink->setTags($newLink->getTags()); + $oldLink->setPrivate($newLink->isPrivate()); return $oldLink; } @@ -143,7 +136,7 @@ class ApiUtils * Format a Tag for the REST API. * * @param string $tag Tag name - * @param int $occurrences Number of links using this tag + * @param int $occurrences Number of bookmarks using this tag * * @return array Link data formatted for the REST API. */ diff --git a/application/api/controllers/ApiController.php b/application/api/controllers/ApiController.php index a6e7cbab..c4b3d0c3 100644 --- a/application/api/controllers/ApiController.php +++ b/application/api/controllers/ApiController.php @@ -2,7 +2,7 @@ namespace Shaarli\Api\Controllers; -use Shaarli\Bookmark\LinkDB; +use Shaarli\Bookmark\BookmarkServiceInterface; use Shaarli\Config\ConfigManager; use Slim\Container; @@ -26,9 +26,9 @@ abstract class ApiController protected $conf; /** - * @var LinkDB + * @var BookmarkServiceInterface */ - protected $linkDb; + protected $bookmarkService; /** * @var HistoryController @@ -51,7 +51,7 @@ abstract class ApiController { $this->ci = $ci; $this->conf = $ci->get('conf'); - $this->linkDb = $ci->get('db'); + $this->bookmarkService = $ci->get('db'); $this->history = $ci->get('history'); if ($this->conf->get('dev.debug', false)) { $this->jsonStyle = JSON_PRETTY_PRINT; diff --git a/application/api/controllers/HistoryController.php b/application/api/controllers/HistoryController.php index 9afcfa26..505647a9 100644 --- a/application/api/controllers/HistoryController.php +++ b/application/api/controllers/HistoryController.php @@ -41,7 +41,7 @@ class HistoryController extends ApiController throw new ApiBadParametersException('Invalid offset'); } - // limit parameter is either a number of links or 'all' for everything. + // limit parameter is either a number of bookmarks or 'all' for everything. $limit = $request->getParam('limit'); if (empty($limit)) { $limit = count($history); diff --git a/application/api/controllers/Info.php b/application/api/controllers/Info.php index f37dcae5..12f6b2f0 100644 --- a/application/api/controllers/Info.php +++ b/application/api/controllers/Info.php @@ -2,6 +2,7 @@ namespace Shaarli\Api\Controllers; +use Shaarli\Bookmark\BookmarkFilter; use Slim\Http\Request; use Slim\Http\Response; @@ -26,8 +27,8 @@ class Info extends ApiController public function getInfo($request, $response) { $info = [ - 'global_counter' => count($this->linkDb), - 'private_counter' => count_private($this->linkDb), + 'global_counter' => $this->bookmarkService->count(), + 'private_counter' => $this->bookmarkService->count(BookmarkFilter::$PRIVATE), 'settings' => array( 'title' => $this->conf->get('general.title', 'Shaarli'), 'header_link' => $this->conf->get('general.header_link', '?'), diff --git a/application/api/controllers/Links.php b/application/api/controllers/Links.php index ffcfd4c7..29247950 100644 --- a/application/api/controllers/Links.php +++ b/application/api/controllers/Links.php @@ -11,7 +11,7 @@ use Slim\Http\Response; /** * Class Links * - * REST API Controller: all services related to links collection. + * REST API Controller: all services related to bookmarks collection. * * @package Api\Controllers * @see http://shaarli.github.io/api-documentation/#links-links-collection @@ -19,12 +19,12 @@ use Slim\Http\Response; class Links extends ApiController { /** - * @var int Number of links returned if no limit is provided. + * @var int Number of bookmarks returned if no limit is provided. */ public static $DEFAULT_LIMIT = 20; /** - * Retrieve a list of links, allowing different filters. + * Retrieve a list of bookmarks, allowing different filters. * * @param Request $request Slim request. * @param Response $response Slim response. @@ -36,33 +36,32 @@ class Links extends ApiController public function getLinks($request, $response) { $private = $request->getParam('visibility'); - $links = $this->linkDb->filterSearch( + $bookmarks = $this->bookmarkService->search( [ 'searchtags' => $request->getParam('searchtags', ''), 'searchterm' => $request->getParam('searchterm', ''), ], - false, $private ); - // Return links from the {offset}th link, starting from 0. + // Return bookmarks from the {offset}th link, starting from 0. $offset = $request->getParam('offset'); if (! empty($offset) && ! ctype_digit($offset)) { throw new ApiBadParametersException('Invalid offset'); } $offset = ! empty($offset) ? intval($offset) : 0; - if ($offset > count($links)) { + if ($offset > count($bookmarks)) { return $response->withJson([], 200, $this->jsonStyle); } - // limit parameter is either a number of links or 'all' for everything. + // limit parameter is either a number of bookmarks or 'all' for everything. $limit = $request->getParam('limit'); if (empty($limit)) { $limit = self::$DEFAULT_LIMIT; } elseif (ctype_digit($limit)) { $limit = intval($limit); } elseif ($limit === 'all') { - $limit = count($links); + $limit = count($bookmarks); } else { throw new ApiBadParametersException('Invalid limit'); } @@ -72,12 +71,12 @@ class Links extends ApiController $out = []; $index = 0; - foreach ($links as $link) { + foreach ($bookmarks as $bookmark) { if (count($out) >= $limit) { break; } if ($index++ >= $offset) { - $out[] = ApiUtils::formatLink($link, $indexUrl); + $out[] = ApiUtils::formatLink($bookmark, $indexUrl); } } @@ -97,11 +96,11 @@ class Links extends ApiController */ public function getLink($request, $response, $args) { - if (!isset($this->linkDb[$args['id']])) { + if (!$this->bookmarkService->exists($args['id'])) { throw new ApiLinkNotFoundException(); } $index = index_url($this->ci['environment']); - $out = ApiUtils::formatLink($this->linkDb[$args['id']], $index); + $out = ApiUtils::formatLink($this->bookmarkService->get($args['id']), $index); return $response->withJson($out, 200, $this->jsonStyle); } @@ -117,9 +116,11 @@ class Links extends ApiController public function postLink($request, $response) { $data = $request->getParsedBody(); - $link = ApiUtils::buildLinkFromRequest($data, $this->conf->get('privacy.default_private_links')); + $bookmark = 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']))) { + if (! empty($bookmark->getUrl()) + && ! empty($dup = $this->bookmarkService->findByUrl($bookmark->getUrl())) + ) { return $response->withJson( ApiUtils::formatLink($dup, index_url($this->ci['environment'])), 409, @@ -127,23 +128,9 @@ class Links extends ApiController ); } - $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')); - $this->history->addLink($link); - $out = ApiUtils::formatLink($link, index_url($this->ci['environment'])); - $redirect = $this->ci->router->relativePathFor('getLink', ['id' => $link['id']]); + $this->bookmarkService->add($bookmark); + $out = ApiUtils::formatLink($bookmark, index_url($this->ci['environment'])); + $redirect = $this->ci->router->relativePathFor('getLink', ['id' => $bookmark->getId()]); return $response->withAddedHeader('Location', $redirect) ->withJson($out, 201, $this->jsonStyle); } @@ -161,18 +148,18 @@ class Links extends ApiController */ public function putLink($request, $response, $args) { - if (! isset($this->linkDb[$args['id']])) { + if (! $this->bookmarkService->exists($args['id'])) { throw new ApiLinkNotFoundException(); } $index = index_url($this->ci['environment']); $data = $request->getParsedBody(); - $requestLink = ApiUtils::buildLinkFromRequest($data, $this->conf->get('privacy.default_private_links')); + $requestBookmark = ApiUtils::buildLinkFromRequest($data, $this->conf->get('privacy.default_private_links')); // duplicate URL on a different link, return 409 Conflict - if (! empty($requestLink['url']) - && ! empty($dup = $this->linkDb->getLinkFromUrl($requestLink['url'])) - && $dup['id'] != $args['id'] + if (! empty($requestBookmark->getUrl()) + && ! empty($dup = $this->bookmarkService->findByUrl($requestBookmark->getUrl())) + && $dup->getId() != $args['id'] ) { return $response->withJson( ApiUtils::formatLink($dup, $index), @@ -181,13 +168,11 @@ class Links extends ApiController ); } - $responseLink = $this->linkDb[$args['id']]; - $responseLink = ApiUtils::updateLink($responseLink, $requestLink); - $this->linkDb[$responseLink['id']] = $responseLink; - $this->linkDb->save($this->conf->get('resource.page_cache')); - $this->history->updateLink($responseLink); + $responseBookmark = $this->bookmarkService->get($args['id']); + $responseBookmark = ApiUtils::updateLink($responseBookmark, $requestBookmark); + $this->bookmarkService->set($responseBookmark); - $out = ApiUtils::formatLink($responseLink, $index); + $out = ApiUtils::formatLink($responseBookmark, $index); return $response->withJson($out, 200, $this->jsonStyle); } @@ -204,13 +189,11 @@ class Links extends ApiController */ public function deleteLink($request, $response, $args) { - if (! isset($this->linkDb[$args['id']])) { + if (! $this->bookmarkService->exists($args['id'])) { throw new ApiLinkNotFoundException(); } - $link = $this->linkDb[$args['id']]; - unset($this->linkDb[(int) $args['id']]); - $this->linkDb->save($this->conf->get('resource.page_cache')); - $this->history->deleteLink($link); + $bookmark = $this->bookmarkService->get($args['id']); + $this->bookmarkService->remove($bookmark); return $response->withStatus(204); } diff --git a/application/api/controllers/Tags.php b/application/api/controllers/Tags.php index 82f3ef74..e60e00a7 100644 --- a/application/api/controllers/Tags.php +++ b/application/api/controllers/Tags.php @@ -5,6 +5,7 @@ namespace Shaarli\Api\Controllers; use Shaarli\Api\ApiUtils; use Shaarli\Api\Exceptions\ApiBadParametersException; use Shaarli\Api\Exceptions\ApiTagNotFoundException; +use Shaarli\Bookmark\BookmarkFilter; use Slim\Http\Request; use Slim\Http\Response; @@ -18,7 +19,7 @@ use Slim\Http\Response; class Tags extends ApiController { /** - * @var int Number of links returned if no limit is provided. + * @var int Number of bookmarks returned if no limit is provided. */ public static $DEFAULT_LIMIT = 'all'; @@ -35,7 +36,7 @@ class Tags extends ApiController public function getTags($request, $response) { $visibility = $request->getParam('visibility'); - $tags = $this->linkDb->linksCountPerTag([], $visibility); + $tags = $this->bookmarkService->bookmarksCountPerTag([], $visibility); // Return tags from the {offset}th tag, starting from 0. $offset = $request->getParam('offset'); @@ -47,7 +48,7 @@ class Tags extends ApiController return $response->withJson([], 200, $this->jsonStyle); } - // limit parameter is either a number of links or 'all' for everything. + // limit parameter is either a number of bookmarks or 'all' for everything. $limit = $request->getParam('limit'); if (empty($limit)) { $limit = self::$DEFAULT_LIMIT; @@ -87,7 +88,7 @@ class Tags extends ApiController */ public function getTag($request, $response, $args) { - $tags = $this->linkDb->linksCountPerTag(); + $tags = $this->bookmarkService->bookmarksCountPerTag(); if (!isset($tags[$args['tagName']])) { throw new ApiTagNotFoundException(); } @@ -111,7 +112,7 @@ class Tags extends ApiController */ public function putTag($request, $response, $args) { - $tags = $this->linkDb->linksCountPerTag(); + $tags = $this->bookmarkService->bookmarksCountPerTag(); if (! isset($tags[$args['tagName']])) { throw new ApiTagNotFoundException(); } @@ -121,13 +122,19 @@ class Tags extends ApiController throw new ApiBadParametersException('New tag name is required in the request body'); } - $updated = $this->linkDb->renameTag($args['tagName'], $data['name']); - $this->linkDb->save($this->conf->get('resource.page_cache')); - foreach ($updated as $link) { - $this->history->updateLink($link); + $bookmarks = $this->bookmarkService->search( + ['searchtags' => $args['tagName']], + BookmarkFilter::$ALL, + true + ); + foreach ($bookmarks as $bookmark) { + $bookmark->renameTag($args['tagName'], $data['name']); + $this->bookmarkService->set($bookmark, false); + $this->history->updateLink($bookmark); } + $this->bookmarkService->save(); - $tags = $this->linkDb->linksCountPerTag(); + $tags = $this->bookmarkService->bookmarksCountPerTag(); $out = ApiUtils::formatTag($data['name'], $tags[$data['name']]); return $response->withJson($out, 200, $this->jsonStyle); } @@ -145,15 +152,22 @@ class Tags extends ApiController */ public function deleteTag($request, $response, $args) { - $tags = $this->linkDb->linksCountPerTag(); + $tags = $this->bookmarkService->bookmarksCountPerTag(); if (! isset($tags[$args['tagName']])) { throw new ApiTagNotFoundException(); } - $updated = $this->linkDb->renameTag($args['tagName'], null); - $this->linkDb->save($this->conf->get('resource.page_cache')); - foreach ($updated as $link) { - $this->history->updateLink($link); + + $bookmarks = $this->bookmarkService->search( + ['searchtags' => $args['tagName']], + BookmarkFilter::$ALL, + true + ); + foreach ($bookmarks as $bookmark) { + $bookmark->deleteTag($args['tagName']); + $this->bookmarkService->set($bookmark, false); + $this->history->updateLink($bookmark); } + $this->bookmarkService->save(); return $response->withStatus(204); } -- cgit v1.2.3