diff options
author | ArthurHoaro <arthur@hoa.ro> | 2020-10-12 11:35:55 +0200 |
---|---|---|
committer | ArthurHoaro <arthur@hoa.ro> | 2020-10-16 20:31:12 +0200 |
commit | 4e3875c0ce7f3b17e3d358dc5ecb1f8bed64546b (patch) | |
tree | 4deb157f03ce7d5402dbfeb65743951d97e527cf /application/bookmark/Bookmark.php | |
parent | 64cac2562661c55f679dba5a7c308e7764f430b5 (diff) | |
download | Shaarli-4e3875c0ce7f3b17e3d358dc5ecb1f8bed64546b.tar.gz Shaarli-4e3875c0ce7f3b17e3d358dc5ecb1f8bed64546b.tar.zst Shaarli-4e3875c0ce7f3b17e3d358dc5ecb1f8bed64546b.zip |
Feature: highlight fulltext search results
How it works:
1. when a fulltext search is made, Shaarli looks for the first
occurence position of every term matching the search. No change here,
but we store these positions in an array, in Bookmark's additionalContent.
2. when formatting bookmarks (through BookmarkFormatter
implementation):
1. first we insert specific tokens at every search result positions
2. we format the content (escape HTML, apply markdown, etc.)
3. as a last step, we replace our token with displayable span
elements
Cons: this tightens coupling between search filters and formatters
Pros: it was absolutely necessary not to perform the
search twice. this solution has close to no impact on performances.
Fixes #205
Diffstat (limited to 'application/bookmark/Bookmark.php')
-rw-r--r-- | application/bookmark/Bookmark.php | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/application/bookmark/Bookmark.php b/application/bookmark/Bookmark.php index fa45d2fc..ea565d1f 100644 --- a/application/bookmark/Bookmark.php +++ b/application/bookmark/Bookmark.php | |||
@@ -54,6 +54,9 @@ class Bookmark | |||
54 | /** @var bool True if the bookmark can only be seen while logged in */ | 54 | /** @var bool True if the bookmark can only be seen while logged in */ |
55 | protected $private; | 55 | protected $private; |
56 | 56 | ||
57 | /** @var mixed[] Available to store any additional content for a bookmark. Currently used for search highlight. */ | ||
58 | protected $additionalContent = []; | ||
59 | |||
57 | /** | 60 | /** |
58 | * Initialize a link from array data. Especially useful to create a Bookmark from former link storage format. | 61 | * Initialize a link from array data. Especially useful to create a Bookmark from former link storage format. |
59 | * | 62 | * |
@@ -95,6 +98,8 @@ class Bookmark | |||
95 | * - the URL with the permalink | 98 | * - the URL with the permalink |
96 | * - the title with the URL | 99 | * - the title with the URL |
97 | * | 100 | * |
101 | * Also make sure that we do not save search highlights in the datastore. | ||
102 | * | ||
98 | * @throws InvalidBookmarkException | 103 | * @throws InvalidBookmarkException |
99 | */ | 104 | */ |
100 | public function validate(): void | 105 | public function validate(): void |
@@ -112,6 +117,9 @@ class Bookmark | |||
112 | if (empty($this->title)) { | 117 | if (empty($this->title)) { |
113 | $this->title = $this->url; | 118 | $this->title = $this->url; |
114 | } | 119 | } |
120 | if (array_key_exists('search_highlight', $this->additionalContent)) { | ||
121 | unset($this->additionalContent['search_highlight']); | ||
122 | } | ||
115 | } | 123 | } |
116 | 124 | ||
117 | /** | 125 | /** |
@@ -436,6 +444,44 @@ class Bookmark | |||
436 | } | 444 | } |
437 | 445 | ||
438 | /** | 446 | /** |
447 | * Get entire additionalContent array. | ||
448 | * | ||
449 | * @return mixed[] | ||
450 | */ | ||
451 | public function getAdditionalContent(): array | ||
452 | { | ||
453 | return $this->additionalContent; | ||
454 | } | ||
455 | |||
456 | /** | ||
457 | * Set a single entry in additionalContent, by key. | ||
458 | * | ||
459 | * @param string $key | ||
460 | * @param mixed|null $value Any type of value can be set. | ||
461 | * | ||
462 | * @return $this | ||
463 | */ | ||
464 | public function addAdditionalContentEntry(string $key, $value): self | ||
465 | { | ||
466 | $this->additionalContent[$key] = $value; | ||
467 | |||
468 | return $this; | ||
469 | } | ||
470 | |||
471 | /** | ||
472 | * Get a single entry in additionalContent, by key. | ||
473 | * | ||
474 | * @param string $key | ||
475 | * @param mixed|null $default | ||
476 | * | ||
477 | * @return mixed|null can be any type or even null. | ||
478 | */ | ||
479 | public function getAdditionalContentEntry(string $key, $default = null) | ||
480 | { | ||
481 | return array_key_exists($key, $this->additionalContent) ? $this->additionalContent[$key] : $default; | ||
482 | } | ||
483 | |||
484 | /** | ||
439 | * Rename a tag in tags list. | 485 | * Rename a tag in tags list. |
440 | * | 486 | * |
441 | * @param string $fromTag | 487 | * @param string $fromTag |