diff options
Diffstat (limited to 'application/formatter')
-rw-r--r-- | application/formatter/BookmarkDefaultFormatter.php | 140 | ||||
-rw-r--r-- | application/formatter/BookmarkFormatter.php | 82 | ||||
-rw-r--r-- | application/formatter/BookmarkMarkdownExtraFormatter.php | 24 | ||||
-rw-r--r-- | application/formatter/BookmarkMarkdownFormatter.php | 20 | ||||
-rw-r--r-- | application/formatter/BookmarkRawFormatter.php | 4 | ||||
-rw-r--r-- | application/formatter/FormatterFactory.php | 2 |
6 files changed, 247 insertions, 25 deletions
diff --git a/application/formatter/BookmarkDefaultFormatter.php b/application/formatter/BookmarkDefaultFormatter.php index 9d4a0fa0..7e0afafc 100644 --- a/application/formatter/BookmarkDefaultFormatter.php +++ b/application/formatter/BookmarkDefaultFormatter.php | |||
@@ -12,10 +12,13 @@ namespace Shaarli\Formatter; | |||
12 | */ | 12 | */ |
13 | class BookmarkDefaultFormatter extends BookmarkFormatter | 13 | class BookmarkDefaultFormatter extends BookmarkFormatter |
14 | { | 14 | { |
15 | protected const SEARCH_HIGHLIGHT_OPEN = '|@@HIGHLIGHT'; | ||
16 | protected const SEARCH_HIGHLIGHT_CLOSE = 'HIGHLIGHT@@|'; | ||
17 | |||
15 | /** | 18 | /** |
16 | * @inheritdoc | 19 | * @inheritdoc |
17 | */ | 20 | */ |
18 | public function formatTitle($bookmark) | 21 | protected function formatTitle($bookmark) |
19 | { | 22 | { |
20 | return escape($bookmark->getTitle()); | 23 | return escape($bookmark->getTitle()); |
21 | } | 24 | } |
@@ -23,10 +26,33 @@ class BookmarkDefaultFormatter extends BookmarkFormatter | |||
23 | /** | 26 | /** |
24 | * @inheritdoc | 27 | * @inheritdoc |
25 | */ | 28 | */ |
26 | public function formatDescription($bookmark) | 29 | protected function formatTitleHtml($bookmark) |
30 | { | ||
31 | $title = $this->tokenizeSearchHighlightField( | ||
32 | $bookmark->getTitle() ?? '', | ||
33 | $bookmark->getAdditionalContentEntry('search_highlight')['title'] ?? [] | ||
34 | ); | ||
35 | |||
36 | return $this->replaceTokens(escape($title)); | ||
37 | } | ||
38 | |||
39 | /** | ||
40 | * @inheritdoc | ||
41 | */ | ||
42 | protected function formatDescription($bookmark) | ||
27 | { | 43 | { |
28 | $indexUrl = ! empty($this->contextData['index_url']) ? $this->contextData['index_url'] : ''; | 44 | $indexUrl = ! empty($this->contextData['index_url']) ? $this->contextData['index_url'] : ''; |
29 | return format_description(escape($bookmark->getDescription()), $indexUrl); | 45 | $description = $this->tokenizeSearchHighlightField( |
46 | $bookmark->getDescription() ?? '', | ||
47 | $bookmark->getAdditionalContentEntry('search_highlight')['description'] ?? [] | ||
48 | ); | ||
49 | $description = format_description( | ||
50 | escape($description), | ||
51 | $indexUrl, | ||
52 | $this->conf->get('formatter_settings.autolink', true) | ||
53 | ); | ||
54 | |||
55 | return $this->replaceTokens($description); | ||
30 | } | 56 | } |
31 | 57 | ||
32 | /** | 58 | /** |
@@ -40,15 +66,36 @@ class BookmarkDefaultFormatter extends BookmarkFormatter | |||
40 | /** | 66 | /** |
41 | * @inheritdoc | 67 | * @inheritdoc |
42 | */ | 68 | */ |
43 | public function formatTagString($bookmark) | 69 | protected function formatTagListHtml($bookmark) |
44 | { | 70 | { |
45 | return implode(' ', $this->formatTagList($bookmark)); | 71 | $tagsSeparator = $this->conf->get('general.tags_separator', ' '); |
72 | if (empty($bookmark->getAdditionalContentEntry('search_highlight')['tags'])) { | ||
73 | return $this->formatTagList($bookmark); | ||
74 | } | ||
75 | |||
76 | $tags = $this->tokenizeSearchHighlightField( | ||
77 | $bookmark->getTagsString($tagsSeparator), | ||
78 | $bookmark->getAdditionalContentEntry('search_highlight')['tags'] | ||
79 | ); | ||
80 | $tags = $this->filterTagList(tags_str2array($tags, $tagsSeparator)); | ||
81 | $tags = escape($tags); | ||
82 | $tags = $this->replaceTokensArray($tags); | ||
83 | |||
84 | return $tags; | ||
46 | } | 85 | } |
47 | 86 | ||
48 | /** | 87 | /** |
49 | * @inheritdoc | 88 | * @inheritdoc |
50 | */ | 89 | */ |
51 | public function formatUrl($bookmark) | 90 | protected function formatTagString($bookmark) |
91 | { | ||
92 | return implode($this->conf->get('general.tags_separator'), $this->formatTagList($bookmark)); | ||
93 | } | ||
94 | |||
95 | /** | ||
96 | * @inheritdoc | ||
97 | */ | ||
98 | protected function formatUrl($bookmark) | ||
52 | { | 99 | { |
53 | if ($bookmark->isNote() && isset($this->contextData['index_url'])) { | 100 | if ($bookmark->isNote() && isset($this->contextData['index_url'])) { |
54 | return rtrim($this->contextData['index_url'], '/') . '/' . escape(ltrim($bookmark->getUrl(), '/')); | 101 | return rtrim($this->contextData['index_url'], '/') . '/' . escape(ltrim($bookmark->getUrl(), '/')); |
@@ -80,8 +127,89 @@ class BookmarkDefaultFormatter extends BookmarkFormatter | |||
80 | /** | 127 | /** |
81 | * @inheritdoc | 128 | * @inheritdoc |
82 | */ | 129 | */ |
130 | protected function formatUrlHtml($bookmark) | ||
131 | { | ||
132 | $url = $this->tokenizeSearchHighlightField( | ||
133 | $bookmark->getUrl() ?? '', | ||
134 | $bookmark->getAdditionalContentEntry('search_highlight')['url'] ?? [] | ||
135 | ); | ||
136 | |||
137 | return $this->replaceTokens(escape($url)); | ||
138 | } | ||
139 | |||
140 | /** | ||
141 | * @inheritdoc | ||
142 | */ | ||
83 | protected function formatThumbnail($bookmark) | 143 | protected function formatThumbnail($bookmark) |
84 | { | 144 | { |
85 | return escape($bookmark->getThumbnail()); | 145 | return escape($bookmark->getThumbnail()); |
86 | } | 146 | } |
147 | |||
148 | /** | ||
149 | * Insert search highlight token in provided field content based on a list of search result positions | ||
150 | * | ||
151 | * @param string $fieldContent | ||
152 | * @param array|null $positions List of of search results with 'start' and 'end' positions. | ||
153 | * | ||
154 | * @return string Updated $fieldContent. | ||
155 | */ | ||
156 | protected function tokenizeSearchHighlightField(string $fieldContent, ?array $positions): string | ||
157 | { | ||
158 | if (empty($positions)) { | ||
159 | return $fieldContent; | ||
160 | } | ||
161 | |||
162 | $insertedTokens = 0; | ||
163 | $tokenLength = strlen(static::SEARCH_HIGHLIGHT_OPEN); | ||
164 | foreach ($positions as $position) { | ||
165 | $position = [ | ||
166 | 'start' => $position['start'] + ($insertedTokens * $tokenLength), | ||
167 | 'end' => $position['end'] + ($insertedTokens * $tokenLength), | ||
168 | ]; | ||
169 | |||
170 | $content = mb_substr($fieldContent, 0, $position['start']); | ||
171 | $content .= static::SEARCH_HIGHLIGHT_OPEN; | ||
172 | $content .= mb_substr($fieldContent, $position['start'], $position['end'] - $position['start']); | ||
173 | $content .= static::SEARCH_HIGHLIGHT_CLOSE; | ||
174 | $content .= mb_substr($fieldContent, $position['end']); | ||
175 | |||
176 | $fieldContent = $content; | ||
177 | |||
178 | $insertedTokens += 2; | ||
179 | } | ||
180 | |||
181 | return $fieldContent; | ||
182 | } | ||
183 | |||
184 | /** | ||
185 | * Replace search highlight tokens with HTML highlighted span. | ||
186 | * | ||
187 | * @param string $fieldContent | ||
188 | * | ||
189 | * @return string updated content. | ||
190 | */ | ||
191 | protected function replaceTokens(string $fieldContent): string | ||
192 | { | ||
193 | return str_replace( | ||
194 | [static::SEARCH_HIGHLIGHT_OPEN, static::SEARCH_HIGHLIGHT_CLOSE], | ||
195 | ['<span class="search-highlight">', '</span>'], | ||
196 | $fieldContent | ||
197 | ); | ||
198 | } | ||
199 | |||
200 | /** | ||
201 | * Apply replaceTokens to an array of content strings. | ||
202 | * | ||
203 | * @param string[] $fieldContents | ||
204 | * | ||
205 | * @return array | ||
206 | */ | ||
207 | protected function replaceTokensArray(array $fieldContents): array | ||
208 | { | ||
209 | foreach ($fieldContents as &$entry) { | ||
210 | $entry = $this->replaceTokens($entry); | ||
211 | } | ||
212 | |||
213 | return $fieldContents; | ||
214 | } | ||
87 | } | 215 | } |
diff --git a/application/formatter/BookmarkFormatter.php b/application/formatter/BookmarkFormatter.php index 0042dafe..124ce78b 100644 --- a/application/formatter/BookmarkFormatter.php +++ b/application/formatter/BookmarkFormatter.php | |||
@@ -2,7 +2,7 @@ | |||
2 | 2 | ||
3 | namespace Shaarli\Formatter; | 3 | namespace Shaarli\Formatter; |
4 | 4 | ||
5 | use DateTime; | 5 | use DateTimeInterface; |
6 | use Shaarli\Bookmark\Bookmark; | 6 | use Shaarli\Bookmark\Bookmark; |
7 | use Shaarli\Config\ConfigManager; | 7 | use Shaarli\Config\ConfigManager; |
8 | 8 | ||
@@ -11,6 +11,29 @@ use Shaarli\Config\ConfigManager; | |||
11 | * | 11 | * |
12 | * Abstract class processing all bookmark attributes through methods designed to be overridden. | 12 | * Abstract class processing all bookmark attributes through methods designed to be overridden. |
13 | * | 13 | * |
14 | * List of available formatted fields: | ||
15 | * - id ID | ||
16 | * - shorturl Unique identifier, used in permalinks | ||
17 | * - url URL, can be altered in some way, e.g. passing through an HTTP reverse proxy | ||
18 | * - real_url (legacy) same as `url` | ||
19 | * - url_html URL to be displayed in HTML content (it can contain HTML tags) | ||
20 | * - title Title | ||
21 | * - title_html Title to be displayed in HTML content (it can contain HTML tags) | ||
22 | * - description Description content. It most likely contains HTML tags | ||
23 | * - thumbnail Thumbnail: path to local cache file, false if there is none, null if hasn't been retrieved | ||
24 | * - taglist List of tags (array) | ||
25 | * - taglist_urlencoded List of tags (array) URL encoded: it must be used to create a link to a URL containing a tag | ||
26 | * - taglist_html List of tags (array) to be displayed in HTML content (it can contain HTML tags) | ||
27 | * - tags Tags separated by a single whitespace | ||
28 | * - tags_urlencoded Tags separated by a single whitespace, URL encoded: must be used to create a link | ||
29 | * - sticky Is sticky (bool) | ||
30 | * - private Is private (bool) | ||
31 | * - class Additional CSS class | ||
32 | * - created Creation DateTime | ||
33 | * - updated Last edit DateTime | ||
34 | * - timestamp Creation timestamp | ||
35 | * - updated_timestamp Last edit timestamp | ||
36 | * | ||
14 | * @package Shaarli\Formatter | 37 | * @package Shaarli\Formatter |
15 | */ | 38 | */ |
16 | abstract class BookmarkFormatter | 39 | abstract class BookmarkFormatter |
@@ -55,13 +78,16 @@ abstract class BookmarkFormatter | |||
55 | $out['shorturl'] = $this->formatShortUrl($bookmark); | 78 | $out['shorturl'] = $this->formatShortUrl($bookmark); |
56 | $out['url'] = $this->formatUrl($bookmark); | 79 | $out['url'] = $this->formatUrl($bookmark); |
57 | $out['real_url'] = $this->formatRealUrl($bookmark); | 80 | $out['real_url'] = $this->formatRealUrl($bookmark); |
81 | $out['url_html'] = $this->formatUrlHtml($bookmark); | ||
58 | $out['title'] = $this->formatTitle($bookmark); | 82 | $out['title'] = $this->formatTitle($bookmark); |
83 | $out['title_html'] = $this->formatTitleHtml($bookmark); | ||
59 | $out['description'] = $this->formatDescription($bookmark); | 84 | $out['description'] = $this->formatDescription($bookmark); |
60 | $out['thumbnail'] = $this->formatThumbnail($bookmark); | 85 | $out['thumbnail'] = $this->formatThumbnail($bookmark); |
61 | $out['urlencoded_taglist'] = $this->formatUrlEncodedTagList($bookmark); | ||
62 | $out['taglist'] = $this->formatTagList($bookmark); | 86 | $out['taglist'] = $this->formatTagList($bookmark); |
63 | $out['urlencoded_tags'] = $this->formatUrlEncodedTagString($bookmark); | 87 | $out['taglist_urlencoded'] = $this->formatTagListUrlEncoded($bookmark); |
88 | $out['taglist_html'] = $this->formatTagListHtml($bookmark); | ||
64 | $out['tags'] = $this->formatTagString($bookmark); | 89 | $out['tags'] = $this->formatTagString($bookmark); |
90 | $out['tags_urlencoded'] = $this->formatTagStringUrlEncoded($bookmark); | ||
65 | $out['sticky'] = $bookmark->isSticky(); | 91 | $out['sticky'] = $bookmark->isSticky(); |
66 | $out['private'] = $bookmark->isPrivate(); | 92 | $out['private'] = $bookmark->isPrivate(); |
67 | $out['class'] = $this->formatClass($bookmark); | 93 | $out['class'] = $this->formatClass($bookmark); |
@@ -69,6 +95,7 @@ abstract class BookmarkFormatter | |||
69 | $out['updated'] = $this->formatUpdated($bookmark); | 95 | $out['updated'] = $this->formatUpdated($bookmark); |
70 | $out['timestamp'] = $this->formatCreatedTimestamp($bookmark); | 96 | $out['timestamp'] = $this->formatCreatedTimestamp($bookmark); |
71 | $out['updated_timestamp'] = $this->formatUpdatedTimestamp($bookmark); | 97 | $out['updated_timestamp'] = $this->formatUpdatedTimestamp($bookmark); |
98 | |||
72 | return $out; | 99 | return $out; |
73 | } | 100 | } |
74 | 101 | ||
@@ -136,6 +163,18 @@ abstract class BookmarkFormatter | |||
136 | } | 163 | } |
137 | 164 | ||
138 | /** | 165 | /** |
166 | * Format Url Html: to be displayed in HTML content, it can contains HTML tags. | ||
167 | * | ||
168 | * @param Bookmark $bookmark instance | ||
169 | * | ||
170 | * @return string formatted Url HTML | ||
171 | */ | ||
172 | protected function formatUrlHtml($bookmark) | ||
173 | { | ||
174 | return $this->formatUrl($bookmark); | ||
175 | } | ||
176 | |||
177 | /** | ||
139 | * Format Title | 178 | * Format Title |
140 | * | 179 | * |
141 | * @param Bookmark $bookmark instance | 180 | * @param Bookmark $bookmark instance |
@@ -148,6 +187,18 @@ abstract class BookmarkFormatter | |||
148 | } | 187 | } |
149 | 188 | ||
150 | /** | 189 | /** |
190 | * Format Title HTML: to be displayed in HTML content, it can contains HTML tags. | ||
191 | * | ||
192 | * @param Bookmark $bookmark instance | ||
193 | * | ||
194 | * @return string formatted Title | ||
195 | */ | ||
196 | protected function formatTitleHtml($bookmark) | ||
197 | { | ||
198 | return $bookmark->getTitle(); | ||
199 | } | ||
200 | |||
201 | /** | ||
151 | * Format Description | 202 | * Format Description |
152 | * | 203 | * |
153 | * @param Bookmark $bookmark instance | 204 | * @param Bookmark $bookmark instance |
@@ -190,12 +241,24 @@ abstract class BookmarkFormatter | |||
190 | * | 241 | * |
191 | * @return array formatted Tags | 242 | * @return array formatted Tags |
192 | */ | 243 | */ |
193 | protected function formatUrlEncodedTagList($bookmark) | 244 | protected function formatTagListUrlEncoded($bookmark) |
194 | { | 245 | { |
195 | return array_map('urlencode', $this->filterTagList($bookmark->getTags())); | 246 | return array_map('urlencode', $this->filterTagList($bookmark->getTags())); |
196 | } | 247 | } |
197 | 248 | ||
198 | /** | 249 | /** |
250 | * Format Tags HTML: to be displayed in HTML content, it can contains HTML tags. | ||
251 | * | ||
252 | * @param Bookmark $bookmark instance | ||
253 | * | ||
254 | * @return array formatted Tags | ||
255 | */ | ||
256 | protected function formatTagListHtml($bookmark) | ||
257 | { | ||
258 | return $this->formatTagList($bookmark); | ||
259 | } | ||
260 | |||
261 | /** | ||
199 | * Format TagString | 262 | * Format TagString |
200 | * | 263 | * |
201 | * @param Bookmark $bookmark instance | 264 | * @param Bookmark $bookmark instance |
@@ -204,7 +267,7 @@ abstract class BookmarkFormatter | |||
204 | */ | 267 | */ |
205 | protected function formatTagString($bookmark) | 268 | protected function formatTagString($bookmark) |
206 | { | 269 | { |
207 | return implode(' ', $this->formatTagList($bookmark)); | 270 | return implode($this->conf->get('general.tags_separator', ' '), $this->formatTagList($bookmark)); |
208 | } | 271 | } |
209 | 272 | ||
210 | /** | 273 | /** |
@@ -214,9 +277,9 @@ abstract class BookmarkFormatter | |||
214 | * | 277 | * |
215 | * @return string formatted TagString | 278 | * @return string formatted TagString |
216 | */ | 279 | */ |
217 | protected function formatUrlEncodedTagString($bookmark) | 280 | protected function formatTagStringUrlEncoded($bookmark) |
218 | { | 281 | { |
219 | return implode(' ', $this->formatUrlEncodedTagList($bookmark)); | 282 | return implode(' ', $this->formatTagListUrlEncoded($bookmark)); |
220 | } | 283 | } |
221 | 284 | ||
222 | /** | 285 | /** |
@@ -237,7 +300,7 @@ abstract class BookmarkFormatter | |||
237 | * | 300 | * |
238 | * @param Bookmark $bookmark instance | 301 | * @param Bookmark $bookmark instance |
239 | * | 302 | * |
240 | * @return DateTime instance | 303 | * @return DateTimeInterface instance |
241 | */ | 304 | */ |
242 | protected function formatCreated(Bookmark $bookmark) | 305 | protected function formatCreated(Bookmark $bookmark) |
243 | { | 306 | { |
@@ -249,7 +312,7 @@ abstract class BookmarkFormatter | |||
249 | * | 312 | * |
250 | * @param Bookmark $bookmark instance | 313 | * @param Bookmark $bookmark instance |
251 | * | 314 | * |
252 | * @return DateTime instance | 315 | * @return DateTimeInterface instance |
253 | */ | 316 | */ |
254 | protected function formatUpdated(Bookmark $bookmark) | 317 | protected function formatUpdated(Bookmark $bookmark) |
255 | { | 318 | { |
@@ -288,6 +351,7 @@ abstract class BookmarkFormatter | |||
288 | 351 | ||
289 | /** | 352 | /** |
290 | * Format tag list, e.g. remove private tags if the user is not logged in. | 353 | * Format tag list, e.g. remove private tags if the user is not logged in. |
354 | * TODO: this method is called multiple time to format tags, the result should be cached. | ||
291 | * | 355 | * |
292 | * @param array $tags | 356 | * @param array $tags |
293 | * | 357 | * |
diff --git a/application/formatter/BookmarkMarkdownExtraFormatter.php b/application/formatter/BookmarkMarkdownExtraFormatter.php new file mode 100644 index 00000000..0694b23f --- /dev/null +++ b/application/formatter/BookmarkMarkdownExtraFormatter.php | |||
@@ -0,0 +1,24 @@ | |||
1 | <?php | ||
2 | |||
3 | namespace Shaarli\Formatter; | ||
4 | |||
5 | use Shaarli\Config\ConfigManager; | ||
6 | |||
7 | /** | ||
8 | * Class BookmarkMarkdownExtraFormatter | ||
9 | * | ||
10 | * Format bookmark description into MarkdownExtra format. | ||
11 | * | ||
12 | * @see https://michelf.ca/projects/php-markdown/extra/ | ||
13 | * | ||
14 | * @package Shaarli\Formatter | ||
15 | */ | ||
16 | class BookmarkMarkdownExtraFormatter extends BookmarkMarkdownFormatter | ||
17 | { | ||
18 | public function __construct(ConfigManager $conf, bool $isLoggedIn) | ||
19 | { | ||
20 | parent::__construct($conf, $isLoggedIn); | ||
21 | |||
22 | $this->parsedown = new \ParsedownExtra(); | ||
23 | } | ||
24 | } | ||
diff --git a/application/formatter/BookmarkMarkdownFormatter.php b/application/formatter/BookmarkMarkdownFormatter.php index 5d244d4c..ee4e8dca 100644 --- a/application/formatter/BookmarkMarkdownFormatter.php +++ b/application/formatter/BookmarkMarkdownFormatter.php | |||
@@ -16,7 +16,7 @@ class BookmarkMarkdownFormatter extends BookmarkDefaultFormatter | |||
16 | /** | 16 | /** |
17 | * When this tag is present in a bookmark, its description should not be processed with Markdown | 17 | * When this tag is present in a bookmark, its description should not be processed with Markdown |
18 | */ | 18 | */ |
19 | const NO_MD_TAG = 'nomarkdown'; | 19 | public const NO_MD_TAG = 'nomarkdown'; |
20 | 20 | ||
21 | /** @var \Parsedown instance */ | 21 | /** @var \Parsedown instance */ |
22 | protected $parsedown; | 22 | protected $parsedown; |
@@ -56,7 +56,10 @@ class BookmarkMarkdownFormatter extends BookmarkDefaultFormatter | |||
56 | return parent::formatDescription($bookmark); | 56 | return parent::formatDescription($bookmark); |
57 | } | 57 | } |
58 | 58 | ||
59 | $processedDescription = $bookmark->getDescription(); | 59 | $processedDescription = $this->tokenizeSearchHighlightField( |
60 | $bookmark->getDescription() ?? '', | ||
61 | $bookmark->getAdditionalContentEntry('search_highlight')['description'] ?? [] | ||
62 | ); | ||
60 | $processedDescription = $this->filterProtocols($processedDescription); | 63 | $processedDescription = $this->filterProtocols($processedDescription); |
61 | $processedDescription = $this->formatHashTags($processedDescription); | 64 | $processedDescription = $this->formatHashTags($processedDescription); |
62 | $processedDescription = $this->reverseEscapedHtml($processedDescription); | 65 | $processedDescription = $this->reverseEscapedHtml($processedDescription); |
@@ -65,9 +68,10 @@ class BookmarkMarkdownFormatter extends BookmarkDefaultFormatter | |||
65 | ->setBreaksEnabled(true) | 68 | ->setBreaksEnabled(true) |
66 | ->text($processedDescription); | 69 | ->text($processedDescription); |
67 | $processedDescription = $this->sanitizeHtml($processedDescription); | 70 | $processedDescription = $this->sanitizeHtml($processedDescription); |
71 | $processedDescription = $this->replaceTokens($processedDescription); | ||
68 | 72 | ||
69 | if (!empty($processedDescription)) { | 73 | if (!empty($processedDescription)) { |
70 | $processedDescription = '<div class="markdown">'. $processedDescription . '</div>'; | 74 | $processedDescription = '<div class="markdown">' . $processedDescription . '</div>'; |
71 | } | 75 | } |
72 | 76 | ||
73 | return $processedDescription; | 77 | return $processedDescription; |
@@ -106,7 +110,7 @@ class BookmarkMarkdownFormatter extends BookmarkDefaultFormatter | |||
106 | function ($match) use ($allowedProtocols, $indexUrl) { | 110 | function ($match) use ($allowedProtocols, $indexUrl) { |
107 | $link = startsWith($match[1], '?') || startsWith($match[1], '/') ? $indexUrl : ''; | 111 | $link = startsWith($match[1], '?') || startsWith($match[1], '/') ? $indexUrl : ''; |
108 | $link .= whitelist_protocols($match[1], $allowedProtocols); | 112 | $link .= whitelist_protocols($match[1], $allowedProtocols); |
109 | return ']('. $link.')'; | 113 | return '](' . $link . ')'; |
110 | }, | 114 | }, |
111 | $description | 115 | $description |
112 | ); | 116 | ); |
@@ -133,7 +137,7 @@ class BookmarkMarkdownFormatter extends BookmarkDefaultFormatter | |||
133 | * \p{Mn} - any non marking space (accents, umlauts, etc) | 137 | * \p{Mn} - any non marking space (accents, umlauts, etc) |
134 | */ | 138 | */ |
135 | $regex = '/(^|\s)#([\p{Pc}\p{N}\p{L}\p{Mn}]+)/mui'; | 139 | $regex = '/(^|\s)#([\p{Pc}\p{N}\p{L}\p{Mn}]+)/mui'; |
136 | $replacement = '$1[#$2]('. $indexUrl .'./add-tag/$2)'; | 140 | $replacement = '$1[#$2](' . $indexUrl . './add-tag/$2)'; |
137 | 141 | ||
138 | $descriptionLines = explode(PHP_EOL, $description); | 142 | $descriptionLines = explode(PHP_EOL, $description); |
139 | $descriptionOut = ''; | 143 | $descriptionOut = ''; |
@@ -174,17 +178,17 @@ class BookmarkMarkdownFormatter extends BookmarkDefaultFormatter | |||
174 | */ | 178 | */ |
175 | protected function sanitizeHtml($description) | 179 | protected function sanitizeHtml($description) |
176 | { | 180 | { |
177 | $escapeTags = array( | 181 | $escapeTags = [ |
178 | 'script', | 182 | 'script', |
179 | 'style', | 183 | 'style', |
180 | 'link', | 184 | 'link', |
181 | 'iframe', | 185 | 'iframe', |
182 | 'frameset', | 186 | 'frameset', |
183 | 'frame', | 187 | 'frame', |
184 | ); | 188 | ]; |
185 | foreach ($escapeTags as $tag) { | 189 | foreach ($escapeTags as $tag) { |
186 | $description = preg_replace_callback( | 190 | $description = preg_replace_callback( |
187 | '#<\s*'. $tag .'[^>]*>(.*</\s*'. $tag .'[^>]*>)?#is', | 191 | '#<\s*' . $tag . '[^>]*>(.*</\s*' . $tag . '[^>]*>)?#is', |
188 | function ($match) { | 192 | function ($match) { |
189 | return escape($match[0]); | 193 | return escape($match[0]); |
190 | }, | 194 | }, |
diff --git a/application/formatter/BookmarkRawFormatter.php b/application/formatter/BookmarkRawFormatter.php index bc372273..4ff07cdf 100644 --- a/application/formatter/BookmarkRawFormatter.php +++ b/application/formatter/BookmarkRawFormatter.php | |||
@@ -10,4 +10,6 @@ namespace Shaarli\Formatter; | |||
10 | * | 10 | * |
11 | * @package Shaarli\Formatter | 11 | * @package Shaarli\Formatter |
12 | */ | 12 | */ |
13 | class BookmarkRawFormatter extends BookmarkFormatter {} | 13 | class BookmarkRawFormatter extends BookmarkFormatter |
14 | { | ||
15 | } | ||
diff --git a/application/formatter/FormatterFactory.php b/application/formatter/FormatterFactory.php index a029579f..bb865aed 100644 --- a/application/formatter/FormatterFactory.php +++ b/application/formatter/FormatterFactory.php | |||
@@ -41,7 +41,7 @@ class FormatterFactory | |||
41 | public function getFormatter(string $type = null): BookmarkFormatter | 41 | public function getFormatter(string $type = null): BookmarkFormatter |
42 | { | 42 | { |
43 | $type = $type ? $type : $this->conf->get('formatter', 'default'); | 43 | $type = $type ? $type : $this->conf->get('formatter', 'default'); |
44 | $className = '\\Shaarli\\Formatter\\Bookmark'. ucfirst($type) .'Formatter'; | 44 | $className = '\\Shaarli\\Formatter\\Bookmark' . ucfirst($type) . 'Formatter'; |
45 | if (!class_exists($className)) { | 45 | if (!class_exists($className)) { |
46 | $className = '\\Shaarli\\Formatter\\BookmarkDefaultFormatter'; | 46 | $className = '\\Shaarli\\Formatter\\BookmarkDefaultFormatter'; |
47 | } | 47 | } |