diff options
20 files changed, 420 insertions, 149 deletions
diff --git a/application/api/controllers/Links.php b/application/api/controllers/Links.php index b83b2260..fe4bdc9f 100644 --- a/application/api/controllers/Links.php +++ b/application/api/controllers/Links.php | |||
@@ -36,13 +36,6 @@ class Links extends ApiController | |||
36 | public function getLinks($request, $response) | 36 | public function getLinks($request, $response) |
37 | { | 37 | { |
38 | $private = $request->getParam('visibility'); | 38 | $private = $request->getParam('visibility'); |
39 | $bookmarks = $this->bookmarkService->search( | ||
40 | [ | ||
41 | 'searchtags' => $request->getParam('searchtags', ''), | ||
42 | 'searchterm' => $request->getParam('searchterm', ''), | ||
43 | ], | ||
44 | $private | ||
45 | ); | ||
46 | 39 | ||
47 | // Return bookmarks from the {offset}th link, starting from 0. | 40 | // Return bookmarks from the {offset}th link, starting from 0. |
48 | $offset = $request->getParam('offset'); | 41 | $offset = $request->getParam('offset'); |
@@ -50,9 +43,6 @@ class Links extends ApiController | |||
50 | throw new ApiBadParametersException('Invalid offset'); | 43 | throw new ApiBadParametersException('Invalid offset'); |
51 | } | 44 | } |
52 | $offset = ! empty($offset) ? intval($offset) : 0; | 45 | $offset = ! empty($offset) ? intval($offset) : 0; |
53 | if ($offset > count($bookmarks)) { | ||
54 | return $response->withJson([], 200, $this->jsonStyle); | ||
55 | } | ||
56 | 46 | ||
57 | // limit parameter is either a number of bookmarks or 'all' for everything. | 47 | // limit parameter is either a number of bookmarks or 'all' for everything. |
58 | $limit = $request->getParam('limit'); | 48 | $limit = $request->getParam('limit'); |
@@ -61,23 +51,33 @@ class Links extends ApiController | |||
61 | } elseif (ctype_digit($limit)) { | 51 | } elseif (ctype_digit($limit)) { |
62 | $limit = intval($limit); | 52 | $limit = intval($limit); |
63 | } elseif ($limit === 'all') { | 53 | } elseif ($limit === 'all') { |
64 | $limit = count($bookmarks); | 54 | $limit = null; |
65 | } else { | 55 | } else { |
66 | throw new ApiBadParametersException('Invalid limit'); | 56 | throw new ApiBadParametersException('Invalid limit'); |
67 | } | 57 | } |
68 | 58 | ||
59 | $searchResult = $this->bookmarkService->search( | ||
60 | [ | ||
61 | 'searchtags' => $request->getParam('searchtags', ''), | ||
62 | 'searchterm' => $request->getParam('searchterm', ''), | ||
63 | ], | ||
64 | $private, | ||
65 | false, | ||
66 | false, | ||
67 | false, | ||
68 | [ | ||
69 | 'limit' => $limit, | ||
70 | 'offset' => $offset, | ||
71 | 'allowOutOfBounds' => true, | ||
72 | ] | ||
73 | ); | ||
74 | |||
69 | // 'environment' is set by Slim and encapsulate $_SERVER. | 75 | // 'environment' is set by Slim and encapsulate $_SERVER. |
70 | $indexUrl = index_url($this->ci['environment']); | 76 | $indexUrl = index_url($this->ci['environment']); |
71 | 77 | ||
72 | $out = []; | 78 | $out = []; |
73 | $index = 0; | 79 | foreach ($searchResult->getBookmarks() as $bookmark) { |
74 | foreach ($bookmarks as $bookmark) { | 80 | $out[] = ApiUtils::formatLink($bookmark, $indexUrl); |
75 | if (count($out) >= $limit) { | ||
76 | break; | ||
77 | } | ||
78 | if ($index++ >= $offset) { | ||
79 | $out[] = ApiUtils::formatLink($bookmark, $indexUrl); | ||
80 | } | ||
81 | } | 81 | } |
82 | 82 | ||
83 | return $response->withJson($out, 200, $this->jsonStyle); | 83 | return $response->withJson($out, 200, $this->jsonStyle); |
diff --git a/application/api/controllers/Tags.php b/application/api/controllers/Tags.php index e60e00a7..5a23f6db 100644 --- a/application/api/controllers/Tags.php +++ b/application/api/controllers/Tags.php | |||
@@ -122,12 +122,12 @@ class Tags extends ApiController | |||
122 | throw new ApiBadParametersException('New tag name is required in the request body'); | 122 | throw new ApiBadParametersException('New tag name is required in the request body'); |
123 | } | 123 | } |
124 | 124 | ||
125 | $bookmarks = $this->bookmarkService->search( | 125 | $searchResult = $this->bookmarkService->search( |
126 | ['searchtags' => $args['tagName']], | 126 | ['searchtags' => $args['tagName']], |
127 | BookmarkFilter::$ALL, | 127 | BookmarkFilter::$ALL, |
128 | true | 128 | true |
129 | ); | 129 | ); |
130 | foreach ($bookmarks as $bookmark) { | 130 | foreach ($searchResult->getBookmarks() as $bookmark) { |
131 | $bookmark->renameTag($args['tagName'], $data['name']); | 131 | $bookmark->renameTag($args['tagName'], $data['name']); |
132 | $this->bookmarkService->set($bookmark, false); | 132 | $this->bookmarkService->set($bookmark, false); |
133 | $this->history->updateLink($bookmark); | 133 | $this->history->updateLink($bookmark); |
@@ -157,12 +157,12 @@ class Tags extends ApiController | |||
157 | throw new ApiTagNotFoundException(); | 157 | throw new ApiTagNotFoundException(); |
158 | } | 158 | } |
159 | 159 | ||
160 | $bookmarks = $this->bookmarkService->search( | 160 | $searchResult = $this->bookmarkService->search( |
161 | ['searchtags' => $args['tagName']], | 161 | ['searchtags' => $args['tagName']], |
162 | BookmarkFilter::$ALL, | 162 | BookmarkFilter::$ALL, |
163 | true | 163 | true |
164 | ); | 164 | ); |
165 | foreach ($bookmarks as $bookmark) { | 165 | foreach ($searchResult->getBookmarks() as $bookmark) { |
166 | $bookmark->deleteTag($args['tagName']); | 166 | $bookmark->deleteTag($args['tagName']); |
167 | $this->bookmarkService->set($bookmark, false); | 167 | $this->bookmarkService->set($bookmark, false); |
168 | $this->history->updateLink($bookmark); | 168 | $this->history->updateLink($bookmark); |
diff --git a/application/bookmark/BookmarkFileService.php b/application/bookmark/BookmarkFileService.php index 6666a251..8ea37427 100644 --- a/application/bookmark/BookmarkFileService.php +++ b/application/bookmark/BookmarkFileService.php | |||
@@ -55,8 +55,12 @@ class BookmarkFileService implements BookmarkServiceInterface | |||
55 | /** | 55 | /** |
56 | * @inheritDoc | 56 | * @inheritDoc |
57 | */ | 57 | */ |
58 | public function __construct(ConfigManager $conf, History $history, Mutex $mutex, bool $isLoggedIn) | 58 | public function __construct( |
59 | { | 59 | ConfigManager $conf, |
60 | History $history, | ||
61 | Mutex $mutex, | ||
62 | bool $isLoggedIn | ||
63 | ) { | ||
60 | $this->conf = $conf; | 64 | $this->conf = $conf; |
61 | $this->history = $history; | 65 | $this->history = $history; |
62 | $this->mutex = $mutex; | 66 | $this->mutex = $mutex; |
@@ -129,8 +133,9 @@ class BookmarkFileService implements BookmarkServiceInterface | |||
129 | string $visibility = null, | 133 | string $visibility = null, |
130 | bool $caseSensitive = false, | 134 | bool $caseSensitive = false, |
131 | bool $untaggedOnly = false, | 135 | bool $untaggedOnly = false, |
132 | bool $ignoreSticky = false | 136 | bool $ignoreSticky = false, |
133 | ) { | 137 | array $pagination = [] |
138 | ): SearchResult { | ||
134 | if ($visibility === null) { | 139 | if ($visibility === null) { |
135 | $visibility = $this->isLoggedIn ? BookmarkFilter::$ALL : BookmarkFilter::$PUBLIC; | 140 | $visibility = $this->isLoggedIn ? BookmarkFilter::$ALL : BookmarkFilter::$PUBLIC; |
136 | } | 141 | } |
@@ -143,13 +148,20 @@ class BookmarkFileService implements BookmarkServiceInterface | |||
143 | $this->bookmarks->reorder('DESC', true); | 148 | $this->bookmarks->reorder('DESC', true); |
144 | } | 149 | } |
145 | 150 | ||
146 | return $this->bookmarkFilter->filter( | 151 | $bookmarks = $this->bookmarkFilter->filter( |
147 | BookmarkFilter::$FILTER_TAG | BookmarkFilter::$FILTER_TEXT, | 152 | BookmarkFilter::$FILTER_TAG | BookmarkFilter::$FILTER_TEXT, |
148 | [$searchTags, $searchTerm], | 153 | [$searchTags, $searchTerm], |
149 | $caseSensitive, | 154 | $caseSensitive, |
150 | $visibility, | 155 | $visibility, |
151 | $untaggedOnly | 156 | $untaggedOnly |
152 | ); | 157 | ); |
158 | |||
159 | return SearchResult::getSearchResult( | ||
160 | $bookmarks, | ||
161 | $pagination['offset'] ?? 0, | ||
162 | $pagination['limit'] ?? null, | ||
163 | $pagination['allowOutOfBounds'] ?? false | ||
164 | ); | ||
153 | } | 165 | } |
154 | 166 | ||
155 | /** | 167 | /** |
@@ -282,7 +294,7 @@ class BookmarkFileService implements BookmarkServiceInterface | |||
282 | */ | 294 | */ |
283 | public function count(string $visibility = null): int | 295 | public function count(string $visibility = null): int |
284 | { | 296 | { |
285 | return count($this->search([], $visibility)); | 297 | return $this->search([], $visibility)->getResultCount(); |
286 | } | 298 | } |
287 | 299 | ||
288 | /** | 300 | /** |
@@ -305,10 +317,10 @@ class BookmarkFileService implements BookmarkServiceInterface | |||
305 | */ | 317 | */ |
306 | public function bookmarksCountPerTag(array $filteringTags = [], string $visibility = null): array | 318 | public function bookmarksCountPerTag(array $filteringTags = [], string $visibility = null): array |
307 | { | 319 | { |
308 | $bookmarks = $this->search(['searchtags' => $filteringTags], $visibility); | 320 | $searchResult = $this->search(['searchtags' => $filteringTags], $visibility); |
309 | $tags = []; | 321 | $tags = []; |
310 | $caseMapping = []; | 322 | $caseMapping = []; |
311 | foreach ($bookmarks as $bookmark) { | 323 | foreach ($searchResult->getBookmarks() as $bookmark) { |
312 | foreach ($bookmark->getTags() as $tag) { | 324 | foreach ($bookmark->getTags() as $tag) { |
313 | if ( | 325 | if ( |
314 | empty($tag) | 326 | empty($tag) |
@@ -357,7 +369,7 @@ class BookmarkFileService implements BookmarkServiceInterface | |||
357 | $previous = null; | 369 | $previous = null; |
358 | $next = null; | 370 | $next = null; |
359 | 371 | ||
360 | foreach ($this->search([], null, false, false, true) as $bookmark) { | 372 | foreach ($this->search([], null, false, false, true)->getBookmarks() as $bookmark) { |
361 | if ($to < $bookmark->getCreated()) { | 373 | if ($to < $bookmark->getCreated()) { |
362 | $next = $bookmark->getCreated(); | 374 | $next = $bookmark->getCreated(); |
363 | } elseif ($from < $bookmark->getCreated() && $to > $bookmark->getCreated()) { | 375 | } elseif ($from < $bookmark->getCreated() && $to > $bookmark->getCreated()) { |
@@ -378,7 +390,7 @@ class BookmarkFileService implements BookmarkServiceInterface | |||
378 | */ | 390 | */ |
379 | public function getLatest(): ?Bookmark | 391 | public function getLatest(): ?Bookmark |
380 | { | 392 | { |
381 | foreach ($this->search([], null, false, false, true) as $bookmark) { | 393 | foreach ($this->search([], null, false, false, true)->getBookmarks() as $bookmark) { |
382 | return $bookmark; | 394 | return $bookmark; |
383 | } | 395 | } |
384 | 396 | ||
diff --git a/application/bookmark/BookmarkServiceInterface.php b/application/bookmark/BookmarkServiceInterface.php index 08cdbb4e..4b1f0daa 100644 --- a/application/bookmark/BookmarkServiceInterface.php +++ b/application/bookmark/BookmarkServiceInterface.php | |||
@@ -44,16 +44,18 @@ interface BookmarkServiceInterface | |||
44 | * @param bool $caseSensitive | 44 | * @param bool $caseSensitive |
45 | * @param bool $untaggedOnly | 45 | * @param bool $untaggedOnly |
46 | * @param bool $ignoreSticky | 46 | * @param bool $ignoreSticky |
47 | * @param array $pagination This array can contain the following keys for pagination: limit, offset. | ||
47 | * | 48 | * |
48 | * @return Bookmark[] | 49 | * @return SearchResult |
49 | */ | 50 | */ |
50 | public function search( | 51 | public function search( |
51 | array $request = [], | 52 | array $request = [], |
52 | string $visibility = null, | 53 | string $visibility = null, |
53 | bool $caseSensitive = false, | 54 | bool $caseSensitive = false, |
54 | bool $untaggedOnly = false, | 55 | bool $untaggedOnly = false, |
55 | bool $ignoreSticky = false | 56 | bool $ignoreSticky = false, |
56 | ); | 57 | array $pagination = [] |
58 | ): SearchResult; | ||
57 | 59 | ||
58 | /** | 60 | /** |
59 | * Get a single bookmark by its ID. | 61 | * Get a single bookmark by its ID. |
diff --git a/application/bookmark/SearchResult.php b/application/bookmark/SearchResult.php new file mode 100644 index 00000000..c0bce311 --- /dev/null +++ b/application/bookmark/SearchResult.php | |||
@@ -0,0 +1,136 @@ | |||
1 | <?php | ||
2 | |||
3 | declare(strict_types=1); | ||
4 | |||
5 | namespace Shaarli\Bookmark; | ||
6 | |||
7 | /** | ||
8 | * Read-only class used to represent search result, including pagination. | ||
9 | */ | ||
10 | class SearchResult | ||
11 | { | ||
12 | /** @var Bookmark[] List of result bookmarks with pagination applied */ | ||
13 | protected $bookmarks; | ||
14 | |||
15 | /** @var int number of Bookmarks found, with pagination applied */ | ||
16 | protected $resultCount; | ||
17 | |||
18 | /** @var int total number of result found */ | ||
19 | protected $totalCount; | ||
20 | |||
21 | /** @var int pagination: limit number of result bookmarks */ | ||
22 | protected $limit; | ||
23 | |||
24 | /** @var int pagination: offset to apply to complete result list */ | ||
25 | protected $offset; | ||
26 | |||
27 | public function __construct(array $bookmarks, int $totalCount, int $offset, ?int $limit) | ||
28 | { | ||
29 | $this->bookmarks = $bookmarks; | ||
30 | $this->resultCount = count($bookmarks); | ||
31 | $this->totalCount = $totalCount; | ||
32 | $this->limit = $limit; | ||
33 | $this->offset = $offset; | ||
34 | } | ||
35 | |||
36 | /** | ||
37 | * Build a SearchResult from provided full result set and pagination settings. | ||
38 | * | ||
39 | * @param Bookmark[] $bookmarks Full set of result which will be filtered | ||
40 | * @param int $offset Start recording results from $offset | ||
41 | * @param int|null $limit End recording results after $limit bookmarks is reached | ||
42 | * @param bool $allowOutOfBounds Set to false to display the last page if the offset is out of bound, | ||
43 | * return empty result set otherwise (default: false) | ||
44 | * | ||
45 | * @return SearchResult | ||
46 | */ | ||
47 | public static function getSearchResult( | ||
48 | $bookmarks, | ||
49 | int $offset = 0, | ||
50 | ?int $limit = null, | ||
51 | bool $allowOutOfBounds = false | ||
52 | ): self { | ||
53 | $totalCount = count($bookmarks); | ||
54 | if (!$allowOutOfBounds && $offset > $totalCount) { | ||
55 | $offset = $limit === null ? 0 : $limit * -1; | ||
56 | } | ||
57 | |||
58 | if ($bookmarks instanceof BookmarkArray) { | ||
59 | $buffer = []; | ||
60 | foreach ($bookmarks as $key => $value) { | ||
61 | $buffer[$key] = $value; | ||
62 | } | ||
63 | $bookmarks = $buffer; | ||
64 | } | ||
65 | |||
66 | return new static( | ||
67 | array_slice($bookmarks, $offset, $limit, true), | ||
68 | $totalCount, | ||
69 | $offset, | ||
70 | $limit | ||
71 | ); | ||
72 | } | ||
73 | |||
74 | /** @return Bookmark[] List of result bookmarks with pagination applied */ | ||
75 | public function getBookmarks(): array | ||
76 | { | ||
77 | return $this->bookmarks; | ||
78 | } | ||
79 | |||
80 | /** @return int number of Bookmarks found, with pagination applied */ | ||
81 | public function getResultCount(): int | ||
82 | { | ||
83 | return $this->resultCount; | ||
84 | } | ||
85 | |||
86 | /** @return int total number of result found */ | ||
87 | public function getTotalCount(): int | ||
88 | { | ||
89 | return $this->totalCount; | ||
90 | } | ||
91 | |||
92 | /** @return int pagination: limit number of result bookmarks */ | ||
93 | public function getLimit(): ?int | ||
94 | { | ||
95 | return $this->limit; | ||
96 | } | ||
97 | |||
98 | /** @return int pagination: offset to apply to complete result list */ | ||
99 | public function getOffset(): int | ||
100 | { | ||
101 | return $this->offset; | ||
102 | } | ||
103 | |||
104 | /** @return int Current page of result set in complete results */ | ||
105 | public function getPage(): int | ||
106 | { | ||
107 | if (empty($this->limit)) { | ||
108 | return $this->offset === 0 ? 1 : 2; | ||
109 | } | ||
110 | $base = $this->offset >= 0 ? $this->offset : $this->totalCount + $this->offset; | ||
111 | |||
112 | return (int) ceil($base / $this->limit) + 1; | ||
113 | } | ||
114 | |||
115 | /** @return int Get the # of the last page */ | ||
116 | public function getLastPage(): int | ||
117 | { | ||
118 | if (empty($this->limit)) { | ||
119 | return $this->offset === 0 ? 1 : 2; | ||
120 | } | ||
121 | |||
122 | return (int) ceil($this->totalCount / $this->limit); | ||
123 | } | ||
124 | |||
125 | /** @return bool Either the current page is the last one or not */ | ||
126 | public function isLastPage(): bool | ||
127 | { | ||
128 | return $this->getPage() === $this->getLastPage(); | ||
129 | } | ||
130 | |||
131 | /** @return bool Either the current page is the first one or not */ | ||
132 | public function isFirstPage(): bool | ||
133 | { | ||
134 | return $this->offset === 0; | ||
135 | } | ||
136 | } | ||
diff --git a/application/feed/FeedBuilder.php b/application/feed/FeedBuilder.php index ed62af26..d5d74fd1 100644 --- a/application/feed/FeedBuilder.php +++ b/application/feed/FeedBuilder.php | |||
@@ -102,22 +102,16 @@ class FeedBuilder | |||
102 | $userInput['searchtags'] = false; | 102 | $userInput['searchtags'] = false; |
103 | } | 103 | } |
104 | 104 | ||
105 | // Optionally filter the results: | 105 | $limit = $this->getLimit($userInput); |
106 | $linksToDisplay = $this->linkDB->search($userInput ?? [], null, false, false, true); | ||
107 | |||
108 | $nblinksToDisplay = $this->getNbLinks(count($linksToDisplay), $userInput); | ||
109 | 106 | ||
110 | // Can't use array_keys() because $link is a LinkDB instance and not a real array. | 107 | // Optionally filter the results: |
111 | $keys = []; | 108 | $searchResult = $this->linkDB->search($userInput ?? [], null, false, false, true, ['limit' => $limit]); |
112 | foreach ($linksToDisplay as $key => $value) { | ||
113 | $keys[] = $key; | ||
114 | } | ||
115 | 109 | ||
116 | $pageaddr = escape(index_url($this->serverInfo)); | 110 | $pageaddr = escape(index_url($this->serverInfo)); |
117 | $this->formatter->addContextData('index_url', $pageaddr); | 111 | $this->formatter->addContextData('index_url', $pageaddr); |
118 | $linkDisplayed = []; | 112 | $links = []; |
119 | for ($i = 0; $i < $nblinksToDisplay && $i < count($keys); $i++) { | 113 | foreach ($searchResult->getBookmarks() as $key => $bookmark) { |
120 | $linkDisplayed[$keys[$i]] = $this->buildItem($feedType, $linksToDisplay[$keys[$i]], $pageaddr); | 114 | $links[$key] = $this->buildItem($feedType, $bookmark, $pageaddr); |
121 | } | 115 | } |
122 | 116 | ||
123 | $data['language'] = $this->getTypeLanguage($feedType); | 117 | $data['language'] = $this->getTypeLanguage($feedType); |
@@ -128,7 +122,7 @@ class FeedBuilder | |||
128 | $data['self_link'] = $pageaddr . $requestUri; | 122 | $data['self_link'] = $pageaddr . $requestUri; |
129 | $data['index_url'] = $pageaddr; | 123 | $data['index_url'] = $pageaddr; |
130 | $data['usepermalinks'] = $this->usePermalinks === true; | 124 | $data['usepermalinks'] = $this->usePermalinks === true; |
131 | $data['links'] = $linkDisplayed; | 125 | $data['links'] = $links; |
132 | 126 | ||
133 | return $data; | 127 | return $data; |
134 | } | 128 | } |
@@ -268,19 +262,18 @@ class FeedBuilder | |||
268 | * If 'nb' not set or invalid, default value: $DEFAULT_NB_LINKS. | 262 | * If 'nb' not set or invalid, default value: $DEFAULT_NB_LINKS. |
269 | * If 'nb' is set to 'all', display all filtered bookmarks (max parameter). | 263 | * If 'nb' is set to 'all', display all filtered bookmarks (max parameter). |
270 | * | 264 | * |
271 | * @param int $max maximum number of bookmarks to display. | ||
272 | * @param array $userInput $_GET. | 265 | * @param array $userInput $_GET. |
273 | * | 266 | * |
274 | * @return int number of bookmarks to display. | 267 | * @return int number of bookmarks to display. |
275 | */ | 268 | */ |
276 | protected function getNbLinks($max, ?array $userInput) | 269 | protected function getLimit(?array $userInput) |
277 | { | 270 | { |
278 | if (empty($userInput['nb'])) { | 271 | if (empty($userInput['nb'])) { |
279 | return self::$DEFAULT_NB_LINKS; | 272 | return self::$DEFAULT_NB_LINKS; |
280 | } | 273 | } |
281 | 274 | ||
282 | if ($userInput['nb'] == 'all') { | 275 | if ($userInput['nb'] == 'all') { |
283 | return $max; | 276 | return null; |
284 | } | 277 | } |
285 | 278 | ||
286 | $intNb = intval($userInput['nb']); | 279 | $intNb = intval($userInput['nb']); |
diff --git a/application/front/controller/admin/ManageTagController.php b/application/front/controller/admin/ManageTagController.php index 8675a0c5..1333cce7 100644 --- a/application/front/controller/admin/ManageTagController.php +++ b/application/front/controller/admin/ManageTagController.php | |||
@@ -57,9 +57,12 @@ class ManageTagController extends ShaarliAdminController | |||
57 | } | 57 | } |
58 | 58 | ||
59 | // TODO: move this to bookmark service | 59 | // TODO: move this to bookmark service |
60 | $count = 0; | 60 | $searchResult = $this->container->bookmarkService->search( |
61 | $bookmarks = $this->container->bookmarkService->search(['searchtags' => $fromTag], BookmarkFilter::$ALL, true); | 61 | ['searchtags' => $fromTag], |
62 | foreach ($bookmarks as $bookmark) { | 62 | BookmarkFilter::$ALL, |
63 | true | ||
64 | ); | ||
65 | foreach ($searchResult->getBookmarks() as $bookmark) { | ||
63 | if (false === $isDelete) { | 66 | if (false === $isDelete) { |
64 | $bookmark->renameTag($fromTag, $toTag); | 67 | $bookmark->renameTag($fromTag, $toTag); |
65 | } else { | 68 | } else { |
@@ -68,11 +71,11 @@ class ManageTagController extends ShaarliAdminController | |||
68 | 71 | ||
69 | $this->container->bookmarkService->set($bookmark, false); | 72 | $this->container->bookmarkService->set($bookmark, false); |
70 | $this->container->history->updateLink($bookmark); | 73 | $this->container->history->updateLink($bookmark); |
71 | $count++; | ||
72 | } | 74 | } |
73 | 75 | ||
74 | $this->container->bookmarkService->save(); | 76 | $this->container->bookmarkService->save(); |
75 | 77 | ||
78 | $count = $searchResult->getResultCount(); | ||
76 | if (true === $isDelete) { | 79 | if (true === $isDelete) { |
77 | $alert = sprintf( | 80 | $alert = sprintf( |
78 | t('The tag was removed from %d bookmark.', 'The tag was removed from %d bookmarks.', $count), | 81 | t('The tag was removed from %d bookmark.', 'The tag was removed from %d bookmarks.', $count), |
diff --git a/application/front/controller/admin/ThumbnailsController.php b/application/front/controller/admin/ThumbnailsController.php index 94d97d4b..5dfea096 100644 --- a/application/front/controller/admin/ThumbnailsController.php +++ b/application/front/controller/admin/ThumbnailsController.php | |||
@@ -22,7 +22,7 @@ class ThumbnailsController extends ShaarliAdminController | |||
22 | public function index(Request $request, Response $response): Response | 22 | public function index(Request $request, Response $response): Response |
23 | { | 23 | { |
24 | $ids = []; | 24 | $ids = []; |
25 | foreach ($this->container->bookmarkService->search() as $bookmark) { | 25 | foreach ($this->container->bookmarkService->search()->getBookmarks() as $bookmark) { |
26 | // A note or not HTTP(S) | 26 | // A note or not HTTP(S) |
27 | if ($bookmark->isNote() || !startsWith(strtolower($bookmark->getUrl()), 'http')) { | 27 | if ($bookmark->isNote() || !startsWith(strtolower($bookmark->getUrl()), 'http')) { |
28 | continue; | 28 | continue; |
diff --git a/application/front/controller/visitor/BookmarkListController.php b/application/front/controller/visitor/BookmarkListController.php index 106440b6..4aae2652 100644 --- a/application/front/controller/visitor/BookmarkListController.php +++ b/application/front/controller/visitor/BookmarkListController.php | |||
@@ -37,7 +37,6 @@ class BookmarkListController extends ShaarliVisitorController | |||
37 | 37 | ||
38 | $searchTags = normalize_spaces($request->getParam('searchtags') ?? ''); | 38 | $searchTags = normalize_spaces($request->getParam('searchtags') ?? ''); |
39 | $searchTerm = escape(normalize_spaces($request->getParam('searchterm') ?? '')); | 39 | $searchTerm = escape(normalize_spaces($request->getParam('searchterm') ?? '')); |
40 | ; | ||
41 | 40 | ||
42 | // Filter bookmarks according search parameters. | 41 | // Filter bookmarks according search parameters. |
43 | $visibility = $this->container->sessionManager->getSessionParameter('visibility'); | 42 | $visibility = $this->container->sessionManager->getSessionParameter('visibility'); |
@@ -45,39 +44,26 @@ class BookmarkListController extends ShaarliVisitorController | |||
45 | 'searchtags' => $searchTags, | 44 | 'searchtags' => $searchTags, |
46 | 'searchterm' => $searchTerm, | 45 | 'searchterm' => $searchTerm, |
47 | ]; | 46 | ]; |
48 | $linksToDisplay = $this->container->bookmarkService->search( | ||
49 | $search, | ||
50 | $visibility, | ||
51 | false, | ||
52 | !!$this->container->sessionManager->getSessionParameter('untaggedonly') | ||
53 | ) ?? []; | ||
54 | |||
55 | // ---- Handle paging. | ||
56 | $keys = []; | ||
57 | foreach ($linksToDisplay as $key => $value) { | ||
58 | $keys[] = $key; | ||
59 | } | ||
60 | |||
61 | $linksPerPage = $this->container->sessionManager->getSessionParameter('LINKS_PER_PAGE', 20) ?: 20; | ||
62 | 47 | ||
63 | // Select articles according to paging. | 48 | // Select articles according to paging. |
64 | $pageCount = (int) ceil(count($keys) / $linksPerPage) ?: 1; | 49 | $page = (int) ($request->getParam('page') ?? 1); |
65 | $page = (int) $request->getParam('page') ?? 1; | ||
66 | $page = $page < 1 ? 1 : $page; | 50 | $page = $page < 1 ? 1 : $page; |
67 | $page = $page > $pageCount ? $pageCount : $page; | 51 | $linksPerPage = $this->container->sessionManager->getSessionParameter('LINKS_PER_PAGE', 20) ?: 20; |
68 | 52 | ||
69 | // Start index. | 53 | $searchResult = $this->container->bookmarkService->search( |
70 | $i = ($page - 1) * $linksPerPage; | 54 | $search, |
71 | $end = $i + $linksPerPage; | 55 | $visibility, |
56 | false, | ||
57 | !!$this->container->sessionManager->getSessionParameter('untaggedonly'), | ||
58 | false, | ||
59 | ['offset' => $linksPerPage * ($page - 1), 'limit' => $linksPerPage] | ||
60 | ) ?? []; | ||
72 | 61 | ||
73 | $linkDisp = []; | ||
74 | $save = false; | 62 | $save = false; |
75 | while ($i < $end && $i < count($keys)) { | 63 | $links = []; |
76 | $save = $this->updateThumbnail($linksToDisplay[$keys[$i]], false) || $save; | 64 | foreach ($searchResult->getBookmarks() as $key => $bookmark) { |
77 | $link = $formatter->format($linksToDisplay[$keys[$i]]); | 65 | $save = $this->updateThumbnail($bookmark, false) || $save; |
78 | 66 | $links[$key] = $formatter->format($bookmark); | |
79 | $linkDisp[$keys[$i]] = $link; | ||
80 | $i++; | ||
81 | } | 67 | } |
82 | 68 | ||
83 | if ($save) { | 69 | if ($save) { |
@@ -87,15 +73,10 @@ class BookmarkListController extends ShaarliVisitorController | |||
87 | // Compute paging navigation | 73 | // Compute paging navigation |
88 | $searchtagsUrl = $searchTags === '' ? '' : '&searchtags=' . urlencode($searchTags); | 74 | $searchtagsUrl = $searchTags === '' ? '' : '&searchtags=' . urlencode($searchTags); |
89 | $searchtermUrl = $searchTerm === '' ? '' : '&searchterm=' . urlencode($searchTerm); | 75 | $searchtermUrl = $searchTerm === '' ? '' : '&searchterm=' . urlencode($searchTerm); |
76 | $page = $searchResult->getPage(); | ||
90 | 77 | ||
91 | $previous_page_url = ''; | 78 | $previousPageUrl = !$searchResult->isLastPage() ? '?page=' . ($page + 1) . $searchtermUrl . $searchtagsUrl : ''; |
92 | if ($i !== count($keys)) { | 79 | $nextPageUrl = !$searchResult->isFirstPage() ? '?page=' . ($page - 1) . $searchtermUrl . $searchtagsUrl : ''; |
93 | $previous_page_url = '?page=' . ($page + 1) . $searchtermUrl . $searchtagsUrl; | ||
94 | } | ||
95 | $next_page_url = ''; | ||
96 | if ($page > 1) { | ||
97 | $next_page_url = '?page=' . ($page - 1) . $searchtermUrl . $searchtagsUrl; | ||
98 | } | ||
99 | 80 | ||
100 | $tagsSeparator = $this->container->conf->get('general.tags_separator', ' '); | 81 | $tagsSeparator = $this->container->conf->get('general.tags_separator', ' '); |
101 | $searchTagsUrlEncoded = array_map('urlencode', tags_str2array($searchTags, $tagsSeparator)); | 82 | $searchTagsUrlEncoded = array_map('urlencode', tags_str2array($searchTags, $tagsSeparator)); |
@@ -105,16 +86,16 @@ class BookmarkListController extends ShaarliVisitorController | |||
105 | $data = array_merge( | 86 | $data = array_merge( |
106 | $this->initializeTemplateVars(), | 87 | $this->initializeTemplateVars(), |
107 | [ | 88 | [ |
108 | 'previous_page_url' => $previous_page_url, | 89 | 'previous_page_url' => $previousPageUrl, |
109 | 'next_page_url' => $next_page_url, | 90 | 'next_page_url' => $nextPageUrl, |
110 | 'page_current' => $page, | 91 | 'page_current' => $page, |
111 | 'page_max' => $pageCount, | 92 | 'page_max' => $searchResult->getLastPage(), |
112 | 'result_count' => count($linksToDisplay), | 93 | 'result_count' => $searchResult->getTotalCount(), |
113 | 'search_term' => escape($searchTerm), | 94 | 'search_term' => escape($searchTerm), |
114 | 'search_tags' => escape($searchTags), | 95 | 'search_tags' => escape($searchTags), |
115 | 'search_tags_url' => $searchTagsUrlEncoded, | 96 | 'search_tags_url' => $searchTagsUrlEncoded, |
116 | 'visibility' => $visibility, | 97 | 'visibility' => $visibility, |
117 | 'links' => $linkDisp, | 98 | 'links' => $links, |
118 | ] | 99 | ] |
119 | ); | 100 | ); |
120 | 101 | ||
diff --git a/application/front/controller/visitor/DailyController.php b/application/front/controller/visitor/DailyController.php index 29492a5f..3739ec16 100644 --- a/application/front/controller/visitor/DailyController.php +++ b/application/front/controller/visitor/DailyController.php | |||
@@ -100,7 +100,7 @@ class DailyController extends ShaarliVisitorController | |||
100 | $days = []; | 100 | $days = []; |
101 | $format = DailyPageHelper::getFormatByType($type); | 101 | $format = DailyPageHelper::getFormatByType($type); |
102 | $length = DailyPageHelper::getRssLengthByType($type); | 102 | $length = DailyPageHelper::getRssLengthByType($type); |
103 | foreach ($this->container->bookmarkService->search() as $bookmark) { | 103 | foreach ($this->container->bookmarkService->search()->getBookmarks() as $bookmark) { |
104 | $day = $bookmark->getCreated()->format($format); | 104 | $day = $bookmark->getCreated()->format($format); |
105 | 105 | ||
106 | // Stop iterating after DAILY_RSS_NB_DAYS entries | 106 | // Stop iterating after DAILY_RSS_NB_DAYS entries |
diff --git a/application/front/controller/visitor/PictureWallController.php b/application/front/controller/visitor/PictureWallController.php index 23553ee6..9c8f07d7 100644 --- a/application/front/controller/visitor/PictureWallController.php +++ b/application/front/controller/visitor/PictureWallController.php | |||
@@ -30,19 +30,19 @@ class PictureWallController extends ShaarliVisitorController | |||
30 | ); | 30 | ); |
31 | 31 | ||
32 | // Optionally filter the results: | 32 | // Optionally filter the results: |
33 | $links = $this->container->bookmarkService->search($request->getQueryParams()); | 33 | $bookmarks = $this->container->bookmarkService->search($request->getQueryParams())->getBookmarks(); |
34 | $linksToDisplay = []; | 34 | $links = []; |
35 | 35 | ||
36 | // Get only bookmarks which have a thumbnail. | 36 | // Get only bookmarks which have a thumbnail. |
37 | // Note: we do not retrieve thumbnails here, the request is too heavy. | 37 | // Note: we do not retrieve thumbnails here, the request is too heavy. |
38 | $formatter = $this->container->formatterFactory->getFormatter('raw'); | 38 | $formatter = $this->container->formatterFactory->getFormatter('raw'); |
39 | foreach ($links as $key => $link) { | 39 | foreach ($bookmarks as $key => $bookmark) { |
40 | if (!empty($link->getThumbnail())) { | 40 | if (!empty($bookmark->getThumbnail())) { |
41 | $linksToDisplay[] = $formatter->format($link); | 41 | $links[] = $formatter->format($bookmark); |
42 | } | 42 | } |
43 | } | 43 | } |
44 | 44 | ||
45 | $data = ['linksToDisplay' => $linksToDisplay]; | 45 | $data = ['linksToDisplay' => $links]; |
46 | $this->executePageHooks('render_picwall', $data, TemplatePage::PICTURE_WALL); | 46 | $this->executePageHooks('render_picwall', $data, TemplatePage::PICTURE_WALL); |
47 | 47 | ||
48 | foreach ($data as $key => $value) { | 48 | foreach ($data as $key => $value) { |
diff --git a/application/netscape/NetscapeBookmarkUtils.php b/application/netscape/NetscapeBookmarkUtils.php index 2d97b4c8..20715bd0 100644 --- a/application/netscape/NetscapeBookmarkUtils.php +++ b/application/netscape/NetscapeBookmarkUtils.php | |||
@@ -64,7 +64,7 @@ class NetscapeBookmarkUtils | |||
64 | } | 64 | } |
65 | 65 | ||
66 | $bookmarkLinks = []; | 66 | $bookmarkLinks = []; |
67 | foreach ($this->bookmarkService->search([], $selection) as $bookmark) { | 67 | foreach ($this->bookmarkService->search([], $selection)->getBookmarks() as $bookmark) { |
68 | $link = $formatter->format($bookmark); | 68 | $link = $formatter->format($bookmark); |
69 | $link['taglist'] = implode(',', $bookmark->getTags()); | 69 | $link['taglist'] = implode(',', $bookmark->getTags()); |
70 | if ($bookmark->isNote() && $prependNoteUrl) { | 70 | if ($bookmark->isNote() && $prependNoteUrl) { |
diff --git a/application/updater/Updater.php b/application/updater/Updater.php index 4f557d0f..11b6c051 100644 --- a/application/updater/Updater.php +++ b/application/updater/Updater.php | |||
@@ -152,7 +152,7 @@ class Updater | |||
152 | { | 152 | { |
153 | $updated = false; | 153 | $updated = false; |
154 | 154 | ||
155 | foreach ($this->bookmarkService->search() as $bookmark) { | 155 | foreach ($this->bookmarkService->search()->getBookmarks() as $bookmark) { |
156 | if ( | 156 | if ( |
157 | $bookmark->isNote() | 157 | $bookmark->isNote() |
158 | && startsWith($bookmark->getUrl(), '?') | 158 | && startsWith($bookmark->getUrl(), '?') |
diff --git a/tests/bookmark/BookmarkFileServiceTest.php b/tests/bookmark/BookmarkFileServiceTest.php index f619aff3..d1af3fb0 100644 --- a/tests/bookmark/BookmarkFileServiceTest.php +++ b/tests/bookmark/BookmarkFileServiceTest.php | |||
@@ -807,7 +807,7 @@ class BookmarkFileServiceTest extends TestCase | |||
807 | $request = ['searchtags' => $tags]; | 807 | $request = ['searchtags' => $tags]; |
808 | $this->assertEquals( | 808 | $this->assertEquals( |
809 | 2, | 809 | 2, |
810 | count($this->privateLinkDB->search($request, null, true)) | 810 | count($this->privateLinkDB->search($request, null, true)->getBookmarks()) |
811 | ); | 811 | ); |
812 | } | 812 | } |
813 | 813 | ||
@@ -820,7 +820,7 @@ class BookmarkFileServiceTest extends TestCase | |||
820 | $request = ['searchtags' => $tags]; | 820 | $request = ['searchtags' => $tags]; |
821 | $this->assertEquals( | 821 | $this->assertEquals( |
822 | 2, | 822 | 2, |
823 | count($this->privateLinkDB->search($request, null, true)) | 823 | count($this->privateLinkDB->search($request, null, true)->getBookmarks()) |
824 | ); | 824 | ); |
825 | } | 825 | } |
826 | 826 | ||
@@ -834,12 +834,12 @@ class BookmarkFileServiceTest extends TestCase | |||
834 | $request = ['searchtags' => $tags]; | 834 | $request = ['searchtags' => $tags]; |
835 | $this->assertEquals( | 835 | $this->assertEquals( |
836 | 1, | 836 | 1, |
837 | count($this->privateLinkDB->search($request, 'all', true)) | 837 | count($this->privateLinkDB->search($request, 'all', true)->getBookmarks()) |
838 | ); | 838 | ); |
839 | 839 | ||
840 | $this->assertEquals( | 840 | $this->assertEquals( |
841 | 0, | 841 | 0, |
842 | count($this->publicLinkDB->search($request, 'public', true)) | 842 | count($this->publicLinkDB->search($request, 'public', true)->getBookmarks()) |
843 | ); | 843 | ); |
844 | } | 844 | } |
845 | 845 | ||
diff --git a/tests/bookmark/SearchResultTest.php b/tests/bookmark/SearchResultTest.php new file mode 100644 index 00000000..12854c1f --- /dev/null +++ b/tests/bookmark/SearchResultTest.php | |||
@@ -0,0 +1,125 @@ | |||
1 | <?php | ||
2 | |||
3 | declare(strict_types=1); | ||
4 | |||
5 | namespace Shaarli\Bookmark; | ||
6 | |||
7 | use Shaarli\TestCase; | ||
8 | |||
9 | /** | ||
10 | * Test SearchResult class. | ||
11 | */ | ||
12 | class SearchResultTest extends TestCase | ||
13 | { | ||
14 | /** Create a SearchResult without any pagination parameter. */ | ||
15 | public function testResultNoParameters(): void | ||
16 | { | ||
17 | $searchResult = SearchResult::getSearchResult($data = ['a', 'b', 'c', 'd', 'e', 'f']); | ||
18 | |||
19 | static::assertSame($data, $searchResult->getBookmarks()); | ||
20 | static::assertSame(6, $searchResult->getResultCount()); | ||
21 | static::assertSame(6, $searchResult->getTotalCount()); | ||
22 | static::assertSame(null, $searchResult->getLimit()); | ||
23 | static::assertSame(0, $searchResult->getOffset()); | ||
24 | static::assertSame(1, $searchResult->getPage()); | ||
25 | static::assertSame(1, $searchResult->getLastPage()); | ||
26 | static::assertTrue($searchResult->isFirstPage()); | ||
27 | static::assertTrue($searchResult->isLastPage()); | ||
28 | } | ||
29 | |||
30 | /** Create a SearchResult with only an offset parameter */ | ||
31 | public function testResultWithOffset(): void | ||
32 | { | ||
33 | $searchResult = SearchResult::getSearchResult(['a', 'b', 'c', 'd', 'e', 'f'], 2); | ||
34 | |||
35 | static::assertSame([2 => 'c', 3 => 'd', 4 => 'e', 5 => 'f'], $searchResult->getBookmarks()); | ||
36 | static::assertSame(4, $searchResult->getResultCount()); | ||
37 | static::assertSame(6, $searchResult->getTotalCount()); | ||
38 | static::assertSame(null, $searchResult->getLimit()); | ||
39 | static::assertSame(2, $searchResult->getOffset()); | ||
40 | static::assertSame(2, $searchResult->getPage()); | ||
41 | static::assertSame(2, $searchResult->getLastPage()); | ||
42 | static::assertFalse($searchResult->isFirstPage()); | ||
43 | static::assertTrue($searchResult->isLastPage()); | ||
44 | } | ||
45 | |||
46 | /** Create a SearchResult with only a limit parameter */ | ||
47 | public function testResultWithLimit(): void | ||
48 | { | ||
49 | $searchResult = SearchResult::getSearchResult(['a', 'b', 'c', 'd', 'e', 'f'], 0, 2); | ||
50 | |||
51 | static::assertSame([0 => 'a', 1 => 'b'], $searchResult->getBookmarks()); | ||
52 | static::assertSame(2, $searchResult->getResultCount()); | ||
53 | static::assertSame(6, $searchResult->getTotalCount()); | ||
54 | static::assertSame(2, $searchResult->getLimit()); | ||
55 | static::assertSame(0, $searchResult->getOffset()); | ||
56 | static::assertSame(1, $searchResult->getPage()); | ||
57 | static::assertSame(3, $searchResult->getLastPage()); | ||
58 | static::assertTrue($searchResult->isFirstPage()); | ||
59 | static::assertFalse($searchResult->isLastPage()); | ||
60 | } | ||
61 | |||
62 | /** Create a SearchResult with offset and limit parameters */ | ||
63 | public function testResultWithLimitAndOffset(): void | ||
64 | { | ||
65 | $searchResult = SearchResult::getSearchResult(['a', 'b', 'c', 'd', 'e', 'f'], 2, 2); | ||
66 | |||
67 | static::assertSame([2 => 'c', 3 => 'd'], $searchResult->getBookmarks()); | ||
68 | static::assertSame(2, $searchResult->getResultCount()); | ||
69 | static::assertSame(6, $searchResult->getTotalCount()); | ||
70 | static::assertSame(2, $searchResult->getLimit()); | ||
71 | static::assertSame(2, $searchResult->getOffset()); | ||
72 | static::assertSame(2, $searchResult->getPage()); | ||
73 | static::assertSame(3, $searchResult->getLastPage()); | ||
74 | static::assertFalse($searchResult->isFirstPage()); | ||
75 | static::assertFalse($searchResult->isLastPage()); | ||
76 | } | ||
77 | |||
78 | /** Create a SearchResult with offset and limit parameters displaying the last page */ | ||
79 | public function testResultWithLimitAndOffsetLastPage(): void | ||
80 | { | ||
81 | $searchResult = SearchResult::getSearchResult(['a', 'b', 'c', 'd', 'e', 'f'], 4, 2); | ||
82 | |||
83 | static::assertSame([4 => 'e', 5 => 'f'], $searchResult->getBookmarks()); | ||
84 | static::assertSame(2, $searchResult->getResultCount()); | ||
85 | static::assertSame(6, $searchResult->getTotalCount()); | ||
86 | static::assertSame(2, $searchResult->getLimit()); | ||
87 | static::assertSame(4, $searchResult->getOffset()); | ||
88 | static::assertSame(3, $searchResult->getPage()); | ||
89 | static::assertSame(3, $searchResult->getLastPage()); | ||
90 | static::assertFalse($searchResult->isFirstPage()); | ||
91 | static::assertTrue($searchResult->isLastPage()); | ||
92 | } | ||
93 | |||
94 | /** Create a SearchResult with offset and limit parameters out of bound (display the last page) */ | ||
95 | public function testResultWithLimitAndOffsetOutOfBounds(): void | ||
96 | { | ||
97 | $searchResult = SearchResult::getSearchResult(['a', 'b', 'c', 'd', 'e', 'f'], 12, 2); | ||
98 | |||
99 | static::assertSame([4 => 'e', 5 => 'f'], $searchResult->getBookmarks()); | ||
100 | static::assertSame(2, $searchResult->getResultCount()); | ||
101 | static::assertSame(6, $searchResult->getTotalCount()); | ||
102 | static::assertSame(2, $searchResult->getLimit()); | ||
103 | static::assertSame(-2, $searchResult->getOffset()); | ||
104 | static::assertSame(3, $searchResult->getPage()); | ||
105 | static::assertSame(3, $searchResult->getLastPage()); | ||
106 | static::assertFalse($searchResult->isFirstPage()); | ||
107 | static::assertTrue($searchResult->isLastPage()); | ||
108 | } | ||
109 | |||
110 | /** Create a SearchResult with offset and limit parameters out of bound (no result) */ | ||
111 | public function testResultWithLimitAndOffsetOutOfBoundsNoResult(): void | ||
112 | { | ||
113 | $searchResult = SearchResult::getSearchResult(['a', 'b', 'c', 'd', 'e', 'f'], 12, 2, true); | ||
114 | |||
115 | static::assertSame([], $searchResult->getBookmarks()); | ||
116 | static::assertSame(0, $searchResult->getResultCount()); | ||
117 | static::assertSame(6, $searchResult->getTotalCount()); | ||
118 | static::assertSame(2, $searchResult->getLimit()); | ||
119 | static::assertSame(12, $searchResult->getOffset()); | ||
120 | static::assertSame(7, $searchResult->getPage()); | ||
121 | static::assertSame(3, $searchResult->getLastPage()); | ||
122 | static::assertFalse($searchResult->isFirstPage()); | ||
123 | static::assertFalse($searchResult->isLastPage()); | ||
124 | } | ||
125 | } | ||
diff --git a/tests/front/controller/admin/ManageTagControllerTest.php b/tests/front/controller/admin/ManageTagControllerTest.php index af6f273f..56a64cbb 100644 --- a/tests/front/controller/admin/ManageTagControllerTest.php +++ b/tests/front/controller/admin/ManageTagControllerTest.php | |||
@@ -6,6 +6,7 @@ namespace Shaarli\Front\Controller\Admin; | |||
6 | 6 | ||
7 | use Shaarli\Bookmark\Bookmark; | 7 | use Shaarli\Bookmark\Bookmark; |
8 | use Shaarli\Bookmark\BookmarkFilter; | 8 | use Shaarli\Bookmark\BookmarkFilter; |
9 | use Shaarli\Bookmark\SearchResult; | ||
9 | use Shaarli\Config\ConfigManager; | 10 | use Shaarli\Config\ConfigManager; |
10 | use Shaarli\Front\Exception\WrongTokenException; | 11 | use Shaarli\Front\Exception\WrongTokenException; |
11 | use Shaarli\Security\SessionManager; | 12 | use Shaarli\Security\SessionManager; |
@@ -100,11 +101,11 @@ class ManageTagControllerTest extends TestCase | |||
100 | ->expects(static::once()) | 101 | ->expects(static::once()) |
101 | ->method('search') | 102 | ->method('search') |
102 | ->with(['searchtags' => 'old-tag'], BookmarkFilter::$ALL, true) | 103 | ->with(['searchtags' => 'old-tag'], BookmarkFilter::$ALL, true) |
103 | ->willReturnCallback(function () use ($bookmark1, $bookmark2): array { | 104 | ->willReturnCallback(function () use ($bookmark1, $bookmark2): SearchResult { |
104 | $bookmark1->expects(static::once())->method('renameTag')->with('old-tag', 'new-tag'); | 105 | $bookmark1->expects(static::once())->method('renameTag')->with('old-tag', 'new-tag'); |
105 | $bookmark2->expects(static::once())->method('renameTag')->with('old-tag', 'new-tag'); | 106 | $bookmark2->expects(static::once())->method('renameTag')->with('old-tag', 'new-tag'); |
106 | 107 | ||
107 | return [$bookmark1, $bookmark2]; | 108 | return SearchResult::getSearchResult([$bookmark1, $bookmark2]); |
108 | }) | 109 | }) |
109 | ; | 110 | ; |
110 | $this->container->bookmarkService | 111 | $this->container->bookmarkService |
@@ -153,11 +154,11 @@ class ManageTagControllerTest extends TestCase | |||
153 | ->expects(static::once()) | 154 | ->expects(static::once()) |
154 | ->method('search') | 155 | ->method('search') |
155 | ->with(['searchtags' => 'old-tag'], BookmarkFilter::$ALL, true) | 156 | ->with(['searchtags' => 'old-tag'], BookmarkFilter::$ALL, true) |
156 | ->willReturnCallback(function () use ($bookmark1, $bookmark2): array { | 157 | ->willReturnCallback(function () use ($bookmark1, $bookmark2): SearchResult { |
157 | $bookmark1->expects(static::once())->method('deleteTag')->with('old-tag'); | 158 | $bookmark1->expects(static::once())->method('deleteTag')->with('old-tag'); |
158 | $bookmark2->expects(static::once())->method('deleteTag')->with('old-tag'); | 159 | $bookmark2->expects(static::once())->method('deleteTag')->with('old-tag'); |
159 | 160 | ||
160 | return [$bookmark1, $bookmark2]; | 161 | return SearchResult::getSearchResult([$bookmark1, $bookmark2]); |
161 | }) | 162 | }) |
162 | ; | 163 | ; |
163 | $this->container->bookmarkService | 164 | $this->container->bookmarkService |
diff --git a/tests/front/controller/admin/ThumbnailsControllerTest.php b/tests/front/controller/admin/ThumbnailsControllerTest.php index e5749654..0c9b63c3 100644 --- a/tests/front/controller/admin/ThumbnailsControllerTest.php +++ b/tests/front/controller/admin/ThumbnailsControllerTest.php | |||
@@ -6,6 +6,7 @@ namespace Shaarli\Front\Controller\Admin; | |||
6 | 6 | ||
7 | use Shaarli\Bookmark\Bookmark; | 7 | use Shaarli\Bookmark\Bookmark; |
8 | use Shaarli\Bookmark\Exception\BookmarkNotFoundException; | 8 | use Shaarli\Bookmark\Exception\BookmarkNotFoundException; |
9 | use Shaarli\Bookmark\SearchResult; | ||
9 | use Shaarli\TestCase; | 10 | use Shaarli\TestCase; |
10 | use Shaarli\Thumbnailer; | 11 | use Shaarli\Thumbnailer; |
11 | use Slim\Http\Request; | 12 | use Slim\Http\Request; |
@@ -40,12 +41,12 @@ class ThumbnailsControllerTest extends TestCase | |||
40 | $this->container->bookmarkService | 41 | $this->container->bookmarkService |
41 | ->expects(static::once()) | 42 | ->expects(static::once()) |
42 | ->method('search') | 43 | ->method('search') |
43 | ->willReturn([ | 44 | ->willReturn(SearchResult::getSearchResult([ |
44 | (new Bookmark())->setId(1)->setUrl('http://url1.tld')->setTitle('Title 1'), | 45 | (new Bookmark())->setId(1)->setUrl('http://url1.tld')->setTitle('Title 1'), |
45 | (new Bookmark())->setId(2)->setUrl('?abcdef')->setTitle('Note 1'), | 46 | (new Bookmark())->setId(2)->setUrl('?abcdef')->setTitle('Note 1'), |
46 | (new Bookmark())->setId(3)->setUrl('http://url2.tld')->setTitle('Title 2'), | 47 | (new Bookmark())->setId(3)->setUrl('http://url2.tld')->setTitle('Title 2'), |
47 | (new Bookmark())->setId(4)->setUrl('ftp://domain.tld', ['ftp'])->setTitle('FTP'), | 48 | (new Bookmark())->setId(4)->setUrl('ftp://domain.tld', ['ftp'])->setTitle('FTP'), |
48 | ]) | 49 | ])) |
49 | ; | 50 | ; |
50 | 51 | ||
51 | $result = $this->controller->index($request, $response); | 52 | $result = $this->controller->index($request, $response); |
diff --git a/tests/front/controller/visitor/BookmarkListControllerTest.php b/tests/front/controller/visitor/BookmarkListControllerTest.php index dec938f2..0fbab9d4 100644 --- a/tests/front/controller/visitor/BookmarkListControllerTest.php +++ b/tests/front/controller/visitor/BookmarkListControllerTest.php | |||
@@ -6,6 +6,7 @@ namespace Shaarli\Front\Controller\Visitor; | |||
6 | 6 | ||
7 | use Shaarli\Bookmark\Bookmark; | 7 | use Shaarli\Bookmark\Bookmark; |
8 | use Shaarli\Bookmark\Exception\BookmarkNotFoundException; | 8 | use Shaarli\Bookmark\Exception\BookmarkNotFoundException; |
9 | use Shaarli\Bookmark\SearchResult; | ||
9 | use Shaarli\Config\ConfigManager; | 10 | use Shaarli\Config\ConfigManager; |
10 | use Shaarli\Security\LoginManager; | 11 | use Shaarli\Security\LoginManager; |
11 | use Shaarli\TestCase; | 12 | use Shaarli\TestCase; |
@@ -45,13 +46,15 @@ class BookmarkListControllerTest extends TestCase | |||
45 | ['searchtags' => '', 'searchterm' => ''], | 46 | ['searchtags' => '', 'searchterm' => ''], |
46 | null, | 47 | null, |
47 | false, | 48 | false, |
48 | false | 49 | false, |
50 | false, | ||
51 | ['offset' => 0, 'limit' => 2] | ||
49 | ) | 52 | ) |
50 | ->willReturn([ | 53 | ->willReturn(SearchResult::getSearchResult([ |
51 | (new Bookmark())->setId(1)->setUrl('http://url1.tld')->setTitle('Title 1'), | 54 | (new Bookmark())->setId(1)->setUrl('http://url1.tld')->setTitle('Title 1'), |
52 | (new Bookmark())->setId(2)->setUrl('http://url2.tld')->setTitle('Title 2'), | 55 | (new Bookmark())->setId(2)->setUrl('http://url2.tld')->setTitle('Title 2'), |
53 | (new Bookmark())->setId(3)->setUrl('http://url3.tld')->setTitle('Title 3'), | 56 | (new Bookmark())->setId(3)->setUrl('http://url3.tld')->setTitle('Title 3'), |
54 | ] | 57 | ], 0, 2) |
55 | ); | 58 | ); |
56 | 59 | ||
57 | $this->container->sessionManager | 60 | $this->container->sessionManager |
@@ -119,13 +122,15 @@ class BookmarkListControllerTest extends TestCase | |||
119 | ['searchtags' => '', 'searchterm' => ''], | 122 | ['searchtags' => '', 'searchterm' => ''], |
120 | null, | 123 | null, |
121 | false, | 124 | false, |
122 | false | 125 | false, |
126 | false, | ||
127 | ['offset' => 2, 'limit' => 2] | ||
123 | ) | 128 | ) |
124 | ->willReturn([ | 129 | ->willReturn(SearchResult::getSearchResult([ |
125 | (new Bookmark())->setId(1)->setUrl('http://url1.tld')->setTitle('Title 1'), | 130 | (new Bookmark())->setId(1)->setUrl('http://url1.tld')->setTitle('Title 1'), |
126 | (new Bookmark())->setId(2)->setUrl('http://url2.tld')->setTitle('Title 2'), | 131 | (new Bookmark())->setId(2)->setUrl('http://url2.tld')->setTitle('Title 2'), |
127 | (new Bookmark())->setId(3)->setUrl('http://url3.tld')->setTitle('Title 3'), | 132 | (new Bookmark())->setId(3)->setUrl('http://url3.tld')->setTitle('Title 3'), |
128 | ]) | 133 | ], 2, 2)) |
129 | ; | 134 | ; |
130 | 135 | ||
131 | $this->container->sessionManager | 136 | $this->container->sessionManager |
@@ -207,13 +212,15 @@ class BookmarkListControllerTest extends TestCase | |||
207 | ['searchtags' => 'abc@def', 'searchterm' => 'ghi jkl'], | 212 | ['searchtags' => 'abc@def', 'searchterm' => 'ghi jkl'], |
208 | 'private', | 213 | 'private', |
209 | false, | 214 | false, |
210 | true | 215 | true, |
216 | false, | ||
217 | ['offset' => 0, 'limit' => 2] | ||
211 | ) | 218 | ) |
212 | ->willReturn([ | 219 | ->willReturn(SearchResult::getSearchResult([ |
213 | (new Bookmark())->setId(1)->setUrl('http://url1.tld')->setTitle('Title 1'), | 220 | (new Bookmark())->setId(1)->setUrl('http://url1.tld')->setTitle('Title 1'), |
214 | (new Bookmark())->setId(2)->setUrl('http://url2.tld')->setTitle('Title 2'), | 221 | (new Bookmark())->setId(2)->setUrl('http://url2.tld')->setTitle('Title 2'), |
215 | (new Bookmark())->setId(3)->setUrl('http://url3.tld')->setTitle('Title 3'), | 222 | (new Bookmark())->setId(3)->setUrl('http://url3.tld')->setTitle('Title 3'), |
216 | ]) | 223 | ], 0, 2)) |
217 | ; | 224 | ; |
218 | 225 | ||
219 | $result = $this->controller->index($request, $response); | 226 | $result = $this->controller->index($request, $response); |
@@ -358,13 +365,13 @@ class BookmarkListControllerTest extends TestCase | |||
358 | $this->container->bookmarkService | 365 | $this->container->bookmarkService |
359 | ->expects(static::once()) | 366 | ->expects(static::once()) |
360 | ->method('search') | 367 | ->method('search') |
361 | ->willReturn([ | 368 | ->willReturn(SearchResult::getSearchResult([ |
362 | (new Bookmark())->setId(1)->setUrl('https://url1.tld')->setTitle('Title 1')->setThumbnail(false), | 369 | (new Bookmark())->setId(1)->setUrl('https://url1.tld')->setTitle('Title 1')->setThumbnail(false), |
363 | $b1 = (new Bookmark())->setId(2)->setUrl('https://url2.tld')->setTitle('Title 2'), | 370 | $b1 = (new Bookmark())->setId(2)->setUrl('https://url2.tld')->setTitle('Title 2'), |
364 | (new Bookmark())->setId(3)->setUrl('https://url3.tld')->setTitle('Title 3')->setThumbnail(false), | 371 | (new Bookmark())->setId(3)->setUrl('https://url3.tld')->setTitle('Title 3')->setThumbnail(false), |
365 | $b2 = (new Bookmark())->setId(2)->setUrl('https://url4.tld')->setTitle('Title 4'), | 372 | $b2 = (new Bookmark())->setId(2)->setUrl('https://url4.tld')->setTitle('Title 4'), |
366 | (new Bookmark())->setId(2)->setUrl('ftp://url5.tld', ['ftp'])->setTitle('Title 5'), | 373 | (new Bookmark())->setId(2)->setUrl('ftp://url5.tld', ['ftp'])->setTitle('Title 5'), |
367 | ]) | 374 | ])) |
368 | ; | 375 | ; |
369 | $this->container->bookmarkService | 376 | $this->container->bookmarkService |
370 | ->expects(static::exactly(2)) | 377 | ->expects(static::exactly(2)) |
diff --git a/tests/front/controller/visitor/DailyControllerTest.php b/tests/front/controller/visitor/DailyControllerTest.php index 70fbce54..821ba321 100644 --- a/tests/front/controller/visitor/DailyControllerTest.php +++ b/tests/front/controller/visitor/DailyControllerTest.php | |||
@@ -5,6 +5,7 @@ declare(strict_types=1); | |||
5 | namespace Shaarli\Front\Controller\Visitor; | 5 | namespace Shaarli\Front\Controller\Visitor; |
6 | 6 | ||
7 | use Shaarli\Bookmark\Bookmark; | 7 | use Shaarli\Bookmark\Bookmark; |
8 | use Shaarli\Bookmark\SearchResult; | ||
8 | use Shaarli\Feed\CachedPage; | 9 | use Shaarli\Feed\CachedPage; |
9 | use Shaarli\TestCase; | 10 | use Shaarli\TestCase; |
10 | use Slim\Http\Request; | 11 | use Slim\Http\Request; |
@@ -347,13 +348,15 @@ class DailyControllerTest extends TestCase | |||
347 | $request = $this->createMock(Request::class); | 348 | $request = $this->createMock(Request::class); |
348 | $response = new Response(); | 349 | $response = new Response(); |
349 | 350 | ||
350 | $this->container->bookmarkService->expects(static::once())->method('search')->willReturn([ | 351 | $this->container->bookmarkService->expects(static::once())->method('search')->willReturn( |
351 | (new Bookmark())->setId(1)->setCreated($dates[0])->setUrl('http://domain.tld/1'), | 352 | SearchResult::getSearchResult([ |
352 | (new Bookmark())->setId(2)->setCreated($dates[1])->setUrl('http://domain.tld/2'), | 353 | (new Bookmark())->setId(1)->setCreated($dates[0])->setUrl('http://domain.tld/1'), |
353 | (new Bookmark())->setId(3)->setCreated($dates[1])->setUrl('http://domain.tld/3'), | 354 | (new Bookmark())->setId(2)->setCreated($dates[1])->setUrl('http://domain.tld/2'), |
354 | (new Bookmark())->setId(4)->setCreated($dates[2])->setUrl('http://domain.tld/4'), | 355 | (new Bookmark())->setId(3)->setCreated($dates[1])->setUrl('http://domain.tld/3'), |
355 | (new Bookmark())->setId(5)->setCreated($dates[3])->setUrl('http://domain.tld/5'), | 356 | (new Bookmark())->setId(4)->setCreated($dates[2])->setUrl('http://domain.tld/4'), |
356 | ]); | 357 | (new Bookmark())->setId(5)->setCreated($dates[3])->setUrl('http://domain.tld/5'), |
358 | ]) | ||
359 | ); | ||
357 | 360 | ||
358 | $this->container->pageCacheManager | 361 | $this->container->pageCacheManager |
359 | ->expects(static::once()) | 362 | ->expects(static::once()) |
@@ -454,7 +457,9 @@ class DailyControllerTest extends TestCase | |||
454 | $request = $this->createMock(Request::class); | 457 | $request = $this->createMock(Request::class); |
455 | $response = new Response(); | 458 | $response = new Response(); |
456 | 459 | ||
457 | $this->container->bookmarkService->expects(static::once())->method('search')->willReturn([]); | 460 | $this->container->bookmarkService |
461 | ->expects(static::once())->method('search') | ||
462 | ->willReturn(SearchResult::getSearchResult([])); | ||
458 | 463 | ||
459 | // Save RainTPL assigned variables | 464 | // Save RainTPL assigned variables |
460 | $assignedVariables = []; | 465 | $assignedVariables = []; |
@@ -613,11 +618,13 @@ class DailyControllerTest extends TestCase | |||
613 | }); | 618 | }); |
614 | $response = new Response(); | 619 | $response = new Response(); |
615 | 620 | ||
616 | $this->container->bookmarkService->expects(static::once())->method('search')->willReturn([ | 621 | $this->container->bookmarkService->expects(static::once())->method('search')->willReturn( |
617 | (new Bookmark())->setId(1)->setCreated($dates[0])->setUrl('http://domain.tld/1'), | 622 | SearchResult::getSearchResult([ |
618 | (new Bookmark())->setId(2)->setCreated($dates[1])->setUrl('http://domain.tld/2'), | 623 | (new Bookmark())->setId(1)->setCreated($dates[0])->setUrl('http://domain.tld/1'), |
619 | (new Bookmark())->setId(3)->setCreated($dates[1])->setUrl('http://domain.tld/3'), | 624 | (new Bookmark())->setId(2)->setCreated($dates[1])->setUrl('http://domain.tld/2'), |
620 | ]); | 625 | (new Bookmark())->setId(3)->setCreated($dates[1])->setUrl('http://domain.tld/3'), |
626 | ]) | ||
627 | ); | ||
621 | 628 | ||
622 | // Save RainTPL assigned variables | 629 | // Save RainTPL assigned variables |
623 | $assignedVariables = []; | 630 | $assignedVariables = []; |
@@ -674,11 +681,13 @@ class DailyControllerTest extends TestCase | |||
674 | }); | 681 | }); |
675 | $response = new Response(); | 682 | $response = new Response(); |
676 | 683 | ||
677 | $this->container->bookmarkService->expects(static::once())->method('search')->willReturn([ | 684 | $this->container->bookmarkService->expects(static::once())->method('search')->willReturn( |
678 | (new Bookmark())->setId(1)->setCreated($dates[0])->setUrl('http://domain.tld/1'), | 685 | SearchResult::getSearchResult([ |
679 | (new Bookmark())->setId(2)->setCreated($dates[1])->setUrl('http://domain.tld/2'), | 686 | (new Bookmark())->setId(1)->setCreated($dates[0])->setUrl('http://domain.tld/1'), |
680 | (new Bookmark())->setId(3)->setCreated($dates[1])->setUrl('http://domain.tld/3'), | 687 | (new Bookmark())->setId(2)->setCreated($dates[1])->setUrl('http://domain.tld/2'), |
681 | ]); | 688 | (new Bookmark())->setId(3)->setCreated($dates[1])->setUrl('http://domain.tld/3'), |
689 | ]) | ||
690 | ); | ||
682 | 691 | ||
683 | // Save RainTPL assigned variables | 692 | // Save RainTPL assigned variables |
684 | $assignedVariables = []; | 693 | $assignedVariables = []; |
diff --git a/tests/front/controller/visitor/PictureWallControllerTest.php b/tests/front/controller/visitor/PictureWallControllerTest.php index b868231d..429e99a2 100644 --- a/tests/front/controller/visitor/PictureWallControllerTest.php +++ b/tests/front/controller/visitor/PictureWallControllerTest.php | |||
@@ -5,6 +5,7 @@ declare(strict_types=1); | |||
5 | namespace Shaarli\Front\Controller\Visitor; | 5 | namespace Shaarli\Front\Controller\Visitor; |
6 | 6 | ||
7 | use Shaarli\Bookmark\Bookmark; | 7 | use Shaarli\Bookmark\Bookmark; |
8 | use Shaarli\Bookmark\SearchResult; | ||
8 | use Shaarli\Config\ConfigManager; | 9 | use Shaarli\Config\ConfigManager; |
9 | use Shaarli\Front\Exception\ThumbnailsDisabledException; | 10 | use Shaarli\Front\Exception\ThumbnailsDisabledException; |
10 | use Shaarli\TestCase; | 11 | use Shaarli\TestCase; |
@@ -50,17 +51,17 @@ class PictureWallControllerTest extends TestCase | |||
50 | $this->container->bookmarkService | 51 | $this->container->bookmarkService |
51 | ->expects(static::once()) | 52 | ->expects(static::once()) |
52 | ->method('search') | 53 | ->method('search') |
53 | ->willReturnCallback(function (array $parameters, ?string $visibility): array { | 54 | ->willReturnCallback(function (array $parameters, ?string $visibility): SearchResult { |
54 | // Visibility is set through the container, not the call | 55 | // Visibility is set through the container, not the call |
55 | static::assertNull($visibility); | 56 | static::assertNull($visibility); |
56 | 57 | ||
57 | // No query parameters | 58 | // No query parameters |
58 | if (count($parameters) === 0) { | 59 | if (count($parameters) === 0) { |
59 | return [ | 60 | return SearchResult::getSearchResult([ |
60 | (new Bookmark())->setId(1)->setUrl('http://url.tld')->setThumbnail('thumb1'), | 61 | (new Bookmark())->setId(1)->setUrl('http://url.tld')->setThumbnail('thumb1'), |
61 | (new Bookmark())->setId(2)->setUrl('http://url2.tld'), | 62 | (new Bookmark())->setId(2)->setUrl('http://url2.tld'), |
62 | (new Bookmark())->setId(3)->setUrl('http://url3.tld')->setThumbnail('thumb2'), | 63 | (new Bookmark())->setId(3)->setUrl('http://url3.tld')->setThumbnail('thumb2'), |
63 | ]; | 64 | ]); |
64 | } | 65 | } |
65 | }) | 66 | }) |
66 | ; | 67 | ; |