aboutsummaryrefslogtreecommitdiffhomepage
path: root/application/front
diff options
context:
space:
mode:
authorArthurHoaro <arthur@hoa.ro>2020-10-22 16:21:03 +0200
committerArthurHoaro <arthur@hoa.ro>2020-11-05 17:54:42 +0100
commitb3bd8c3e8d367975980043e772f7cd78b7f96bc6 (patch)
treeec79899ea564c093d8b0578f3e614881a4ea7c3d /application/front
parent48df9f45b8c4b2995c1e04146071628668531b37 (diff)
downloadShaarli-b3bd8c3e8d367975980043e772f7cd78b7f96bc6.tar.gz
Shaarli-b3bd8c3e8d367975980043e772f7cd78b7f96bc6.tar.zst
Shaarli-b3bd8c3e8d367975980043e772f7cd78b7f96bc6.zip
Feature: support any tag separator
So it allows to have multiple words tags. Breaking change: commas ',' are no longer a default separator. Fixes #594
Diffstat (limited to 'application/front')
-rw-r--r--application/front/controller/admin/ManageTagController.php33
-rw-r--r--application/front/controller/admin/ShaareManageController.php4
-rw-r--r--application/front/controller/admin/ShaarePublishController.php12
-rw-r--r--application/front/controller/visitor/BookmarkListController.php11
-rw-r--r--application/front/controller/visitor/TagCloudController.php10
-rw-r--r--application/front/controller/visitor/TagController.php10
6 files changed, 65 insertions, 15 deletions
diff --git a/application/front/controller/admin/ManageTagController.php b/application/front/controller/admin/ManageTagController.php
index 2065c3e2..22fb461c 100644
--- a/application/front/controller/admin/ManageTagController.php
+++ b/application/front/controller/admin/ManageTagController.php
@@ -24,6 +24,12 @@ class ManageTagController extends ShaarliAdminController
24 $fromTag = $request->getParam('fromtag') ?? ''; 24 $fromTag = $request->getParam('fromtag') ?? '';
25 25
26 $this->assignView('fromtag', escape($fromTag)); 26 $this->assignView('fromtag', escape($fromTag));
27 $separator = escape($this->container->conf->get('general.tags_separator', ' '));
28 if ($separator === ' ') {
29 $separator = '&nbsp;';
30 $this->assignView('tags_separator_desc', t('whitespace'));
31 }
32 $this->assignView('tags_separator', $separator);
27 $this->assignView( 33 $this->assignView(
28 'pagetitle', 34 'pagetitle',
29 t('Manage tags') .' - '. $this->container->conf->get('general.title', 'Shaarli') 35 t('Manage tags') .' - '. $this->container->conf->get('general.title', 'Shaarli')
@@ -85,4 +91,31 @@ class ManageTagController extends ShaarliAdminController
85 91
86 return $this->redirect($response, $redirect); 92 return $this->redirect($response, $redirect);
87 } 93 }
94
95 /**
96 * POST /admin/tags/change-separator - Change tag separator
97 */
98 public function changeSeparator(Request $request, Response $response): Response
99 {
100 $this->checkToken($request);
101
102 $reservedCharacters = ['-', '.', '*'];
103 $newSeparator = $request->getParam('separator');
104 if ($newSeparator === null || mb_strlen($newSeparator) !== 1) {
105 $this->saveErrorMessage(t('Tags separator must be a single character.'));
106 } elseif (in_array($newSeparator, $reservedCharacters, true)) {
107 $reservedCharacters = implode(' ', array_map(function (string $character) {
108 return '<code>' . $character . '</code>';
109 }, $reservedCharacters));
110 $this->saveErrorMessage(
111 t('These characters are reserved and can\'t be used as tags separator: ') . $reservedCharacters
112 );
113 } else {
114 $this->container->conf->set('general.tags_separator', $newSeparator, true, true);
115
116 $this->saveSuccessMessage('Your tags separator setting has been updated!');
117 }
118
119 return $this->redirect($response, '/admin/tags');
120 }
88} 121}
diff --git a/application/front/controller/admin/ShaareManageController.php b/application/front/controller/admin/ShaareManageController.php
index 2ed298f5..0b143172 100644
--- a/application/front/controller/admin/ShaareManageController.php
+++ b/application/front/controller/admin/ShaareManageController.php
@@ -125,7 +125,7 @@ class ShaareManageController extends ShaarliAdminController
125 // To preserve backward compatibility with 3rd parties, plugins still use arrays 125 // To preserve backward compatibility with 3rd parties, plugins still use arrays
126 $data = $formatter->format($bookmark); 126 $data = $formatter->format($bookmark);
127 $this->executePageHooks('save_link', $data); 127 $this->executePageHooks('save_link', $data);
128 $bookmark->fromArray($data); 128 $bookmark->fromArray($data, $this->container->conf->get('general.tags_separator', ' '));
129 129
130 $this->container->bookmarkService->set($bookmark, false); 130 $this->container->bookmarkService->set($bookmark, false);
131 ++$count; 131 ++$count;
@@ -167,7 +167,7 @@ class ShaareManageController extends ShaarliAdminController
167 // To preserve backward compatibility with 3rd parties, plugins still use arrays 167 // To preserve backward compatibility with 3rd parties, plugins still use arrays
168 $data = $formatter->format($bookmark); 168 $data = $formatter->format($bookmark);
169 $this->executePageHooks('save_link', $data); 169 $this->executePageHooks('save_link', $data);
170 $bookmark->fromArray($data); 170 $bookmark->fromArray($data, $this->container->conf->get('general.tags_separator', ' '));
171 171
172 $this->container->bookmarkService->set($bookmark); 172 $this->container->bookmarkService->set($bookmark);
173 173
diff --git a/application/front/controller/admin/ShaarePublishController.php b/application/front/controller/admin/ShaarePublishController.php
index 18afc2d1..625a5680 100644
--- a/application/front/controller/admin/ShaarePublishController.php
+++ b/application/front/controller/admin/ShaarePublishController.php
@@ -113,7 +113,10 @@ class ShaarePublishController extends ShaarliAdminController
113 $bookmark->setDescription($request->getParam('lf_description')); 113 $bookmark->setDescription($request->getParam('lf_description'));
114 $bookmark->setUrl($request->getParam('lf_url'), $this->container->conf->get('security.allowed_protocols', [])); 114 $bookmark->setUrl($request->getParam('lf_url'), $this->container->conf->get('security.allowed_protocols', []));
115 $bookmark->setPrivate(filter_var($request->getParam('lf_private'), FILTER_VALIDATE_BOOLEAN)); 115 $bookmark->setPrivate(filter_var($request->getParam('lf_private'), FILTER_VALIDATE_BOOLEAN));
116 $bookmark->setTagsString($request->getParam('lf_tags')); 116 $bookmark->setTagsString(
117 $request->getParam('lf_tags'),
118 $this->container->conf->get('general.tags_separator', ' ')
119 );
117 120
118 if ($this->container->conf->get('thumbnails.mode', Thumbnailer::MODE_NONE) !== Thumbnailer::MODE_NONE 121 if ($this->container->conf->get('thumbnails.mode', Thumbnailer::MODE_NONE) !== Thumbnailer::MODE_NONE
119 && true !== $this->container->conf->get('general.enable_async_metadata', true) 122 && true !== $this->container->conf->get('general.enable_async_metadata', true)
@@ -128,7 +131,7 @@ class ShaarePublishController extends ShaarliAdminController
128 $data = $formatter->format($bookmark); 131 $data = $formatter->format($bookmark);
129 $this->executePageHooks('save_link', $data); 132 $this->executePageHooks('save_link', $data);
130 133
131 $bookmark->fromArray($data); 134 $bookmark->fromArray($data, $this->container->conf->get('general.tags_separator', ' '));
132 $this->container->bookmarkService->set($bookmark); 135 $this->container->bookmarkService->set($bookmark);
133 136
134 // If we are called from the bookmarklet, we must close the popup: 137 // If we are called from the bookmarklet, we must close the popup:
@@ -221,6 +224,11 @@ class ShaarePublishController extends ShaarliAdminController
221 224
222 protected function buildFormData(array $link, bool $isNew, Request $request): array 225 protected function buildFormData(array $link, bool $isNew, Request $request): array
223 { 226 {
227 $link['tags'] = strlen($link['tags']) > 0
228 ? $link['tags'] . $this->container->conf->get('general.tags_separator', ' ')
229 : $link['tags']
230 ;
231
224 return escape([ 232 return escape([
225 'link' => $link, 233 'link' => $link,
226 'link_is_new' => $isNew, 234 'link_is_new' => $isNew,
diff --git a/application/front/controller/visitor/BookmarkListController.php b/application/front/controller/visitor/BookmarkListController.php
index 78c474c9..cc3837ce 100644
--- a/application/front/controller/visitor/BookmarkListController.php
+++ b/application/front/controller/visitor/BookmarkListController.php
@@ -95,6 +95,10 @@ class BookmarkListController extends ShaarliVisitorController
95 $next_page_url = '?page=' . ($page - 1) . $searchtermUrl . $searchtagsUrl; 95 $next_page_url = '?page=' . ($page - 1) . $searchtermUrl . $searchtagsUrl;
96 } 96 }
97 97
98 $tagsSeparator = $this->container->conf->get('general.tags_separator', ' ');
99 $searchTagsUrlEncoded = array_map('urlencode', tags_str2array($searchTags, $tagsSeparator));
100 $searchTags = !empty($searchTags) ? trim($searchTags, $tagsSeparator) . $tagsSeparator : '';
101
98 // Fill all template fields. 102 // Fill all template fields.
99 $data = array_merge( 103 $data = array_merge(
100 $this->initializeTemplateVars(), 104 $this->initializeTemplateVars(),
@@ -106,7 +110,7 @@ class BookmarkListController extends ShaarliVisitorController
106 'result_count' => count($linksToDisplay), 110 'result_count' => count($linksToDisplay),
107 'search_term' => escape($searchTerm), 111 'search_term' => escape($searchTerm),
108 'search_tags' => escape($searchTags), 112 'search_tags' => escape($searchTags),
109 'search_tags_url' => array_map('urlencode', explode(' ', $searchTags)), 113 'search_tags_url' => $searchTagsUrlEncoded,
110 'visibility' => $visibility, 114 'visibility' => $visibility,
111 'links' => $linkDisp, 115 'links' => $linkDisp,
112 ] 116 ]
@@ -119,8 +123,9 @@ class BookmarkListController extends ShaarliVisitorController
119 return '[' . $tag . ']'; 123 return '[' . $tag . ']';
120 }; 124 };
121 $data['pagetitle'] .= ! empty($searchTags) 125 $data['pagetitle'] .= ! empty($searchTags)
122 ? implode(' ', array_map($bracketWrap, preg_split('/\s+/', $searchTags))) . ' ' 126 ? implode(' ', array_map($bracketWrap, tags_str2array($searchTags, $tagsSeparator))) . ' '
123 : ''; 127 : ''
128 ;
124 $data['pagetitle'] .= '- '; 129 $data['pagetitle'] .= '- ';
125 } 130 }
126 131
diff --git a/application/front/controller/visitor/TagCloudController.php b/application/front/controller/visitor/TagCloudController.php
index 76ed7690..560cad08 100644
--- a/application/front/controller/visitor/TagCloudController.php
+++ b/application/front/controller/visitor/TagCloudController.php
@@ -47,13 +47,14 @@ class TagCloudController extends ShaarliVisitorController
47 */ 47 */
48 protected function processRequest(string $type, Request $request, Response $response): Response 48 protected function processRequest(string $type, Request $request, Response $response): Response
49 { 49 {
50 $tagsSeparator = $this->container->conf->get('general.tags_separator', ' ');
50 if ($this->container->loginManager->isLoggedIn() === true) { 51 if ($this->container->loginManager->isLoggedIn() === true) {
51 $visibility = $this->container->sessionManager->getSessionParameter('visibility'); 52 $visibility = $this->container->sessionManager->getSessionParameter('visibility');
52 } 53 }
53 54
54 $sort = $request->getQueryParam('sort'); 55 $sort = $request->getQueryParam('sort');
55 $searchTags = $request->getQueryParam('searchtags'); 56 $searchTags = $request->getQueryParam('searchtags');
56 $filteringTags = $searchTags !== null ? explode(' ', $searchTags) : []; 57 $filteringTags = $searchTags !== null ? explode($tagsSeparator, $searchTags) : [];
57 58
58 $tags = $this->container->bookmarkService->bookmarksCountPerTag($filteringTags, $visibility ?? null); 59 $tags = $this->container->bookmarkService->bookmarksCountPerTag($filteringTags, $visibility ?? null);
59 60
@@ -71,8 +72,9 @@ class TagCloudController extends ShaarliVisitorController
71 $tagsUrl[escape($tag)] = urlencode((string) $tag); 72 $tagsUrl[escape($tag)] = urlencode((string) $tag);
72 } 73 }
73 74
74 $searchTags = implode(' ', escape($filteringTags)); 75 $searchTags = tags_array2str($filteringTags, $tagsSeparator);
75 $searchTagsUrl = urlencode(implode(' ', $filteringTags)); 76 $searchTags = !empty($searchTags) ? trim($searchTags, $tagsSeparator) . $tagsSeparator : '';
77 $searchTagsUrl = urlencode($searchTags);
76 $data = [ 78 $data = [
77 'search_tags' => escape($searchTags), 79 'search_tags' => escape($searchTags),
78 'search_tags_url' => $searchTagsUrl, 80 'search_tags_url' => $searchTagsUrl,
@@ -82,7 +84,7 @@ class TagCloudController extends ShaarliVisitorController
82 $this->executePageHooks('render_tag' . $type, $data, 'tag.' . $type); 84 $this->executePageHooks('render_tag' . $type, $data, 'tag.' . $type);
83 $this->assignAllView($data); 85 $this->assignAllView($data);
84 86
85 $searchTags = !empty($searchTags) ? $searchTags .' - ' : ''; 87 $searchTags = !empty($searchTags) ? trim(str_replace($tagsSeparator, ' ', $searchTags)) .' - ' : '';
86 $this->assignView( 88 $this->assignView(
87 'pagetitle', 89 'pagetitle',
88 $searchTags . t('Tag '. $type) .' - '. $this->container->conf->get('general.title', 'Shaarli') 90 $searchTags . t('Tag '. $type) .' - '. $this->container->conf->get('general.title', 'Shaarli')
diff --git a/application/front/controller/visitor/TagController.php b/application/front/controller/visitor/TagController.php
index de4e7ea2..7a3377a7 100644
--- a/application/front/controller/visitor/TagController.php
+++ b/application/front/controller/visitor/TagController.php
@@ -45,9 +45,10 @@ class TagController extends ShaarliVisitorController
45 unset($params['addtag']); 45 unset($params['addtag']);
46 } 46 }
47 47
48 $tagsSeparator = $this->container->conf->get('general.tags_separator', ' ');
48 // Check if this tag is already in the search query and ignore it if it is. 49 // Check if this tag is already in the search query and ignore it if it is.
49 // Each tag is always separated by a space 50 // Each tag is always separated by a space
50 $currentTags = isset($params['searchtags']) ? explode(' ', $params['searchtags']) : []; 51 $currentTags = tags_str2array($params['searchtags'] ?? '', $tagsSeparator);
51 52
52 $addtag = true; 53 $addtag = true;
53 foreach ($currentTags as $value) { 54 foreach ($currentTags as $value) {
@@ -62,7 +63,7 @@ class TagController extends ShaarliVisitorController
62 $currentTags[] = trim($newTag); 63 $currentTags[] = trim($newTag);
63 } 64 }
64 65
65 $params['searchtags'] = trim(implode(' ', $currentTags)); 66 $params['searchtags'] = tags_array2str($currentTags, $tagsSeparator);
66 67
67 // We also remove page (keeping the same page has no sense, since the results are different) 68 // We also remove page (keeping the same page has no sense, since the results are different)
68 unset($params['page']); 69 unset($params['page']);
@@ -98,10 +99,11 @@ class TagController extends ShaarliVisitorController
98 } 99 }
99 100
100 if (isset($params['searchtags'])) { 101 if (isset($params['searchtags'])) {
101 $tags = explode(' ', $params['searchtags']); 102 $tagsSeparator = $this->container->conf->get('general.tags_separator', ' ');
103 $tags = tags_str2array($params['searchtags'] ?? '', $tagsSeparator);
102 // Remove value from array $tags. 104 // Remove value from array $tags.
103 $tags = array_diff($tags, [$tagToRemove]); 105 $tags = array_diff($tags, [$tagToRemove]);
104 $params['searchtags'] = implode(' ', $tags); 106 $params['searchtags'] = tags_array2str($tags, $tagsSeparator);
105 107
106 if (empty($params['searchtags'])) { 108 if (empty($params['searchtags'])) {
107 unset($params['searchtags']); 109 unset($params['searchtags']);