aboutsummaryrefslogtreecommitdiffhomepage
path: root/application
diff options
context:
space:
mode:
Diffstat (limited to 'application')
-rw-r--r--application/History.php11
-rw-r--r--application/Languages.php17
-rw-r--r--application/Thumbnailer.php13
-rw-r--r--application/TimeZone.php7
-rw-r--r--application/Utils.php16
-rw-r--r--application/api/ApiMiddleware.php4
-rw-r--r--application/api/ApiUtils.php6
-rw-r--r--application/api/controllers/HistoryController.php1
-rw-r--r--application/api/controllers/Info.php4
-rw-r--r--application/api/controllers/Links.php6
-rw-r--r--application/api/exceptions/ApiAuthorizationException.php2
-rw-r--r--application/api/exceptions/ApiException.php2
-rw-r--r--application/bookmark/Bookmark.php7
-rw-r--r--application/bookmark/BookmarkArray.php6
-rw-r--r--application/bookmark/BookmarkFileService.php22
-rw-r--r--application/bookmark/BookmarkFilter.php12
-rw-r--r--application/bookmark/BookmarkIO.php4
-rw-r--r--application/bookmark/BookmarkInitializer.php9
-rw-r--r--application/bookmark/LinkUtils.php11
-rw-r--r--application/bookmark/exception/BookmarkNotFoundException.php1
-rw-r--r--application/bookmark/exception/EmptyDataStoreException.php6
-rw-r--r--application/bookmark/exception/InvalidBookmarkException.php14
-rw-r--r--application/bookmark/exception/NotWritableDataStoreException.php4
-rw-r--r--application/config/ConfigIO.php1
-rw-r--r--application/config/ConfigManager.php13
-rw-r--r--application/config/ConfigPhp.php28
-rw-r--r--application/config/ConfigPlugin.php8
-rw-r--r--application/config/exception/MissingFieldConfigException.php1
-rw-r--r--application/config/exception/UnauthorizedConfigException.php1
-rw-r--r--application/container/ContainerBuilder.php2
-rw-r--r--application/exceptions/IOException.php1
-rw-r--r--application/feed/FeedBuilder.php9
-rw-r--r--application/formatter/BookmarkDefaultFormatter.php4
-rw-r--r--application/formatter/BookmarkMarkdownFormatter.php14
-rw-r--r--application/formatter/BookmarkRawFormatter.php4
-rw-r--r--application/formatter/FormatterFactory.php2
-rw-r--r--application/front/ShaarliMiddleware.php6
-rw-r--r--application/front/controller/admin/ConfigureController.php12
-rw-r--r--application/front/controller/admin/ExportController.php4
-rw-r--r--application/front/controller/admin/ImportController.php4
-rw-r--r--application/front/controller/admin/ManageTagController.php4
-rw-r--r--application/front/controller/admin/PasswordController.php4
-rw-r--r--application/front/controller/admin/PluginsController.php4
-rw-r--r--application/front/controller/admin/ServerController.php4
-rw-r--r--application/front/controller/admin/SessionFilterController.php2
-rw-r--r--application/front/controller/admin/ShaareAddController.php2
-rw-r--r--application/front/controller/admin/ShaareManageController.php2
-rw-r--r--application/front/controller/admin/ShaarePublishController.php13
-rw-r--r--application/front/controller/admin/ThumbnailsController.php2
-rw-r--r--application/front/controller/admin/ToolsController.php2
-rw-r--r--application/front/controller/visitor/BookmarkListController.php8
-rw-r--r--application/front/controller/visitor/DailyController.php2
-rw-r--r--application/front/controller/visitor/FeedController.php2
-rw-r--r--application/front/controller/visitor/InstallController.php25
-rw-r--r--application/front/controller/visitor/LoginController.php8
-rw-r--r--application/front/controller/visitor/PictureWallController.php2
-rw-r--r--application/front/controller/visitor/ShaarliVisitorController.php5
-rw-r--r--application/front/controller/visitor/TagCloudController.php4
-rw-r--r--application/front/controller/visitor/TagController.php8
-rw-r--r--application/helper/ApplicationUtils.php47
-rw-r--r--application/helper/FileUtils.php4
-rw-r--r--application/http/HttpUtils.php73
-rw-r--r--application/http/Url.php10
-rw-r--r--application/http/UrlUtils.php11
-rw-r--r--application/legacy/LegacyController.php2
-rw-r--r--application/legacy/LegacyLinkDB.php20
-rw-r--r--application/legacy/LegacyLinkFilter.php18
-rw-r--r--application/legacy/LegacyUpdater.php12
-rw-r--r--application/netscape/NetscapeBookmarkUtils.php4
-rw-r--r--application/plugin/PluginManager.php13
-rw-r--r--application/plugin/exception/PluginFileNotFoundException.php1
-rw-r--r--application/render/ThemeUtils.php4
-rw-r--r--application/security/BanManager.php8
-rw-r--r--application/security/LoginManager.php16
-rw-r--r--application/security/SessionManager.php3
-rw-r--r--application/updater/Updater.php10
-rw-r--r--application/updater/UpdaterUtils.php8
77 files changed, 372 insertions, 294 deletions
diff --git a/application/History.php b/application/History.php
index bd5c1bf7..d230f39d 100644
--- a/application/History.php
+++ b/application/History.php
@@ -1,4 +1,5 @@
1<?php 1<?php
2
2namespace Shaarli; 3namespace Shaarli;
3 4
4use DateTime; 5use DateTime;
@@ -31,27 +32,27 @@ class History
31 /** 32 /**
32 * @var string Action key: a new link has been created. 33 * @var string Action key: a new link has been created.
33 */ 34 */
34 const CREATED = 'CREATED'; 35 public const CREATED = 'CREATED';
35 36
36 /** 37 /**
37 * @var string Action key: a link has been updated. 38 * @var string Action key: a link has been updated.
38 */ 39 */
39 const UPDATED = 'UPDATED'; 40 public const UPDATED = 'UPDATED';
40 41
41 /** 42 /**
42 * @var string Action key: a link has been deleted. 43 * @var string Action key: a link has been deleted.
43 */ 44 */
44 const DELETED = 'DELETED'; 45 public const DELETED = 'DELETED';
45 46
46 /** 47 /**
47 * @var string Action key: settings have been updated. 48 * @var string Action key: settings have been updated.
48 */ 49 */
49 const SETTINGS = 'SETTINGS'; 50 public const SETTINGS = 'SETTINGS';
50 51
51 /** 52 /**
52 * @var string Action key: a bulk import has been processed. 53 * @var string Action key: a bulk import has been processed.
53 */ 54 */
54 const IMPORT = 'IMPORT'; 55 public const IMPORT = 'IMPORT';
55 56
56 /** 57 /**
57 * @var string History file path. 58 * @var string History file path.
diff --git a/application/Languages.php b/application/Languages.php
index d83e0765..60e91631 100644
--- a/application/Languages.php
+++ b/application/Languages.php
@@ -41,7 +41,7 @@ class Languages
41 /** 41 /**
42 * Core translations domain 42 * Core translations domain
43 */ 43 */
44 const DEFAULT_DOMAIN = 'shaarli'; 44 public const DEFAULT_DOMAIN = 'shaarli';
45 45
46 /** 46 /**
47 * @var TranslatorInterface 47 * @var TranslatorInterface
@@ -76,7 +76,8 @@ class Languages
76 $this->language = $confLanguage; 76 $this->language = $confLanguage;
77 } 77 }
78 78
79 if (! extension_loaded('gettext') 79 if (
80 ! extension_loaded('gettext')
80 || in_array($this->conf->get('translation.mode', 'auto'), ['auto', 'php']) 81 || in_array($this->conf->get('translation.mode', 'auto'), ['auto', 'php'])
81 ) { 82 ) {
82 $this->initPhpTranslator(); 83 $this->initPhpTranslator();
@@ -98,7 +99,7 @@ class Languages
98 $this->translator->loadDomain(self::DEFAULT_DOMAIN, 'inc/languages'); 99 $this->translator->loadDomain(self::DEFAULT_DOMAIN, 'inc/languages');
99 100
100 // Default extension translation from the current theme 101 // Default extension translation from the current theme
101 $themeTransFolder = rtrim($this->conf->get('raintpl_tpl'), '/') .'/'. $this->conf->get('theme') .'/language'; 102 $themeTransFolder = rtrim($this->conf->get('raintpl_tpl'), '/') . '/' . $this->conf->get('theme') . '/language';
102 if (is_dir($themeTransFolder)) { 103 if (is_dir($themeTransFolder)) {
103 $this->translator->loadDomain($this->conf->get('theme'), $themeTransFolder, false); 104 $this->translator->loadDomain($this->conf->get('theme'), $themeTransFolder, false);
104 } 105 }
@@ -121,7 +122,9 @@ class Languages
121 $translations = new Translations(); 122 $translations = new Translations();
122 // Core translations 123 // Core translations
123 try { 124 try {
124 $translations = $translations->addFromPoFile('inc/languages/'. $this->language .'/LC_MESSAGES/shaarli.po'); 125 $translations = $translations->addFromPoFile(
126 'inc/languages/' . $this->language . '/LC_MESSAGES/shaarli.po'
127 );
125 $translations->setDomain('shaarli'); 128 $translations->setDomain('shaarli');
126 $this->translator->loadTranslations($translations); 129 $this->translator->loadTranslations($translations);
127 } catch (\InvalidArgumentException $e) { 130 } catch (\InvalidArgumentException $e) {
@@ -129,11 +132,11 @@ class Languages
129 132
130 // Default extension translation from the current theme 133 // Default extension translation from the current theme
131 $theme = $this->conf->get('theme'); 134 $theme = $this->conf->get('theme');
132 $themeTransFolder = rtrim($this->conf->get('raintpl_tpl'), '/') .'/'. $theme .'/language'; 135 $themeTransFolder = rtrim($this->conf->get('raintpl_tpl'), '/') . '/' . $theme . '/language';
133 if (is_dir($themeTransFolder)) { 136 if (is_dir($themeTransFolder)) {
134 try { 137 try {
135 $translations = Translations::fromPoFile( 138 $translations = Translations::fromPoFile(
136 $themeTransFolder .'/'. $this->language .'/LC_MESSAGES/'. $theme .'.po' 139 $themeTransFolder . '/' . $this->language . '/LC_MESSAGES/' . $theme . '.po'
137 ); 140 );
138 $translations->setDomain($theme); 141 $translations->setDomain($theme);
139 $this->translator->loadTranslations($translations); 142 $this->translator->loadTranslations($translations);
@@ -149,7 +152,7 @@ class Languages
149 152
150 try { 153 try {
151 $extension = Translations::fromPoFile( 154 $extension = Translations::fromPoFile(
152 $translationPath . $this->language .'/LC_MESSAGES/'. $domain .'.po' 155 $translationPath . $this->language . '/LC_MESSAGES/' . $domain . '.po'
153 ); 156 );
154 $extension->setDomain($domain); 157 $extension->setDomain($domain);
155 $this->translator->loadTranslations($extension); 158 $this->translator->loadTranslations($extension);
diff --git a/application/Thumbnailer.php b/application/Thumbnailer.php
index 5aec23c8..c4ff8d7a 100644
--- a/application/Thumbnailer.php
+++ b/application/Thumbnailer.php
@@ -13,7 +13,7 @@ use WebThumbnailer\WebThumbnailer;
13 */ 13 */
14class Thumbnailer 14class Thumbnailer
15{ 15{
16 const COMMON_MEDIA_DOMAINS = [ 16 protected const COMMON_MEDIA_DOMAINS = [
17 'imgur.com', 17 'imgur.com',
18 'flickr.com', 18 'flickr.com',
19 'youtube.com', 19 'youtube.com',
@@ -31,9 +31,9 @@ class Thumbnailer
31 'deviantart.com', 31 'deviantart.com',
32 ]; 32 ];
33 33
34 const MODE_ALL = 'all'; 34 public const MODE_ALL = 'all';
35 const MODE_COMMON = 'common'; 35 public const MODE_COMMON = 'common';
36 const MODE_NONE = 'none'; 36 public const MODE_NONE = 'none';
37 37
38 /** 38 /**
39 * @var WebThumbnailer instance. 39 * @var WebThumbnailer instance.
@@ -60,7 +60,7 @@ class Thumbnailer
60 // TODO: create a proper error handling system able to catch exceptions... 60 // TODO: create a proper error handling system able to catch exceptions...
61 die(t( 61 die(t(
62 'php-gd extension must be loaded to use thumbnails. ' 62 'php-gd extension must be loaded to use thumbnails. '
63 .'Thumbnails are now disabled. Please reload the page.' 63 . 'Thumbnails are now disabled. Please reload the page.'
64 )); 64 ));
65 } 65 }
66 66
@@ -81,7 +81,8 @@ class Thumbnailer
81 */ 81 */
82 public function get($url) 82 public function get($url)
83 { 83 {
84 if ($this->conf->get('thumbnails.mode') === self::MODE_COMMON 84 if (
85 $this->conf->get('thumbnails.mode') === self::MODE_COMMON
85 && ! $this->isCommonMediaOrImage($url) 86 && ! $this->isCommonMediaOrImage($url)
86 ) { 87 ) {
87 return false; 88 return false;
diff --git a/application/TimeZone.php b/application/TimeZone.php
index c1869ef8..a420eb96 100644
--- a/application/TimeZone.php
+++ b/application/TimeZone.php
@@ -1,4 +1,5 @@
1<?php 1<?php
2
2/** 3/**
3 * Generates a list of available timezone continents and cities. 4 * Generates a list of available timezone continents and cities.
4 * 5 *
@@ -43,7 +44,7 @@ function generateTimeZoneData($installedTimeZones, $preselectedTimezone = '')
43 // Try to split the provided timezone 44 // Try to split the provided timezone
44 $spos = strpos($preselectedTimezone, '/'); 45 $spos = strpos($preselectedTimezone, '/');
45 $pcontinent = substr($preselectedTimezone, 0, $spos); 46 $pcontinent = substr($preselectedTimezone, 0, $spos);
46 $pcity = substr($preselectedTimezone, $spos+1); 47 $pcity = substr($preselectedTimezone, $spos + 1);
47 } 48 }
48 49
49 $continents = []; 50 $continents = [];
@@ -60,7 +61,7 @@ function generateTimeZoneData($installedTimeZones, $preselectedTimezone = '')
60 } 61 }
61 62
62 $continent = substr($tz, 0, $spos); 63 $continent = substr($tz, 0, $spos);
63 $city = substr($tz, $spos+1); 64 $city = substr($tz, $spos + 1);
64 $cities[] = ['continent' => $continent, 'city' => $city]; 65 $cities[] = ['continent' => $continent, 'city' => $city];
65 $continents[$continent] = true; 66 $continents[$continent] = true;
66 } 67 }
@@ -85,7 +86,7 @@ function generateTimeZoneData($installedTimeZones, $preselectedTimezone = '')
85function isTimeZoneValid($continent, $city) 86function isTimeZoneValid($continent, $city)
86{ 87{
87 return in_array( 88 return in_array(
88 $continent.'/'.$city, 89 $continent . '/' . $city,
89 timezone_identifiers_list() 90 timezone_identifiers_list()
90 ); 91 );
91} 92}
diff --git a/application/Utils.php b/application/Utils.php
index db046893..952378ab 100644
--- a/application/Utils.php
+++ b/application/Utils.php
@@ -1,4 +1,5 @@
1<?php 1<?php
2
2/** 3/**
3 * Shaarli utilities 4 * Shaarli utilities
4 */ 5 */
@@ -102,7 +103,7 @@ function escape($input)
102 } 103 }
103 104
104 if (is_array($input)) { 105 if (is_array($input)) {
105 $out = array(); 106 $out = [];
106 foreach ($input as $key => $value) { 107 foreach ($input as $key => $value) {
107 $out[escape($key)] = escape($value); 108 $out[escape($key)] = escape($value);
108 } 109 }
@@ -163,7 +164,7 @@ function checkDateFormat($format, $string)
163 * 164 *
164 * @return string $referer - final referer. 165 * @return string $referer - final referer.
165 */ 166 */
166function generateLocation($referer, $host, $loopTerms = array()) 167function generateLocation($referer, $host, $loopTerms = [])
167{ 168{
168 $finalReferer = './?'; 169 $finalReferer = './?';
169 170
@@ -196,7 +197,7 @@ function generateLocation($referer, $host, $loopTerms = array())
196function autoLocale($headerLocale) 197function autoLocale($headerLocale)
197{ 198{
198 // Default if browser does not send HTTP_ACCEPT_LANGUAGE 199 // Default if browser does not send HTTP_ACCEPT_LANGUAGE
199 $locales = array('en_US', 'en_US.utf8', 'en_US.UTF-8'); 200 $locales = ['en_US', 'en_US.utf8', 'en_US.UTF-8'];
200 if (! empty($headerLocale)) { 201 if (! empty($headerLocale)) {
201 if (preg_match_all('/([a-z]{2,3})[-_]?([a-z]{2})?,?/i', $headerLocale, $matches, PREG_SET_ORDER)) { 202 if (preg_match_all('/([a-z]{2,3})[-_]?([a-z]{2})?,?/i', $headerLocale, $matches, PREG_SET_ORDER)) {
202 $attempts = []; 203 $attempts = [];
@@ -376,13 +377,15 @@ function return_bytes($val)
376 return $val; 377 return $val;
377 } 378 }
378 $val = trim($val); 379 $val = trim($val);
379 $last = strtolower($val[strlen($val)-1]); 380 $last = strtolower($val[strlen($val) - 1]);
380 $val = intval(substr($val, 0, -1)); 381 $val = intval(substr($val, 0, -1));
381 switch ($last) { 382 switch ($last) {
382 case 'g': 383 case 'g':
383 $val *= 1024; 384 $val *= 1024;
385 // do no break in order 1024^2 for each unit
384 case 'm': 386 case 'm':
385 $val *= 1024; 387 $val *= 1024;
388 // do no break in order 1024^2 for each unit
386 case 'k': 389 case 'k':
387 $val *= 1024; 390 $val *= 1024;
388 } 391 }
@@ -482,7 +485,9 @@ function alphabetical_sort(&$data, $reverse = false, $byKeys = false)
482 */ 485 */
483function t($text, $nText = '', $nb = 1, $domain = 'shaarli', $variables = [], $fixCase = false) 486function t($text, $nText = '', $nb = 1, $domain = 'shaarli', $variables = [], $fixCase = false)
484{ 487{
485 $postFunction = $fixCase ? 'ucfirst' : function ($input) { return $input; }; 488 $postFunction = $fixCase ? 'ucfirst' : function ($input) {
489 return $input;
490 };
486 491
487 return $postFunction(dn__($domain, $text, $nText, $nb, $variables)); 492 return $postFunction(dn__($domain, $text, $nText, $nb, $variables));
488} 493}
@@ -494,4 +499,3 @@ function exception2text(Throwable $e): string
494{ 499{
495 return $e->getMessage() . PHP_EOL . $e->getFile() . $e->getLine() . PHP_EOL . $e->getTraceAsString(); 500 return $e->getMessage() . PHP_EOL . $e->getFile() . $e->getLine() . PHP_EOL . $e->getTraceAsString();
496} 501}
497
diff --git a/application/api/ApiMiddleware.php b/application/api/ApiMiddleware.php
index adc8b266..9fb88358 100644
--- a/application/api/ApiMiddleware.php
+++ b/application/api/ApiMiddleware.php
@@ -1,4 +1,5 @@
1<?php 1<?php
2
2namespace Shaarli\Api; 3namespace Shaarli\Api;
3 4
4use malkusch\lock\mutex\FlockMutex; 5use malkusch\lock\mutex\FlockMutex;
@@ -108,7 +109,8 @@ class ApiMiddleware
108 */ 109 */
109 protected function checkToken($request) 110 protected function checkToken($request)
110 { 111 {
111 if (!$request->hasHeader('Authorization') 112 if (
113 !$request->hasHeader('Authorization')
112 && !isset($this->container->environment['REDIRECT_HTTP_AUTHORIZATION']) 114 && !isset($this->container->environment['REDIRECT_HTTP_AUTHORIZATION'])
113 ) { 115 ) {
114 throw new ApiAuthorizationException('JWT token not provided'); 116 throw new ApiAuthorizationException('JWT token not provided');
diff --git a/application/api/ApiUtils.php b/application/api/ApiUtils.php
index eb1ca9bc..05a2840a 100644
--- a/application/api/ApiUtils.php
+++ b/application/api/ApiUtils.php
@@ -1,4 +1,5 @@
1<?php 1<?php
2
2namespace Shaarli\Api; 3namespace Shaarli\Api;
3 4
4use Shaarli\Api\Exceptions\ApiAuthorizationException; 5use Shaarli\Api\Exceptions\ApiAuthorizationException;
@@ -27,7 +28,7 @@ class ApiUtils
27 throw new ApiAuthorizationException('Malformed JWT token'); 28 throw new ApiAuthorizationException('Malformed JWT token');
28 } 29 }
29 30
30 $genSign = Base64Url::encode(hash_hmac('sha512', $parts[0] .'.'. $parts[1], $secret, true)); 31 $genSign = Base64Url::encode(hash_hmac('sha512', $parts[0] . '.' . $parts[1], $secret, true));
31 if ($parts[2] != $genSign) { 32 if ($parts[2] != $genSign) {
32 throw new ApiAuthorizationException('Invalid JWT signature'); 33 throw new ApiAuthorizationException('Invalid JWT signature');
33 } 34 }
@@ -42,7 +43,8 @@ class ApiUtils
42 throw new ApiAuthorizationException('Invalid JWT payload'); 43 throw new ApiAuthorizationException('Invalid JWT payload');
43 } 44 }
44 45
45 if (empty($payload->iat) 46 if (
47 empty($payload->iat)
46 || $payload->iat > time() 48 || $payload->iat > time()
47 || time() - $payload->iat > ApiMiddleware::$TOKEN_DURATION 49 || time() - $payload->iat > ApiMiddleware::$TOKEN_DURATION
48 ) { 50 ) {
diff --git a/application/api/controllers/HistoryController.php b/application/api/controllers/HistoryController.php
index 505647a9..d83a3a25 100644
--- a/application/api/controllers/HistoryController.php
+++ b/application/api/controllers/HistoryController.php
@@ -1,6 +1,5 @@
1<?php 1<?php
2 2
3
4namespace Shaarli\Api\Controllers; 3namespace Shaarli\Api\Controllers;
5 4
6use Shaarli\Api\Exceptions\ApiBadParametersException; 5use Shaarli\Api\Exceptions\ApiBadParametersException;
diff --git a/application/api/controllers/Info.php b/application/api/controllers/Info.php
index 12f6b2f0..ae7db93e 100644
--- a/application/api/controllers/Info.php
+++ b/application/api/controllers/Info.php
@@ -29,13 +29,13 @@ class Info extends ApiController
29 $info = [ 29 $info = [
30 'global_counter' => $this->bookmarkService->count(), 30 'global_counter' => $this->bookmarkService->count(),
31 'private_counter' => $this->bookmarkService->count(BookmarkFilter::$PRIVATE), 31 'private_counter' => $this->bookmarkService->count(BookmarkFilter::$PRIVATE),
32 'settings' => array( 32 'settings' => [
33 'title' => $this->conf->get('general.title', 'Shaarli'), 33 'title' => $this->conf->get('general.title', 'Shaarli'),
34 'header_link' => $this->conf->get('general.header_link', '?'), 34 'header_link' => $this->conf->get('general.header_link', '?'),
35 'timezone' => $this->conf->get('general.timezone', 'UTC'), 35 'timezone' => $this->conf->get('general.timezone', 'UTC'),
36 'enabled_plugins' => $this->conf->get('general.enabled_plugins', []), 36 'enabled_plugins' => $this->conf->get('general.enabled_plugins', []),
37 'default_private_links' => $this->conf->get('privacy.default_private_links', false), 37 'default_private_links' => $this->conf->get('privacy.default_private_links', false),
38 ), 38 ],
39 ]; 39 ];
40 40
41 return $response->withJson($info, 200, $this->jsonStyle); 41 return $response->withJson($info, 200, $this->jsonStyle);
diff --git a/application/api/controllers/Links.php b/application/api/controllers/Links.php
index 6bf529e4..c379b962 100644
--- a/application/api/controllers/Links.php
+++ b/application/api/controllers/Links.php
@@ -119,7 +119,8 @@ class Links extends ApiController
119 $data = (array) ($request->getParsedBody() ?? []); 119 $data = (array) ($request->getParsedBody() ?? []);
120 $bookmark = ApiUtils::buildBookmarkFromRequest($data, $this->conf->get('privacy.default_private_links')); 120 $bookmark = ApiUtils::buildBookmarkFromRequest($data, $this->conf->get('privacy.default_private_links'));
121 // duplicate by URL, return 409 Conflict 121 // duplicate by URL, return 409 Conflict
122 if (! empty($bookmark->getUrl()) 122 if (
123 ! empty($bookmark->getUrl())
123 && ! empty($dup = $this->bookmarkService->findByUrl($bookmark->getUrl())) 124 && ! empty($dup = $this->bookmarkService->findByUrl($bookmark->getUrl()))
124 ) { 125 ) {
125 return $response->withJson( 126 return $response->withJson(
@@ -159,7 +160,8 @@ class Links extends ApiController
159 160
160 $requestBookmark = ApiUtils::buildBookmarkFromRequest($data, $this->conf->get('privacy.default_private_links')); 161 $requestBookmark = ApiUtils::buildBookmarkFromRequest($data, $this->conf->get('privacy.default_private_links'));
161 // duplicate URL on a different link, return 409 Conflict 162 // duplicate URL on a different link, return 409 Conflict
162 if (! empty($requestBookmark->getUrl()) 163 if (
164 ! empty($requestBookmark->getUrl())
163 && ! empty($dup = $this->bookmarkService->findByUrl($requestBookmark->getUrl())) 165 && ! empty($dup = $this->bookmarkService->findByUrl($requestBookmark->getUrl()))
164 && $dup->getId() != $id 166 && $dup->getId() != $id
165 ) { 167 ) {
diff --git a/application/api/exceptions/ApiAuthorizationException.php b/application/api/exceptions/ApiAuthorizationException.php
index 0e3f4776..c77e9eea 100644
--- a/application/api/exceptions/ApiAuthorizationException.php
+++ b/application/api/exceptions/ApiAuthorizationException.php
@@ -28,7 +28,7 @@ class ApiAuthorizationException extends ApiException
28 */ 28 */
29 public function setMessage($message) 29 public function setMessage($message)
30 { 30 {
31 $original = $this->debug === true ? ': '. $this->getMessage() : ''; 31 $original = $this->debug === true ? ': ' . $this->getMessage() : '';
32 $this->message = $message . $original; 32 $this->message = $message . $original;
33 } 33 }
34} 34}
diff --git a/application/api/exceptions/ApiException.php b/application/api/exceptions/ApiException.php
index d6b66323..7deafb96 100644
--- a/application/api/exceptions/ApiException.php
+++ b/application/api/exceptions/ApiException.php
@@ -44,7 +44,7 @@ abstract class ApiException extends \Exception
44 } 44 }
45 return [ 45 return [
46 'message' => $this->getMessage(), 46 'message' => $this->getMessage(),
47 'stacktrace' => get_class($this) .': '. $this->getTraceAsString() 47 'stacktrace' => get_class($this) . ': ' . $this->getTraceAsString()
48 ]; 48 ];
49 } 49 }
50 50
diff --git a/application/bookmark/Bookmark.php b/application/bookmark/Bookmark.php
index 8aaeb9d8..4238ef25 100644
--- a/application/bookmark/Bookmark.php
+++ b/application/bookmark/Bookmark.php
@@ -19,7 +19,7 @@ use Shaarli\Bookmark\Exception\InvalidBookmarkException;
19class Bookmark 19class Bookmark
20{ 20{
21 /** @var string Date format used in string (former ID format) */ 21 /** @var string Date format used in string (former ID format) */
22 const LINK_DATE_FORMAT = 'Ymd_His'; 22 public const LINK_DATE_FORMAT = 'Ymd_His';
23 23
24 /** @var int Bookmark ID */ 24 /** @var int Bookmark ID */
25 protected $id; 25 protected $id;
@@ -106,7 +106,8 @@ class Bookmark
106 */ 106 */
107 public function validate(): void 107 public function validate(): void
108 { 108 {
109 if ($this->id === null 109 if (
110 $this->id === null
110 || ! is_int($this->id) 111 || ! is_int($this->id)
111 || empty($this->shortUrl) 112 || empty($this->shortUrl)
112 || empty($this->created) 113 || empty($this->created)
@@ -114,7 +115,7 @@ class Bookmark
114 throw new InvalidBookmarkException($this); 115 throw new InvalidBookmarkException($this);
115 } 116 }
116 if (empty($this->url)) { 117 if (empty($this->url)) {
117 $this->url = '/shaare/'. $this->shortUrl; 118 $this->url = '/shaare/' . $this->shortUrl;
118 } 119 }
119 if (empty($this->title)) { 120 if (empty($this->title)) {
120 $this->title = $this->url; 121 $this->title = $this->url;
diff --git a/application/bookmark/BookmarkArray.php b/application/bookmark/BookmarkArray.php
index 67bb3b73..b9328116 100644
--- a/application/bookmark/BookmarkArray.php
+++ b/application/bookmark/BookmarkArray.php
@@ -72,7 +72,8 @@ class BookmarkArray implements \Iterator, \Countable, \ArrayAccess
72 */ 72 */
73 public function offsetSet($offset, $value) 73 public function offsetSet($offset, $value)
74 { 74 {
75 if (! $value instanceof Bookmark 75 if (
76 ! $value instanceof Bookmark
76 || $value->getId() === null || empty($value->getUrl()) 77 || $value->getId() === null || empty($value->getUrl())
77 || ($offset !== null && ! is_int($offset)) || ! is_int($value->getId()) 78 || ($offset !== null && ! is_int($offset)) || ! is_int($value->getId())
78 || $offset !== null && $offset !== $value->getId() 79 || $offset !== null && $offset !== $value->getId()
@@ -222,7 +223,8 @@ class BookmarkArray implements \Iterator, \Countable, \ArrayAccess
222 */ 223 */
223 public function getByUrl(string $url): ?Bookmark 224 public function getByUrl(string $url): ?Bookmark
224 { 225 {
225 if (! empty($url) 226 if (
227 ! empty($url)
226 && isset($this->urls[$url]) 228 && isset($this->urls[$url])
227 && isset($this->bookmarks[$this->urls[$url]]) 229 && isset($this->bookmarks[$this->urls[$url]])
228 ) { 230 ) {
diff --git a/application/bookmark/BookmarkFileService.php b/application/bookmark/BookmarkFileService.php
index 85efeea6..6666a251 100644
--- a/application/bookmark/BookmarkFileService.php
+++ b/application/bookmark/BookmarkFileService.php
@@ -69,7 +69,7 @@ class BookmarkFileService implements BookmarkServiceInterface
69 } else { 69 } else {
70 try { 70 try {
71 $this->bookmarks = $this->bookmarksIO->read(); 71 $this->bookmarks = $this->bookmarksIO->read();
72 } catch (EmptyDataStoreException|DatastoreNotInitializedException $e) { 72 } catch (EmptyDataStoreException | DatastoreNotInitializedException $e) {
73 $this->bookmarks = new BookmarkArray(); 73 $this->bookmarks = new BookmarkArray();
74 74
75 if ($this->isLoggedIn) { 75 if ($this->isLoggedIn) {
@@ -85,7 +85,7 @@ class BookmarkFileService implements BookmarkServiceInterface
85 if (! $this->bookmarks instanceof BookmarkArray) { 85 if (! $this->bookmarks instanceof BookmarkArray) {
86 $this->migrate(); 86 $this->migrate();
87 exit( 87 exit(
88 'Your data store has been migrated, please reload the page.'. PHP_EOL . 88 'Your data store has been migrated, please reload the page.' . PHP_EOL .
89 'If this message keeps showing up, please delete data/updates.txt file.' 89 'If this message keeps showing up, please delete data/updates.txt file.'
90 ); 90 );
91 } 91 }
@@ -102,7 +102,8 @@ class BookmarkFileService implements BookmarkServiceInterface
102 $bookmark = $this->bookmarkFilter->filter(BookmarkFilter::$FILTER_HASH, $hash); 102 $bookmark = $this->bookmarkFilter->filter(BookmarkFilter::$FILTER_HASH, $hash);
103 // PHP 7.3 introduced array_key_first() to avoid this hack 103 // PHP 7.3 introduced array_key_first() to avoid this hack
104 $first = reset($bookmark); 104 $first = reset($bookmark);
105 if (!$this->isLoggedIn 105 if (
106 !$this->isLoggedIn
106 && $first->isPrivate() 107 && $first->isPrivate()
107 && (empty($privateKey) || $privateKey !== $first->getAdditionalContentEntry('private_key')) 108 && (empty($privateKey) || $privateKey !== $first->getAdditionalContentEntry('private_key'))
108 ) { 109 ) {
@@ -165,7 +166,8 @@ class BookmarkFileService implements BookmarkServiceInterface
165 } 166 }
166 167
167 $bookmark = $this->bookmarks[$id]; 168 $bookmark = $this->bookmarks[$id];
168 if (($bookmark->isPrivate() && $visibility != 'all' && $visibility != 'private') 169 if (
170 ($bookmark->isPrivate() && $visibility != 'all' && $visibility != 'private')
169 || (! $bookmark->isPrivate() && $visibility != 'all' && $visibility != 'public') 171 || (! $bookmark->isPrivate() && $visibility != 'all' && $visibility != 'public')
170 ) { 172 ) {
171 throw new Exception('Unauthorized'); 173 throw new Exception('Unauthorized');
@@ -265,7 +267,8 @@ class BookmarkFileService implements BookmarkServiceInterface
265 } 267 }
266 268
267 $bookmark = $this->bookmarks[$id]; 269 $bookmark = $this->bookmarks[$id];
268 if (($bookmark->isPrivate() && $visibility != 'all' && $visibility != 'private') 270 if (
271 ($bookmark->isPrivate() && $visibility != 'all' && $visibility != 'private')
269 || (! $bookmark->isPrivate() && $visibility != 'all' && $visibility != 'public') 272 || (! $bookmark->isPrivate() && $visibility != 'all' && $visibility != 'public')
270 ) { 273 ) {
271 return false; 274 return false;
@@ -307,7 +310,8 @@ class BookmarkFileService implements BookmarkServiceInterface
307 $caseMapping = []; 310 $caseMapping = [];
308 foreach ($bookmarks as $bookmark) { 311 foreach ($bookmarks as $bookmark) {
309 foreach ($bookmark->getTags() as $tag) { 312 foreach ($bookmark->getTags() as $tag) {
310 if (empty($tag) 313 if (
314 empty($tag)
311 || (! $this->isLoggedIn && startsWith($tag, '.')) 315 || (! $this->isLoggedIn && startsWith($tag, '.'))
312 || $tag === BookmarkMarkdownFormatter::NO_MD_TAG 316 || $tag === BookmarkMarkdownFormatter::NO_MD_TAG
313 || in_array($tag, $filteringTags, true) 317 || in_array($tag, $filteringTags, true)
@@ -356,7 +360,7 @@ class BookmarkFileService implements BookmarkServiceInterface
356 foreach ($this->search([], null, false, false, true) as $bookmark) { 360 foreach ($this->search([], null, false, false, true) as $bookmark) {
357 if ($to < $bookmark->getCreated()) { 361 if ($to < $bookmark->getCreated()) {
358 $next = $bookmark->getCreated(); 362 $next = $bookmark->getCreated();
359 } else if ($from < $bookmark->getCreated() && $to > $bookmark->getCreated()) { 363 } elseif ($from < $bookmark->getCreated() && $to > $bookmark->getCreated()) {
360 $out[] = $bookmark; 364 $out[] = $bookmark;
361 } else { 365 } else {
362 if ($previous !== null) { 366 if ($previous !== null) {
@@ -405,14 +409,14 @@ class BookmarkFileService implements BookmarkServiceInterface
405 false 409 false
406 ); 410 );
407 $updater = new LegacyUpdater( 411 $updater = new LegacyUpdater(
408 UpdaterUtils::read_updates_file($this->conf->get('resource.updates')), 412 UpdaterUtils::readUpdatesFile($this->conf->get('resource.updates')),
409 $bookmarkDb, 413 $bookmarkDb,
410 $this->conf, 414 $this->conf,
411 true 415 true
412 ); 416 );
413 $newUpdates = $updater->update(); 417 $newUpdates = $updater->update();
414 if (! empty($newUpdates)) { 418 if (! empty($newUpdates)) {
415 UpdaterUtils::write_updates_file( 419 UpdaterUtils::writeUpdatesFile(
416 $this->conf->get('resource.updates'), 420 $this->conf->get('resource.updates'),
417 $updater->getDoneUpdates() 421 $updater->getDoneUpdates()
418 ); 422 );
diff --git a/application/bookmark/BookmarkFilter.php b/application/bookmark/BookmarkFilter.php
index 5d8733dc..db83c51c 100644
--- a/application/bookmark/BookmarkFilter.php
+++ b/application/bookmark/BookmarkFilter.php
@@ -150,7 +150,7 @@ class BookmarkFilter
150 return $this->bookmarks; 150 return $this->bookmarks;
151 } 151 }
152 152
153 $out = array(); 153 $out = [];
154 foreach ($this->bookmarks as $key => $value) { 154 foreach ($this->bookmarks as $key => $value) {
155 if ($value->isPrivate() && $visibility === 'private') { 155 if ($value->isPrivate() && $visibility === 'private') {
156 $out[$key] = $value; 156 $out[$key] = $value;
@@ -395,7 +395,7 @@ class BookmarkFilter
395 $search = $link->getTagsString($tagsSeparator); 395 $search = $link->getTagsString($tagsSeparator);
396 if (strlen(trim($link->getDescription())) && strpos($link->getDescription(), '#') !== false) { 396 if (strlen(trim($link->getDescription())) && strpos($link->getDescription(), '#') !== false) {
397 // description given and at least one possible tag found 397 // description given and at least one possible tag found
398 $descTags = array(); 398 $descTags = [];
399 // find all tags in the form of #tag in the description 399 // find all tags in the form of #tag in the description
400 preg_match_all( 400 preg_match_all(
401 '/(?<![' . self::$HASHTAG_CHARS . '])#([' . self::$HASHTAG_CHARS . ']+?)\b/sm', 401 '/(?<![' . self::$HASHTAG_CHARS . '])#([' . self::$HASHTAG_CHARS . ']+?)\b/sm',
@@ -552,10 +552,10 @@ class BookmarkFilter
552 protected function buildFullTextSearchableLink(Bookmark $link, array &$lengths): string 552 protected function buildFullTextSearchableLink(Bookmark $link, array &$lengths): string
553 { 553 {
554 $tagString = $link->getTagsString($this->conf->get('general.tags_separator', ' ')); 554 $tagString = $link->getTagsString($this->conf->get('general.tags_separator', ' '));
555 $content = mb_convert_case($link->getTitle(), MB_CASE_LOWER, 'UTF-8') .'\\'; 555 $content = mb_convert_case($link->getTitle(), MB_CASE_LOWER, 'UTF-8') . '\\';
556 $content .= mb_convert_case($link->getDescription(), MB_CASE_LOWER, 'UTF-8') .'\\'; 556 $content .= mb_convert_case($link->getDescription(), MB_CASE_LOWER, 'UTF-8') . '\\';
557 $content .= mb_convert_case($link->getUrl(), MB_CASE_LOWER, 'UTF-8') .'\\'; 557 $content .= mb_convert_case($link->getUrl(), MB_CASE_LOWER, 'UTF-8') . '\\';
558 $content .= mb_convert_case($tagString, MB_CASE_LOWER, 'UTF-8') .'\\'; 558 $content .= mb_convert_case($tagString, MB_CASE_LOWER, 'UTF-8') . '\\';
559 559
560 $lengths['title'] = ['start' => 0, 'end' => mb_strlen($link->getTitle())]; 560 $lengths['title'] = ['start' => 0, 'end' => mb_strlen($link->getTitle())];
561 $nextField = $lengths['title']['end'] + 1; 561 $nextField = $lengths['title']['end'] + 1;
diff --git a/application/bookmark/BookmarkIO.php b/application/bookmark/BookmarkIO.php
index f40fa476..c78dbe41 100644
--- a/application/bookmark/BookmarkIO.php
+++ b/application/bookmark/BookmarkIO.php
@@ -112,12 +112,12 @@ class BookmarkIO
112 if (is_file($this->datastore) && !is_writeable($this->datastore)) { 112 if (is_file($this->datastore) && !is_writeable($this->datastore)) {
113 // The datastore exists but is not writeable 113 // The datastore exists but is not writeable
114 throw new NotWritableDataStoreException($this->datastore); 114 throw new NotWritableDataStoreException($this->datastore);
115 } else if (!is_file($this->datastore) && !is_writeable(dirname($this->datastore))) { 115 } elseif (!is_file($this->datastore) && !is_writeable(dirname($this->datastore))) {
116 // The datastore does not exist and its parent directory is not writeable 116 // The datastore does not exist and its parent directory is not writeable
117 throw new NotWritableDataStoreException(dirname($this->datastore)); 117 throw new NotWritableDataStoreException(dirname($this->datastore));
118 } 118 }
119 119
120 $data = self::$phpPrefix.base64_encode(gzdeflate(serialize($links))).self::$phpSuffix; 120 $data = self::$phpPrefix . base64_encode(gzdeflate(serialize($links))) . self::$phpSuffix;
121 121
122 $this->mutex->synchronized(function () use ($data) { 122 $this->mutex->synchronized(function () use ($data) {
123 file_put_contents( 123 file_put_contents(
diff --git a/application/bookmark/BookmarkInitializer.php b/application/bookmark/BookmarkInitializer.php
index 98dd3f1c..8ab5c441 100644
--- a/application/bookmark/BookmarkInitializer.php
+++ b/application/bookmark/BookmarkInitializer.php
@@ -13,6 +13,9 @@ namespace Shaarli\Bookmark;
13 * To prevent data corruption, it does not overwrite existing bookmarks, 13 * To prevent data corruption, it does not overwrite existing bookmarks,
14 * even though there should not be any. 14 * even though there should not be any.
15 * 15 *
16 * We disable this because otherwise it creates indentation issues, and heredoc is not supported by PHP gettext.
17 * @phpcs:disable Generic.Files.LineLength.TooLong
18 *
16 * @package Shaarli\Bookmark 19 * @package Shaarli\Bookmark
17 */ 20 */
18class BookmarkInitializer 21class BookmarkInitializer
@@ -39,7 +42,7 @@ class BookmarkInitializer
39 $bookmark->setTitle('Calm Jazz Music - YouTube ' . t('(private bookmark with thumbnail demo)')); 42 $bookmark->setTitle('Calm Jazz Music - YouTube ' . t('(private bookmark with thumbnail demo)'));
40 $bookmark->setUrl('https://www.youtube.com/watch?v=DVEUcbPkb-c'); 43 $bookmark->setUrl('https://www.youtube.com/watch?v=DVEUcbPkb-c');
41 $bookmark->setDescription(t( 44 $bookmark->setDescription(t(
42'Shaarli will automatically pick up the thumbnail for links to a variety of websites. 45 'Shaarli will automatically pick up the thumbnail for links to a variety of websites.
43 46
44Explore your new Shaarli instance by trying out controls and menus. 47Explore your new Shaarli instance by trying out controls and menus.
45Visit the project on [Github](https://github.com/shaarli/Shaarli) or [the documentation](https://shaarli.readthedocs.io/en/master/) to learn more about Shaarli. 48Visit the project on [Github](https://github.com/shaarli/Shaarli) or [the documentation](https://shaarli.readthedocs.io/en/master/) to learn more about Shaarli.
@@ -54,7 +57,7 @@ Now you can edit or delete the default shaares.
54 $bookmark = new Bookmark(); 57 $bookmark = new Bookmark();
55 $bookmark->setTitle(t('Note: Shaare descriptions')); 58 $bookmark->setTitle(t('Note: Shaare descriptions'));
56 $bookmark->setDescription(t( 59 $bookmark->setDescription(t(
57'Adding a shaare without entering a URL creates a text-only "note" post such as this one. 60 'Adding a shaare without entering a URL creates a text-only "note" post such as this one.
58This note is private, so you are the only one able to see it while logged in. 61This note is private, so you are the only one able to see it while logged in.
59 62
60You can use this to keep notes, post articles, code snippets, and much more. 63You can use this to keep notes, post articles, code snippets, and much more.
@@ -91,7 +94,7 @@ Markdown also supports tables:
91 'Shaarli - ' . t('The personal, minimalist, super-fast, database free, bookmarking service') 94 'Shaarli - ' . t('The personal, minimalist, super-fast, database free, bookmarking service')
92 ); 95 );
93 $bookmark->setDescription(t( 96 $bookmark->setDescription(t(
94'Welcome to Shaarli! 97 'Welcome to Shaarli!
95 98
96Shaarli allows you to bookmark your favorite pages, and share them with others or store them privately. 99Shaarli allows you to bookmark your favorite pages, and share them with others or store them privately.
97You can add a description to your bookmarks, such as this one, and tag them. 100You can add a description to your bookmarks, such as this one, and tag them.
diff --git a/application/bookmark/LinkUtils.php b/application/bookmark/LinkUtils.php
index cf97e3b0..d65e97ed 100644
--- a/application/bookmark/LinkUtils.php
+++ b/application/bookmark/LinkUtils.php
@@ -67,14 +67,15 @@ function html_extract_tag($tag, $html)
67 $propertiesKey = ['property', 'name', 'itemprop']; 67 $propertiesKey = ['property', 'name', 'itemprop'];
68 $properties = implode('|', $propertiesKey); 68 $properties = implode('|', $propertiesKey);
69 // We need a OR here to accept either 'property=og:noquote' or 'property="og:unrelated og:my-tag"' 69 // We need a OR here to accept either 'property=og:noquote' or 'property="og:unrelated og:my-tag"'
70 $orCondition = '["\']?(?:og:)?'. $tag .'["\']?|["\'][^\'"]*?(?:og:)?' . $tag . '[^\'"]*?[\'"]'; 70 $orCondition = '["\']?(?:og:)?' . $tag . '["\']?|["\'][^\'"]*?(?:og:)?' . $tag . '[^\'"]*?[\'"]';
71 // Try to retrieve OpenGraph tag. 71 // Try to retrieve OpenGraph tag.
72 $ogRegex = '#<meta[^>]+(?:'. $properties .')=(?:'. $orCondition .')[^>]*content=(["\'])([^\1]*?)\1.*?>#'; 72 $ogRegex = '#<meta[^>]+(?:' . $properties . ')=(?:' . $orCondition . ')[^>]*content=(["\'])([^\1]*?)\1.*?>#';
73 // If the attributes are not in the order property => content (e.g. Github) 73 // If the attributes are not in the order property => content (e.g. Github)
74 // New regex to keep this readable... more or less. 74 // New regex to keep this readable... more or less.
75 $ogRegexReverse = '#<meta[^>]+content=(["\'])([^\1]*?)\1[^>]+(?:'. $properties .')=(?:'. $orCondition .').*?>#'; 75 $ogRegexReverse = '#<meta[^>]+content=(["\'])([^\1]*?)\1[^>]+(?:' . $properties . ')=(?:' . $orCondition . ').*?>#';
76 76
77 if (preg_match($ogRegex, $html, $matches) > 0 77 if (
78 preg_match($ogRegex, $html, $matches) > 0
78 || preg_match($ogRegexReverse, $html, $matches) > 0 79 || preg_match($ogRegexReverse, $html, $matches) > 0
79 ) { 80 ) {
80 return $matches[2]; 81 return $matches[2];
@@ -116,7 +117,7 @@ function hashtag_autolink($description, $indexUrl = '')
116 * \p{Mn} - any non marking space (accents, umlauts, etc) 117 * \p{Mn} - any non marking space (accents, umlauts, etc)
117 */ 118 */
118 $regex = '/(^|\s)#([\p{Pc}\p{N}\p{L}\p{Mn}]+)/mui'; 119 $regex = '/(^|\s)#([\p{Pc}\p{N}\p{L}\p{Mn}]+)/mui';
119 $replacement = '$1<a href="'. $indexUrl .'./add-tag/$2" title="Hashtag $2">#$2</a>'; 120 $replacement = '$1<a href="' . $indexUrl . './add-tag/$2" title="Hashtag $2">#$2</a>';
120 return preg_replace($regex, $replacement, $description); 121 return preg_replace($regex, $replacement, $description);
121} 122}
122 123
diff --git a/application/bookmark/exception/BookmarkNotFoundException.php b/application/bookmark/exception/BookmarkNotFoundException.php
index 827a3d35..a91d1efa 100644
--- a/application/bookmark/exception/BookmarkNotFoundException.php
+++ b/application/bookmark/exception/BookmarkNotFoundException.php
@@ -1,4 +1,5 @@
1<?php 1<?php
2
2namespace Shaarli\Bookmark\Exception; 3namespace Shaarli\Bookmark\Exception;
3 4
4use Exception; 5use Exception;
diff --git a/application/bookmark/exception/EmptyDataStoreException.php b/application/bookmark/exception/EmptyDataStoreException.php
index cd48c1e6..16a98470 100644
--- a/application/bookmark/exception/EmptyDataStoreException.php
+++ b/application/bookmark/exception/EmptyDataStoreException.php
@@ -1,7 +1,7 @@
1<?php 1<?php
2 2
3
4namespace Shaarli\Bookmark\Exception; 3namespace Shaarli\Bookmark\Exception;
5 4
6 5class EmptyDataStoreException extends \Exception
7class EmptyDataStoreException extends \Exception {} 6{
7}
diff --git a/application/bookmark/exception/InvalidBookmarkException.php b/application/bookmark/exception/InvalidBookmarkException.php
index 10c84a6d..fe184f8c 100644
--- a/application/bookmark/exception/InvalidBookmarkException.php
+++ b/application/bookmark/exception/InvalidBookmarkException.php
@@ -16,14 +16,14 @@ class InvalidBookmarkException extends \Exception
16 } else { 16 } else {
17 $created = 'Not a DateTime object'; 17 $created = 'Not a DateTime object';
18 } 18 }
19 $this->message = 'This bookmark is not valid'. PHP_EOL; 19 $this->message = 'This bookmark is not valid' . PHP_EOL;
20 $this->message .= ' - ID: '. $bookmark->getId() . PHP_EOL; 20 $this->message .= ' - ID: ' . $bookmark->getId() . PHP_EOL;
21 $this->message .= ' - Title: '. $bookmark->getTitle() . PHP_EOL; 21 $this->message .= ' - Title: ' . $bookmark->getTitle() . PHP_EOL;
22 $this->message .= ' - Url: '. $bookmark->getUrl() . PHP_EOL; 22 $this->message .= ' - Url: ' . $bookmark->getUrl() . PHP_EOL;
23 $this->message .= ' - ShortUrl: '. $bookmark->getShortUrl() . PHP_EOL; 23 $this->message .= ' - ShortUrl: ' . $bookmark->getShortUrl() . PHP_EOL;
24 $this->message .= ' - Created: '. $created . PHP_EOL; 24 $this->message .= ' - Created: ' . $created . PHP_EOL;
25 } else { 25 } else {
26 $this->message = 'The provided data is not a bookmark'. PHP_EOL; 26 $this->message = 'The provided data is not a bookmark' . PHP_EOL;
27 $this->message .= var_export($bookmark, true); 27 $this->message .= var_export($bookmark, true);
28 } 28 }
29 } 29 }
diff --git a/application/bookmark/exception/NotWritableDataStoreException.php b/application/bookmark/exception/NotWritableDataStoreException.php
index 95f34b50..df91f3bc 100644
--- a/application/bookmark/exception/NotWritableDataStoreException.php
+++ b/application/bookmark/exception/NotWritableDataStoreException.php
@@ -1,9 +1,7 @@
1<?php 1<?php
2 2
3
4namespace Shaarli\Bookmark\Exception; 3namespace Shaarli\Bookmark\Exception;
5 4
6
7class NotWritableDataStoreException extends \Exception 5class NotWritableDataStoreException extends \Exception
8{ 6{
9 /** 7 /**
@@ -13,7 +11,7 @@ class NotWritableDataStoreException extends \Exception
13 */ 11 */
14 public function __construct($dataStore) 12 public function __construct($dataStore)
15 { 13 {
16 $this->message = 'Couldn\'t load data from the data store file "'. $dataStore .'". '. 14 $this->message = 'Couldn\'t load data from the data store file "' . $dataStore . '". ' .
17 'Your data might be corrupted, or your file isn\'t readable.'; 15 'Your data might be corrupted, or your file isn\'t readable.';
18 } 16 }
19} 17}
diff --git a/application/config/ConfigIO.php b/application/config/ConfigIO.php
index 3efe5b6f..a623bc8b 100644
--- a/application/config/ConfigIO.php
+++ b/application/config/ConfigIO.php
@@ -1,4 +1,5 @@
1<?php 1<?php
2
2namespace Shaarli\Config; 3namespace Shaarli\Config;
3 4
4/** 5/**
diff --git a/application/config/ConfigManager.php b/application/config/ConfigManager.php
index 3260d7c0..717a038f 100644
--- a/application/config/ConfigManager.php
+++ b/application/config/ConfigManager.php
@@ -1,4 +1,5 @@
1<?php 1<?php
2
2namespace Shaarli\Config; 3namespace Shaarli\Config;
3 4
4use Shaarli\Config\Exception\MissingFieldConfigException; 5use Shaarli\Config\Exception\MissingFieldConfigException;
@@ -20,7 +21,7 @@ class ConfigManager
20 */ 21 */
21 protected static $NOT_FOUND = 'NOT_FOUND'; 22 protected static $NOT_FOUND = 'NOT_FOUND';
22 23
23 public static $DEFAULT_PLUGINS = array('qrcode'); 24 public static $DEFAULT_PLUGINS = ['qrcode'];
24 25
25 /** 26 /**
26 * @var string Config folder. 27 * @var string Config folder.
@@ -133,7 +134,7 @@ class ConfigManager
133 public function set($setting, $value, $write = false, $isLoggedIn = false) 134 public function set($setting, $value, $write = false, $isLoggedIn = false)
134 { 135 {
135 if (empty($setting) || ! is_string($setting)) { 136 if (empty($setting) || ! is_string($setting)) {
136 throw new \Exception(t('Invalid setting key parameter. String expected, got: '). gettype($setting)); 137 throw new \Exception(t('Invalid setting key parameter. String expected, got: ') . gettype($setting));
137 } 138 }
138 139
139 // During the ConfigIO transition, map legacy settings to the new ones. 140 // During the ConfigIO transition, map legacy settings to the new ones.
@@ -160,7 +161,7 @@ class ConfigManager
160 public function remove($setting, $write = false, $isLoggedIn = false) 161 public function remove($setting, $write = false, $isLoggedIn = false)
161 { 162 {
162 if (empty($setting) || ! is_string($setting)) { 163 if (empty($setting) || ! is_string($setting)) {
163 throw new \Exception(t('Invalid setting key parameter. String expected, got: '). gettype($setting)); 164 throw new \Exception(t('Invalid setting key parameter. String expected, got: ') . gettype($setting));
164 } 165 }
165 166
166 // During the ConfigIO transition, map legacy settings to the new ones. 167 // During the ConfigIO transition, map legacy settings to the new ones.
@@ -213,7 +214,7 @@ class ConfigManager
213 public function write($isLoggedIn) 214 public function write($isLoggedIn)
214 { 215 {
215 // These fields are required in configuration. 216 // These fields are required in configuration.
216 $mandatoryFields = array( 217 $mandatoryFields = [
217 'credentials.login', 218 'credentials.login',
218 'credentials.hash', 219 'credentials.hash',
219 'credentials.salt', 220 'credentials.salt',
@@ -222,7 +223,7 @@ class ConfigManager
222 'general.title', 223 'general.title',
223 'general.header_link', 224 'general.header_link',
224 'privacy.default_private_links', 225 'privacy.default_private_links',
225 ); 226 ];
226 227
227 // Only logged in user can alter config. 228 // Only logged in user can alter config.
228 if (is_file($this->getConfigFileExt()) && !$isLoggedIn) { 229 if (is_file($this->getConfigFileExt()) && !$isLoggedIn) {
@@ -392,7 +393,7 @@ class ConfigManager
392 $this->setEmpty('translation.mode', 'php'); 393 $this->setEmpty('translation.mode', 'php');
393 $this->setEmpty('translation.extensions', []); 394 $this->setEmpty('translation.extensions', []);
394 395
395 $this->setEmpty('plugins', array()); 396 $this->setEmpty('plugins', []);
396 397
397 $this->setEmpty('formatter', 'markdown'); 398 $this->setEmpty('formatter', 'markdown');
398 } 399 }
diff --git a/application/config/ConfigPhp.php b/application/config/ConfigPhp.php
index cad34594..53d6a7a3 100644
--- a/application/config/ConfigPhp.php
+++ b/application/config/ConfigPhp.php
@@ -1,4 +1,5 @@
1<?php 1<?php
2
2namespace Shaarli\Config; 3namespace Shaarli\Config;
3 4
4/** 5/**
@@ -12,7 +13,7 @@ class ConfigPhp implements ConfigIO
12 /** 13 /**
13 * @var array List of config key without group. 14 * @var array List of config key without group.
14 */ 15 */
15 public static $ROOT_KEYS = array( 16 public static $ROOT_KEYS = [
16 'login', 17 'login',
17 'hash', 18 'hash',
18 'salt', 19 'salt',
@@ -22,7 +23,7 @@ class ConfigPhp implements ConfigIO
22 'redirector', 23 'redirector',
23 'disablesessionprotection', 24 'disablesessionprotection',
24 'privateLinkByDefault', 25 'privateLinkByDefault',
25 ); 26 ];
26 27
27 /** 28 /**
28 * Map legacy config keys with the new ones. 29 * Map legacy config keys with the new ones.
@@ -31,7 +32,7 @@ class ConfigPhp implements ConfigIO
31 * 32 *
32 * @var array current key => legacy key. 33 * @var array current key => legacy key.
33 */ 34 */
34 public static $LEGACY_KEYS_MAPPING = array( 35 public static $LEGACY_KEYS_MAPPING = [
35 'credentials.login' => 'login', 36 'credentials.login' => 'login',
36 'credentials.hash' => 'hash', 37 'credentials.hash' => 'hash',
37 'credentials.salt' => 'salt', 38 'credentials.salt' => 'salt',
@@ -68,7 +69,7 @@ class ConfigPhp implements ConfigIO
68 'privacy.hide_public_links' => 'config.HIDE_PUBLIC_LINKS', 69 'privacy.hide_public_links' => 'config.HIDE_PUBLIC_LINKS',
69 'privacy.hide_timestamps' => 'config.HIDE_TIMESTAMPS', 70 'privacy.hide_timestamps' => 'config.HIDE_TIMESTAMPS',
70 'security.open_shaarli' => 'config.OPEN_SHAARLI', 71 'security.open_shaarli' => 'config.OPEN_SHAARLI',
71 ); 72 ];
72 73
73 /** 74 /**
74 * @inheritdoc 75 * @inheritdoc
@@ -76,12 +77,12 @@ class ConfigPhp implements ConfigIO
76 public function read($filepath) 77 public function read($filepath)
77 { 78 {
78 if (! file_exists($filepath) || ! is_readable($filepath)) { 79 if (! file_exists($filepath) || ! is_readable($filepath)) {
79 return array(); 80 return [];
80 } 81 }
81 82
82 include $filepath; 83 include $filepath;
83 84
84 $out = array(); 85 $out = [];
85 foreach (self::$ROOT_KEYS as $key) { 86 foreach (self::$ROOT_KEYS as $key) {
86 $out[$key] = isset($GLOBALS[$key]) ? $GLOBALS[$key] : ''; 87 $out[$key] = isset($GLOBALS[$key]) ? $GLOBALS[$key] : '';
87 } 88 }
@@ -95,7 +96,7 @@ class ConfigPhp implements ConfigIO
95 */ 96 */
96 public function write($filepath, $conf) 97 public function write($filepath, $conf)
97 { 98 {
98 $configStr = '<?php '. PHP_EOL; 99 $configStr = '<?php ' . PHP_EOL;
99 foreach (self::$ROOT_KEYS as $key) { 100 foreach (self::$ROOT_KEYS as $key) {
100 if (isset($conf[$key])) { 101 if (isset($conf[$key])) {
101 $configStr .= '$GLOBALS[\'' . $key . '\'] = ' . var_export($conf[$key], true) . ';' . PHP_EOL; 102 $configStr .= '$GLOBALS[\'' . $key . '\'] = ' . var_export($conf[$key], true) . ';' . PHP_EOL;
@@ -106,8 +107,8 @@ class ConfigPhp implements ConfigIO
106 foreach ($conf['config'] as $key => $value) { 107 foreach ($conf['config'] as $key => $value) {
107 $configStr .= '$GLOBALS[\'config\'][\'' 108 $configStr .= '$GLOBALS[\'config\'][\''
108 . $key 109 . $key
109 .'\'] = ' 110 . '\'] = '
110 .var_export($conf['config'][$key], true).';' 111 . var_export($conf['config'][$key], true) . ';'
111 . PHP_EOL; 112 . PHP_EOL;
112 } 113 }
113 114
@@ -115,18 +116,19 @@ class ConfigPhp implements ConfigIO
115 foreach ($conf['plugins'] as $key => $value) { 116 foreach ($conf['plugins'] as $key => $value) {
116 $configStr .= '$GLOBALS[\'plugins\'][\'' 117 $configStr .= '$GLOBALS[\'plugins\'][\''
117 . $key 118 . $key
118 .'\'] = ' 119 . '\'] = '
119 .var_export($conf['plugins'][$key], true).';' 120 . var_export($conf['plugins'][$key], true) . ';'
120 . PHP_EOL; 121 . PHP_EOL;
121 } 122 }
122 } 123 }
123 124
124 if (!file_put_contents($filepath, $configStr) 125 if (
126 !file_put_contents($filepath, $configStr)
125 || strcmp(file_get_contents($filepath), $configStr) != 0 127 || strcmp(file_get_contents($filepath), $configStr) != 0
126 ) { 128 ) {
127 throw new \Shaarli\Exceptions\IOException( 129 throw new \Shaarli\Exceptions\IOException(
128 $filepath, 130 $filepath,
129 t('Shaarli could not create the config file. '. 131 t('Shaarli could not create the config file. ' .
130 'Please make sure Shaarli has the right to write in the folder is it installed in.') 132 'Please make sure Shaarli has the right to write in the folder is it installed in.')
131 ); 133 );
132 } 134 }
diff --git a/application/config/ConfigPlugin.php b/application/config/ConfigPlugin.php
index ea8dfbda..6cadef12 100644
--- a/application/config/ConfigPlugin.php
+++ b/application/config/ConfigPlugin.php
@@ -39,8 +39,8 @@ function save_plugin_config($formData)
39 throw new PluginConfigOrderException(); 39 throw new PluginConfigOrderException();
40 } 40 }
41 41
42 $plugins = array(); 42 $plugins = [];
43 $newEnabledPlugins = array(); 43 $newEnabledPlugins = [];
44 foreach ($formData as $key => $data) { 44 foreach ($formData as $key => $data) {
45 if (startsWith($key, 'order')) { 45 if (startsWith($key, 'order')) {
46 continue; 46 continue;
@@ -62,7 +62,7 @@ function save_plugin_config($formData)
62 throw new PluginConfigOrderException(); 62 throw new PluginConfigOrderException();
63 } 63 }
64 64
65 $finalPlugins = array(); 65 $finalPlugins = [];
66 // Make plugins order continuous. 66 // Make plugins order continuous.
67 foreach ($plugins as $plugin) { 67 foreach ($plugins as $plugin) {
68 $finalPlugins[] = $plugin; 68 $finalPlugins[] = $plugin;
@@ -81,7 +81,7 @@ function save_plugin_config($formData)
81 */ 81 */
82function validate_plugin_order($formData) 82function validate_plugin_order($formData)
83{ 83{
84 $orders = array(); 84 $orders = [];
85 foreach ($formData as $key => $value) { 85 foreach ($formData as $key => $value) {
86 // No duplicate order allowed. 86 // No duplicate order allowed.
87 if (in_array($value, $orders, true)) { 87 if (in_array($value, $orders, true)) {
diff --git a/application/config/exception/MissingFieldConfigException.php b/application/config/exception/MissingFieldConfigException.php
index 9e0a9359..a5f4356a 100644
--- a/application/config/exception/MissingFieldConfigException.php
+++ b/application/config/exception/MissingFieldConfigException.php
@@ -1,6 +1,5 @@
1<?php 1<?php
2 2
3
4namespace Shaarli\Config\Exception; 3namespace Shaarli\Config\Exception;
5 4
6/** 5/**
diff --git a/application/config/exception/UnauthorizedConfigException.php b/application/config/exception/UnauthorizedConfigException.php
index 72311fae..b041c6e3 100644
--- a/application/config/exception/UnauthorizedConfigException.php
+++ b/application/config/exception/UnauthorizedConfigException.php
@@ -1,6 +1,5 @@
1<?php 1<?php
2 2
3
4namespace Shaarli\Config\Exception; 3namespace Shaarli\Config\Exception;
5 4
6/** 5/**
diff --git a/application/container/ContainerBuilder.php b/application/container/ContainerBuilder.php
index d84418ad..f0234eca 100644
--- a/application/container/ContainerBuilder.php
+++ b/application/container/ContainerBuilder.php
@@ -158,7 +158,7 @@ class ContainerBuilder
158 158
159 $container['updater'] = function (ShaarliContainer $container): Updater { 159 $container['updater'] = function (ShaarliContainer $container): Updater {
160 return new Updater( 160 return new Updater(
161 UpdaterUtils::read_updates_file($container->conf->get('resource.updates')), 161 UpdaterUtils::readUpdatesFile($container->conf->get('resource.updates')),
162 $container->bookmarkService, 162 $container->bookmarkService,
163 $container->conf, 163 $container->conf,
164 $container->loginManager->isLoggedIn() 164 $container->loginManager->isLoggedIn()
diff --git a/application/exceptions/IOException.php b/application/exceptions/IOException.php
index 2aa25e5c..c1a9ffbe 100644
--- a/application/exceptions/IOException.php
+++ b/application/exceptions/IOException.php
@@ -1,4 +1,5 @@
1<?php 1<?php
2
2namespace Shaarli\Exceptions; 3namespace Shaarli\Exceptions;
3 4
4use Exception; 5use Exception;
diff --git a/application/feed/FeedBuilder.php b/application/feed/FeedBuilder.php
index f70fce4f..ed62af26 100644
--- a/application/feed/FeedBuilder.php
+++ b/application/feed/FeedBuilder.php
@@ -1,4 +1,5 @@
1<?php 1<?php
2
2namespace Shaarli\Feed; 3namespace Shaarli\Feed;
3 4
4use DateTime; 5use DateTime;
@@ -107,14 +108,14 @@ class FeedBuilder
107 $nblinksToDisplay = $this->getNbLinks(count($linksToDisplay), $userInput); 108 $nblinksToDisplay = $this->getNbLinks(count($linksToDisplay), $userInput);
108 109
109 // Can't use array_keys() because $link is a LinkDB instance and not a real array. 110 // Can't use array_keys() because $link is a LinkDB instance and not a real array.
110 $keys = array(); 111 $keys = [];
111 foreach ($linksToDisplay as $key => $value) { 112 foreach ($linksToDisplay as $key => $value) {
112 $keys[] = $key; 113 $keys[] = $key;
113 } 114 }
114 115
115 $pageaddr = escape(index_url($this->serverInfo)); 116 $pageaddr = escape(index_url($this->serverInfo));
116 $this->formatter->addContextData('index_url', $pageaddr); 117 $this->formatter->addContextData('index_url', $pageaddr);
117 $linkDisplayed = array(); 118 $linkDisplayed = [];
118 for ($i = 0; $i < $nblinksToDisplay && $i < count($keys); $i++) { 119 for ($i = 0; $i < $nblinksToDisplay && $i < count($keys); $i++) {
119 $linkDisplayed[$keys[$i]] = $this->buildItem($feedType, $linksToDisplay[$keys[$i]], $pageaddr); 120 $linkDisplayed[$keys[$i]] = $this->buildItem($feedType, $linksToDisplay[$keys[$i]], $pageaddr);
120 } 121 }
@@ -176,9 +177,9 @@ class FeedBuilder
176 $data = $this->formatter->format($link); 177 $data = $this->formatter->format($link);
177 $data['guid'] = rtrim($pageaddr, '/') . '/shaare/' . $data['shorturl']; 178 $data['guid'] = rtrim($pageaddr, '/') . '/shaare/' . $data['shorturl'];
178 if ($this->usePermalinks === true) { 179 if ($this->usePermalinks === true) {
179 $permalink = '<a href="'. $data['url'] .'" title="'. t('Direct link') .'">'. t('Direct link') .'</a>'; 180 $permalink = '<a href="' . $data['url'] . '" title="' . t('Direct link') . '">' . t('Direct link') . '</a>';
180 } else { 181 } else {
181 $permalink = '<a href="'. $data['guid'] .'" title="'. t('Permalink') .'">'. t('Permalink') .'</a>'; 182 $permalink = '<a href="' . $data['guid'] . '" title="' . t('Permalink') . '">' . t('Permalink') . '</a>';
182 } 183 }
183 $data['description'] .= PHP_EOL . PHP_EOL . '<br>&#8212; ' . $permalink; 184 $data['description'] .= PHP_EOL . PHP_EOL . '<br>&#8212; ' . $permalink;
184 185
diff --git a/application/formatter/BookmarkDefaultFormatter.php b/application/formatter/BookmarkDefaultFormatter.php
index 51bea0f1..7e0afafc 100644
--- a/application/formatter/BookmarkDefaultFormatter.php
+++ b/application/formatter/BookmarkDefaultFormatter.php
@@ -12,8 +12,8 @@ namespace Shaarli\Formatter;
12 */ 12 */
13class BookmarkDefaultFormatter extends BookmarkFormatter 13class BookmarkDefaultFormatter extends BookmarkFormatter
14{ 14{
15 const SEARCH_HIGHLIGHT_OPEN = '|@@HIGHLIGHT'; 15 protected const SEARCH_HIGHLIGHT_OPEN = '|@@HIGHLIGHT';
16 const SEARCH_HIGHLIGHT_CLOSE = 'HIGHLIGHT@@|'; 16 protected const SEARCH_HIGHLIGHT_CLOSE = 'HIGHLIGHT@@|';
17 17
18 /** 18 /**
19 * @inheritdoc 19 * @inheritdoc
diff --git a/application/formatter/BookmarkMarkdownFormatter.php b/application/formatter/BookmarkMarkdownFormatter.php
index f7714be9..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;
@@ -71,7 +71,7 @@ class BookmarkMarkdownFormatter extends BookmarkDefaultFormatter
71 $processedDescription = $this->replaceTokens($processedDescription); 71 $processedDescription = $this->replaceTokens($processedDescription);
72 72
73 if (!empty($processedDescription)) { 73 if (!empty($processedDescription)) {
74 $processedDescription = '<div class="markdown">'. $processedDescription . '</div>'; 74 $processedDescription = '<div class="markdown">' . $processedDescription . '</div>';
75 } 75 }
76 76
77 return $processedDescription; 77 return $processedDescription;
@@ -110,7 +110,7 @@ class BookmarkMarkdownFormatter extends BookmarkDefaultFormatter
110 function ($match) use ($allowedProtocols, $indexUrl) { 110 function ($match) use ($allowedProtocols, $indexUrl) {
111 $link = startsWith($match[1], '?') || startsWith($match[1], '/') ? $indexUrl : ''; 111 $link = startsWith($match[1], '?') || startsWith($match[1], '/') ? $indexUrl : '';
112 $link .= whitelist_protocols($match[1], $allowedProtocols); 112 $link .= whitelist_protocols($match[1], $allowedProtocols);
113 return ']('. $link.')'; 113 return '](' . $link . ')';
114 }, 114 },
115 $description 115 $description
116 ); 116 );
@@ -137,7 +137,7 @@ class BookmarkMarkdownFormatter extends BookmarkDefaultFormatter
137 * \p{Mn} - any non marking space (accents, umlauts, etc) 137 * \p{Mn} - any non marking space (accents, umlauts, etc)
138 */ 138 */
139 $regex = '/(^|\s)#([\p{Pc}\p{N}\p{L}\p{Mn}]+)/mui'; 139 $regex = '/(^|\s)#([\p{Pc}\p{N}\p{L}\p{Mn}]+)/mui';
140 $replacement = '$1[#$2]('. $indexUrl .'./add-tag/$2)'; 140 $replacement = '$1[#$2](' . $indexUrl . './add-tag/$2)';
141 141
142 $descriptionLines = explode(PHP_EOL, $description); 142 $descriptionLines = explode(PHP_EOL, $description);
143 $descriptionOut = ''; 143 $descriptionOut = '';
@@ -178,17 +178,17 @@ class BookmarkMarkdownFormatter extends BookmarkDefaultFormatter
178 */ 178 */
179 protected function sanitizeHtml($description) 179 protected function sanitizeHtml($description)
180 { 180 {
181 $escapeTags = array( 181 $escapeTags = [
182 'script', 182 'script',
183 'style', 183 'style',
184 'link', 184 'link',
185 'iframe', 185 'iframe',
186 'frameset', 186 'frameset',
187 'frame', 187 'frame',
188 ); 188 ];
189 foreach ($escapeTags as $tag) { 189 foreach ($escapeTags as $tag) {
190 $description = preg_replace_callback( 190 $description = preg_replace_callback(
191 '#<\s*'. $tag .'[^>]*>(.*</\s*'. $tag .'[^>]*>)?#is', 191 '#<\s*' . $tag . '[^>]*>(.*</\s*' . $tag . '[^>]*>)?#is',
192 function ($match) { 192 function ($match) {
193 return escape($match[0]); 193 return escape($match[0]);
194 }, 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 */
13class BookmarkRawFormatter extends BookmarkFormatter {} 13class 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 }
diff --git a/application/front/ShaarliMiddleware.php b/application/front/ShaarliMiddleware.php
index d1aa1399..164217f4 100644
--- a/application/front/ShaarliMiddleware.php
+++ b/application/front/ShaarliMiddleware.php
@@ -42,7 +42,8 @@ class ShaarliMiddleware
42 $this->initBasePath($request); 42 $this->initBasePath($request);
43 43
44 try { 44 try {
45 if (!is_file($this->container->conf->getConfigFileExt()) 45 if (
46 !is_file($this->container->conf->getConfigFileExt())
46 && !in_array($next->getName(), ['displayInstall', 'saveInstall'], true) 47 && !in_array($next->getName(), ['displayInstall', 'saveInstall'], true)
47 ) { 48 ) {
48 return $response->withRedirect($this->container->basePath . '/install'); 49 return $response->withRedirect($this->container->basePath . '/install');
@@ -86,7 +87,8 @@ class ShaarliMiddleware
86 */ 87 */
87 protected function checkOpenShaarli(Request $request, Response $response, callable $next): bool 88 protected function checkOpenShaarli(Request $request, Response $response, callable $next): bool
88 { 89 {
89 if (// if the user isn't logged in 90 if (
91// if the user isn't logged in
90 !$this->container->loginManager->isLoggedIn() 92 !$this->container->loginManager->isLoggedIn()
91 // and Shaarli doesn't have public content... 93 // and Shaarli doesn't have public content...
92 && $this->container->conf->get('privacy.hide_public_links') 94 && $this->container->conf->get('privacy.hide_public_links')
diff --git a/application/front/controller/admin/ConfigureController.php b/application/front/controller/admin/ConfigureController.php
index 0ed7ad81..dc421661 100644
--- a/application/front/controller/admin/ConfigureController.php
+++ b/application/front/controller/admin/ConfigureController.php
@@ -51,7 +51,10 @@ class ConfigureController extends ShaarliAdminController
51 $this->assignView('languages', Languages::getAvailableLanguages()); 51 $this->assignView('languages', Languages::getAvailableLanguages());
52 $this->assignView('gd_enabled', extension_loaded('gd')); 52 $this->assignView('gd_enabled', extension_loaded('gd'));
53 $this->assignView('thumbnails_mode', $this->container->conf->get('thumbnails.mode', Thumbnailer::MODE_NONE)); 53 $this->assignView('thumbnails_mode', $this->container->conf->get('thumbnails.mode', Thumbnailer::MODE_NONE));
54 $this->assignView('pagetitle', t('Configure') .' - '. $this->container->conf->get('general.title', 'Shaarli')); 54 $this->assignView(
55 'pagetitle',
56 t('Configure') . ' - ' . $this->container->conf->get('general.title', 'Shaarli')
57 );
55 58
56 return $response->write($this->render(TemplatePage::CONFIGURE)); 59 return $response->write($this->render(TemplatePage::CONFIGURE));
57 } 60 }
@@ -95,12 +98,15 @@ class ConfigureController extends ShaarliAdminController
95 } 98 }
96 99
97 $thumbnailsMode = extension_loaded('gd') ? $request->getParam('enableThumbnails') : Thumbnailer::MODE_NONE; 100 $thumbnailsMode = extension_loaded('gd') ? $request->getParam('enableThumbnails') : Thumbnailer::MODE_NONE;
98 if ($thumbnailsMode !== Thumbnailer::MODE_NONE 101 if (
102 $thumbnailsMode !== Thumbnailer::MODE_NONE
99 && $thumbnailsMode !== $this->container->conf->get('thumbnails.mode', Thumbnailer::MODE_NONE) 103 && $thumbnailsMode !== $this->container->conf->get('thumbnails.mode', Thumbnailer::MODE_NONE)
100 ) { 104 ) {
101 $this->saveWarningMessage( 105 $this->saveWarningMessage(
102 t('You have enabled or changed thumbnails mode.') . 106 t('You have enabled or changed thumbnails mode.') .
103 '<a href="'. $this->container->basePath .'/admin/thumbnails">' . t('Please synchronize them.') .'</a>' 107 '<a href="' . $this->container->basePath . '/admin/thumbnails">' .
108 t('Please synchronize them.') .
109 '</a>'
104 ); 110 );
105 } 111 }
106 $this->container->conf->set('thumbnails.mode', $thumbnailsMode); 112 $this->container->conf->set('thumbnails.mode', $thumbnailsMode);
diff --git a/application/front/controller/admin/ExportController.php b/application/front/controller/admin/ExportController.php
index 2be957fa..f01d7e9b 100644
--- a/application/front/controller/admin/ExportController.php
+++ b/application/front/controller/admin/ExportController.php
@@ -23,7 +23,7 @@ class ExportController extends ShaarliAdminController
23 */ 23 */
24 public function index(Request $request, Response $response): Response 24 public function index(Request $request, Response $response): Response
25 { 25 {
26 $this->assignView('pagetitle', t('Export') .' - '. $this->container->conf->get('general.title', 'Shaarli')); 26 $this->assignView('pagetitle', t('Export') . ' - ' . $this->container->conf->get('general.title', 'Shaarli'));
27 27
28 return $response->write($this->render(TemplatePage::EXPORT)); 28 return $response->write($this->render(TemplatePage::EXPORT));
29 } 29 }
@@ -68,7 +68,7 @@ class ExportController extends ShaarliAdminController
68 $response = $response->withHeader('Content-Type', 'text/html; charset=utf-8'); 68 $response = $response->withHeader('Content-Type', 'text/html; charset=utf-8');
69 $response = $response->withHeader( 69 $response = $response->withHeader(
70 'Content-disposition', 70 'Content-disposition',
71 'attachment; filename=bookmarks_'.$selection.'_'.$now->format(Bookmark::LINK_DATE_FORMAT).'.html' 71 'attachment; filename=bookmarks_' . $selection . '_' . $now->format(Bookmark::LINK_DATE_FORMAT) . '.html'
72 ); 72 );
73 73
74 $this->assignView('date', $now->format(DateTime::RFC822)); 74 $this->assignView('date', $now->format(DateTime::RFC822));
diff --git a/application/front/controller/admin/ImportController.php b/application/front/controller/admin/ImportController.php
index 758d5ef9..c2ad6a09 100644
--- a/application/front/controller/admin/ImportController.php
+++ b/application/front/controller/admin/ImportController.php
@@ -38,7 +38,7 @@ class ImportController extends ShaarliAdminController
38 true 38 true
39 ) 39 )
40 ); 40 );
41 $this->assignView('pagetitle', t('Import') .' - '. $this->container->conf->get('general.title', 'Shaarli')); 41 $this->assignView('pagetitle', t('Import') . ' - ' . $this->container->conf->get('general.title', 'Shaarli'));
42 42
43 return $response->write($this->render(TemplatePage::IMPORT)); 43 return $response->write($this->render(TemplatePage::IMPORT));
44 } 44 }
@@ -64,7 +64,7 @@ class ImportController extends ShaarliAdminController
64 $msg = sprintf( 64 $msg = sprintf(
65 t( 65 t(
66 'The file you are trying to upload is probably bigger than what this webserver can accept' 66 'The file you are trying to upload is probably bigger than what this webserver can accept'
67 .' (%s). Please upload in smaller chunks.' 67 . ' (%s). Please upload in smaller chunks.'
68 ), 68 ),
69 get_max_upload_size(ini_get('post_max_size'), ini_get('upload_max_filesize')) 69 get_max_upload_size(ini_get('post_max_size'), ini_get('upload_max_filesize'))
70 ); 70 );
diff --git a/application/front/controller/admin/ManageTagController.php b/application/front/controller/admin/ManageTagController.php
index 22fb461c..8675a0c5 100644
--- a/application/front/controller/admin/ManageTagController.php
+++ b/application/front/controller/admin/ManageTagController.php
@@ -32,7 +32,7 @@ class ManageTagController extends ShaarliAdminController
32 $this->assignView('tags_separator', $separator); 32 $this->assignView('tags_separator', $separator);
33 $this->assignView( 33 $this->assignView(
34 'pagetitle', 34 'pagetitle',
35 t('Manage tags') .' - '. $this->container->conf->get('general.title', 'Shaarli') 35 t('Manage tags') . ' - ' . $this->container->conf->get('general.title', 'Shaarli')
36 ); 36 );
37 37
38 return $response->write($this->render(TemplatePage::CHANGE_TAG)); 38 return $response->write($this->render(TemplatePage::CHANGE_TAG));
@@ -87,7 +87,7 @@ class ManageTagController extends ShaarliAdminController
87 87
88 $this->saveSuccessMessage($alert); 88 $this->saveSuccessMessage($alert);
89 89
90 $redirect = true === $isDelete ? '/admin/tags' : '/?searchtags='. urlencode($toTag); 90 $redirect = true === $isDelete ? '/admin/tags' : '/?searchtags=' . urlencode($toTag);
91 91
92 return $this->redirect($response, $redirect); 92 return $this->redirect($response, $redirect);
93 } 93 }
diff --git a/application/front/controller/admin/PasswordController.php b/application/front/controller/admin/PasswordController.php
index 5ec0d24b..4aaf1f82 100644
--- a/application/front/controller/admin/PasswordController.php
+++ b/application/front/controller/admin/PasswordController.php
@@ -25,7 +25,7 @@ class PasswordController extends ShaarliAdminController
25 25
26 $this->assignView( 26 $this->assignView(
27 'pagetitle', 27 'pagetitle',
28 t('Change password') .' - '. $this->container->conf->get('general.title', 'Shaarli') 28 t('Change password') . ' - ' . $this->container->conf->get('general.title', 'Shaarli')
29 ); 29 );
30 } 30 }
31 31
@@ -78,7 +78,7 @@ class PasswordController extends ShaarliAdminController
78 78
79 // Save new password 79 // Save new password
80 // Salt renders rainbow-tables attacks useless. 80 // Salt renders rainbow-tables attacks useless.
81 $this->container->conf->set('credentials.salt', sha1(uniqid('', true) .'_'. mt_rand())); 81 $this->container->conf->set('credentials.salt', sha1(uniqid('', true) . '_' . mt_rand()));
82 $this->container->conf->set( 82 $this->container->conf->set(
83 'credentials.hash', 83 'credentials.hash',
84 sha1( 84 sha1(
diff --git a/application/front/controller/admin/PluginsController.php b/application/front/controller/admin/PluginsController.php
index 8e059681..ae47c1af 100644
--- a/application/front/controller/admin/PluginsController.php
+++ b/application/front/controller/admin/PluginsController.php
@@ -42,7 +42,7 @@ class PluginsController extends ShaarliAdminController
42 $this->assignView('disabledPlugins', $disabledPlugins); 42 $this->assignView('disabledPlugins', $disabledPlugins);
43 $this->assignView( 43 $this->assignView(
44 'pagetitle', 44 'pagetitle',
45 t('Plugin Administration') .' - '. $this->container->conf->get('general.title', 'Shaarli') 45 t('Plugin Administration') . ' - ' . $this->container->conf->get('general.title', 'Shaarli')
46 ); 46 );
47 47
48 return $response->write($this->render(TemplatePage::PLUGINS_ADMIN)); 48 return $response->write($this->render(TemplatePage::PLUGINS_ADMIN));
@@ -64,7 +64,7 @@ class PluginsController extends ShaarliAdminController
64 unset($parameters['parameters_form']); 64 unset($parameters['parameters_form']);
65 unset($parameters['token']); 65 unset($parameters['token']);
66 foreach ($parameters as $param => $value) { 66 foreach ($parameters as $param => $value) {
67 $this->container->conf->set('plugins.'. $param, escape($value)); 67 $this->container->conf->set('plugins.' . $param, escape($value));
68 } 68 }
69 } else { 69 } else {
70 $this->container->conf->set('general.enabled_plugins', save_plugin_config($parameters)); 70 $this->container->conf->set('general.enabled_plugins', save_plugin_config($parameters));
diff --git a/application/front/controller/admin/ServerController.php b/application/front/controller/admin/ServerController.php
index 780151dd..fabeaf2f 100644
--- a/application/front/controller/admin/ServerController.php
+++ b/application/front/controller/admin/ServerController.php
@@ -72,7 +72,9 @@ class ServerController extends ShaarliAdminController
72 72
73 $this->saveWarningMessage( 73 $this->saveWarningMessage(
74 t('Thumbnails cache has been cleared.') . ' ' . 74 t('Thumbnails cache has been cleared.') . ' ' .
75 '<a href="'. $this->container->basePath .'/admin/thumbnails">' . t('Please synchronize them.') .'</a>' 75 '<a href="' . $this->container->basePath . '/admin/thumbnails">' .
76 t('Please synchronize them.') .
77 '</a>'
76 ); 78 );
77 } else { 79 } else {
78 $folders = [ 80 $folders = [
diff --git a/application/front/controller/admin/SessionFilterController.php b/application/front/controller/admin/SessionFilterController.php
index d9a7a2e0..0917b6d2 100644
--- a/application/front/controller/admin/SessionFilterController.php
+++ b/application/front/controller/admin/SessionFilterController.php
@@ -45,6 +45,4 @@ class SessionFilterController extends ShaarliAdminController
45 45
46 return $this->redirectFromReferer($request, $response, ['visibility']); 46 return $this->redirectFromReferer($request, $response, ['visibility']);
47 } 47 }
48
49
50} 48}
diff --git a/application/front/controller/admin/ShaareAddController.php b/application/front/controller/admin/ShaareAddController.php
index 8dc386b2..ab8e7f40 100644
--- a/application/front/controller/admin/ShaareAddController.php
+++ b/application/front/controller/admin/ShaareAddController.php
@@ -23,7 +23,7 @@ class ShaareAddController extends ShaarliAdminController
23 23
24 $this->assignView( 24 $this->assignView(
25 'pagetitle', 25 'pagetitle',
26 t('Shaare a new link') .' - '. $this->container->conf->get('general.title', 'Shaarli') 26 t('Shaare a new link') . ' - ' . $this->container->conf->get('general.title', 'Shaarli')
27 ); 27 );
28 $this->assignView('tags', $tags); 28 $this->assignView('tags', $tags);
29 $this->assignView('default_private_links', $this->container->conf->get('privacy.default_private_links', false)); 29 $this->assignView('default_private_links', $this->container->conf->get('privacy.default_private_links', false));
diff --git a/application/front/controller/admin/ShaareManageController.php b/application/front/controller/admin/ShaareManageController.php
index 0b143172..35837baa 100644
--- a/application/front/controller/admin/ShaareManageController.php
+++ b/application/front/controller/admin/ShaareManageController.php
@@ -54,7 +54,7 @@ class ShaareManageController extends ShaarliAdminController
54 $data = $formatter->format($bookmark); 54 $data = $formatter->format($bookmark);
55 $this->executePageHooks('delete_link', $data); 55 $this->executePageHooks('delete_link', $data);
56 $this->container->bookmarkService->remove($bookmark, false); 56 $this->container->bookmarkService->remove($bookmark, false);
57 ++ $count; 57 ++$count;
58 } 58 }
59 59
60 if ($count > 0) { 60 if ($count > 0) {
diff --git a/application/front/controller/admin/ShaarePublishController.php b/application/front/controller/admin/ShaarePublishController.php
index 625a5680..4cbfcdc5 100644
--- a/application/front/controller/admin/ShaarePublishController.php
+++ b/application/front/controller/admin/ShaarePublishController.php
@@ -118,7 +118,8 @@ class ShaarePublishController extends ShaarliAdminController
118 $this->container->conf->get('general.tags_separator', ' ') 118 $this->container->conf->get('general.tags_separator', ' ')
119 ); 119 );
120 120
121 if ($this->container->conf->get('thumbnails.mode', Thumbnailer::MODE_NONE) !== Thumbnailer::MODE_NONE 121 if (
122 $this->container->conf->get('thumbnails.mode', Thumbnailer::MODE_NONE) !== Thumbnailer::MODE_NONE
122 && true !== $this->container->conf->get('general.enable_async_metadata', true) 123 && true !== $this->container->conf->get('general.enable_async_metadata', true)
123 && $bookmark->shouldUpdateThumbnail() 124 && $bookmark->shouldUpdateThumbnail()
124 ) { 125 ) {
@@ -148,7 +149,8 @@ class ShaarePublishController extends ShaarliAdminController
148 return $this->redirectFromReferer( 149 return $this->redirectFromReferer(
149 $request, 150 $request,
150 $response, 151 $response,
151 ['/admin/add-shaare', '/admin/shaare'], ['addlink', 'post', 'edit_link'], 152 ['/admin/add-shaare', '/admin/shaare'],
153 ['addlink', 'post', 'edit_link'],
152 $bookmark->getShortUrl() 154 $bookmark->getShortUrl()
153 ); 155 );
154 } 156 }
@@ -168,10 +170,10 @@ class ShaarePublishController extends ShaarliAdminController
168 $this->assignView($key, $value); 170 $this->assignView($key, $value);
169 } 171 }
170 172
171 $editLabel = false === $isNew ? t('Edit') .' ' : ''; 173 $editLabel = false === $isNew ? t('Edit') . ' ' : '';
172 $this->assignView( 174 $this->assignView(
173 'pagetitle', 175 'pagetitle',
174 $editLabel . t('Shaare') .' - '. $this->container->conf->get('general.title', 'Shaarli') 176 $editLabel . t('Shaare') . ' - ' . $this->container->conf->get('general.title', 'Shaarli')
175 ); 177 );
176 178
177 return $response->write($this->render(TemplatePage::EDIT_LINK)); 179 return $response->write($this->render(TemplatePage::EDIT_LINK));
@@ -194,7 +196,8 @@ class ShaarePublishController extends ShaarliAdminController
194 196
195 // If this is an HTTP(S) link, we try go get the page to extract 197 // If this is an HTTP(S) link, we try go get the page to extract
196 // the title (otherwise we will to straight to the edit form.) 198 // the title (otherwise we will to straight to the edit form.)
197 if (true !== $this->container->conf->get('general.enable_async_metadata', true) 199 if (
200 true !== $this->container->conf->get('general.enable_async_metadata', true)
198 && empty($title) 201 && empty($title)
199 && strpos(get_url_scheme($url) ?: '', 'http') !== false 202 && strpos(get_url_scheme($url) ?: '', 'http') !== false
200 ) { 203 ) {
diff --git a/application/front/controller/admin/ThumbnailsController.php b/application/front/controller/admin/ThumbnailsController.php
index 4dc09d38..94d97d4b 100644
--- a/application/front/controller/admin/ThumbnailsController.php
+++ b/application/front/controller/admin/ThumbnailsController.php
@@ -34,7 +34,7 @@ class ThumbnailsController extends ShaarliAdminController
34 $this->assignView('ids', $ids); 34 $this->assignView('ids', $ids);
35 $this->assignView( 35 $this->assignView(
36 'pagetitle', 36 'pagetitle',
37 t('Thumbnails update') .' - '. $this->container->conf->get('general.title', 'Shaarli') 37 t('Thumbnails update') . ' - ' . $this->container->conf->get('general.title', 'Shaarli')
38 ); 38 );
39 39
40 return $response->write($this->render(TemplatePage::THUMBNAILS)); 40 return $response->write($this->render(TemplatePage::THUMBNAILS));
diff --git a/application/front/controller/admin/ToolsController.php b/application/front/controller/admin/ToolsController.php
index a87f20d2..560e5e3e 100644
--- a/application/front/controller/admin/ToolsController.php
+++ b/application/front/controller/admin/ToolsController.php
@@ -28,7 +28,7 @@ class ToolsController extends ShaarliAdminController
28 $this->assignView($key, $value); 28 $this->assignView($key, $value);
29 } 29 }
30 30
31 $this->assignView('pagetitle', t('Tools') .' - '. $this->container->conf->get('general.title', 'Shaarli')); 31 $this->assignView('pagetitle', t('Tools') . ' - ' . $this->container->conf->get('general.title', 'Shaarli'));
32 32
33 return $response->write($this->render(TemplatePage::TOOLS)); 33 return $response->write($this->render(TemplatePage::TOOLS));
34 } 34 }
diff --git a/application/front/controller/visitor/BookmarkListController.php b/application/front/controller/visitor/BookmarkListController.php
index cc3837ce..fe8231be 100644
--- a/application/front/controller/visitor/BookmarkListController.php
+++ b/application/front/controller/visitor/BookmarkListController.php
@@ -35,7 +35,8 @@ class BookmarkListController extends ShaarliVisitorController
35 $formatter->addContextData('base_path', $this->container->basePath); 35 $formatter->addContextData('base_path', $this->container->basePath);
36 36
37 $searchTags = normalize_spaces($request->getParam('searchtags') ?? ''); 37 $searchTags = normalize_spaces($request->getParam('searchtags') ?? '');
38 $searchTerm = escape(normalize_spaces($request->getParam('searchterm') ?? ''));; 38 $searchTerm = escape(normalize_spaces($request->getParam('searchterm') ?? ''));
39 ;
39 40
40 // Filter bookmarks according search parameters. 41 // Filter bookmarks according search parameters.
41 $visibility = $this->container->sessionManager->getSessionParameter('visibility'); 42 $visibility = $this->container->sessionManager->getSessionParameter('visibility');
@@ -160,7 +161,7 @@ class BookmarkListController extends ShaarliVisitorController
160 $data = array_merge( 161 $data = array_merge(
161 $this->initializeTemplateVars(), 162 $this->initializeTemplateVars(),
162 [ 163 [
163 'pagetitle' => $bookmark->getTitle() .' - '. $this->container->conf->get('general.title', 'Shaarli'), 164 'pagetitle' => $bookmark->getTitle() . ' - ' . $this->container->conf->get('general.title', 'Shaarli'),
164 'links' => [$formatter->format($bookmark)], 165 'links' => [$formatter->format($bookmark)],
165 ] 166 ]
166 ); 167 );
@@ -185,7 +186,8 @@ class BookmarkListController extends ShaarliVisitorController
185 $bookmark->setThumbnail(null); 186 $bookmark->setThumbnail(null);
186 187
187 // Requires an update, not async retrieval, thumbnails enabled 188 // Requires an update, not async retrieval, thumbnails enabled
188 if ($bookmark->shouldUpdateThumbnail() 189 if (
190 $bookmark->shouldUpdateThumbnail()
189 && true !== $this->container->conf->get('general.enable_async_metadata', true) 191 && true !== $this->container->conf->get('general.enable_async_metadata', true)
190 && $this->container->conf->get('thumbnails.mode', Thumbnailer::MODE_NONE) !== Thumbnailer::MODE_NONE 192 && $this->container->conf->get('thumbnails.mode', Thumbnailer::MODE_NONE) !== Thumbnailer::MODE_NONE
191 ) { 193 ) {
diff --git a/application/front/controller/visitor/DailyController.php b/application/front/controller/visitor/DailyController.php
index 728bc2d8..846cfe22 100644
--- a/application/front/controller/visitor/DailyController.php
+++ b/application/front/controller/visitor/DailyController.php
@@ -132,7 +132,7 @@ class DailyController extends ShaarliVisitorController
132 'date' => $endDateTime, 132 'date' => $endDateTime,
133 'date_rss' => $endDateTime->format(DateTime::RSS), 133 'date_rss' => $endDateTime->format(DateTime::RSS),
134 'date_human' => DailyPageHelper::getDescriptionByType($type, $dayDateTime), 134 'date_human' => DailyPageHelper::getDescriptionByType($type, $dayDateTime),
135 'absolute_url' => $indexUrl . 'daily?'. $type .'=' . $day, 135 'absolute_url' => $indexUrl . 'daily?' . $type . '=' . $day,
136 'links' => [], 136 'links' => [],
137 ]; 137 ];
138 138
diff --git a/application/front/controller/visitor/FeedController.php b/application/front/controller/visitor/FeedController.php
index 8d8b546a..edc7ef43 100644
--- a/application/front/controller/visitor/FeedController.php
+++ b/application/front/controller/visitor/FeedController.php
@@ -27,7 +27,7 @@ class FeedController extends ShaarliVisitorController
27 27
28 protected function processRequest(string $feedType, Request $request, Response $response): Response 28 protected function processRequest(string $feedType, Request $request, Response $response): Response
29 { 29 {
30 $response = $response->withHeader('Content-Type', 'application/'. $feedType .'+xml; charset=utf-8'); 30 $response = $response->withHeader('Content-Type', 'application/' . $feedType . '+xml; charset=utf-8');
31 31
32 $pageUrl = page_url($this->container->environment); 32 $pageUrl = page_url($this->container->environment);
33 $cache = $this->container->pageCacheManager->getCachePage($pageUrl); 33 $cache = $this->container->pageCacheManager->getCachePage($pageUrl);
diff --git a/application/front/controller/visitor/InstallController.php b/application/front/controller/visitor/InstallController.php
index 22329294..bf965929 100644
--- a/application/front/controller/visitor/InstallController.php
+++ b/application/front/controller/visitor/InstallController.php
@@ -39,7 +39,8 @@ class InstallController extends ShaarliVisitorController
39 // Before installation, we'll make sure that permissions are set properly, and sessions are working. 39 // Before installation, we'll make sure that permissions are set properly, and sessions are working.
40 $this->checkPermissions(); 40 $this->checkPermissions();
41 41
42 if (static::SESSION_TEST_VALUE 42 if (
43 static::SESSION_TEST_VALUE
43 !== $this->container->sessionManager->getSessionParameter(static::SESSION_TEST_KEY) 44 !== $this->container->sessionManager->getSessionParameter(static::SESSION_TEST_KEY)
44 ) { 45 ) {
45 $this->container->sessionManager->setSessionParameter(static::SESSION_TEST_KEY, static::SESSION_TEST_VALUE); 46 $this->container->sessionManager->setSessionParameter(static::SESSION_TEST_KEY, static::SESSION_TEST_VALUE);
@@ -75,17 +76,18 @@ class InstallController extends ShaarliVisitorController
75 // This part makes sure sessions works correctly. 76 // This part makes sure sessions works correctly.
76 // (Because on some hosts, session.save_path may not be set correctly, 77 // (Because on some hosts, session.save_path may not be set correctly,
77 // or we may not have write access to it.) 78 // or we may not have write access to it.)
78 if (static::SESSION_TEST_VALUE 79 if (
80 static::SESSION_TEST_VALUE
79 !== $this->container->sessionManager->getSessionParameter(static::SESSION_TEST_KEY) 81 !== $this->container->sessionManager->getSessionParameter(static::SESSION_TEST_KEY)
80 ) { 82 ) {
81 // Step 2: Check if data in session is correct. 83 // Step 2: Check if data in session is correct.
82 $msg = t( 84 $msg = t(
83 '<pre>Sessions do not seem to work correctly on your server.<br>'. 85 '<pre>Sessions do not seem to work correctly on your server.<br>' .
84 'Make sure the variable "session.save_path" is set correctly in your PHP config, '. 86 'Make sure the variable "session.save_path" is set correctly in your PHP config, ' .
85 'and that you have write access to it.<br>'. 87 'and that you have write access to it.<br>' .
86 'It currently points to %s.<br>'. 88 'It currently points to %s.<br>' .
87 'On some browsers, accessing your server via a hostname like \'localhost\' '. 89 'On some browsers, accessing your server via a hostname like \'localhost\' ' .
88 'or any custom hostname without a dot causes cookie storage to fail. '. 90 'or any custom hostname without a dot causes cookie storage to fail. ' .
89 'We recommend accessing your server via it\'s IP address or Fully Qualified Domain Name.<br>' 91 'We recommend accessing your server via it\'s IP address or Fully Qualified Domain Name.<br>'
90 ); 92 );
91 $msg = sprintf($msg, $this->container->sessionManager->getSavePath()); 93 $msg = sprintf($msg, $this->container->sessionManager->getSavePath());
@@ -104,7 +106,8 @@ class InstallController extends ShaarliVisitorController
104 public function save(Request $request, Response $response): Response 106 public function save(Request $request, Response $response): Response
105 { 107 {
106 $timezone = 'UTC'; 108 $timezone = 'UTC';
107 if (!empty($request->getParam('continent')) 109 if (
110 !empty($request->getParam('continent'))
108 && !empty($request->getParam('city')) 111 && !empty($request->getParam('city'))
109 && isTimeZoneValid($request->getParam('continent'), $request->getParam('city')) 112 && isTimeZoneValid($request->getParam('continent'), $request->getParam('city'))
110 ) { 113 ) {
@@ -114,7 +117,7 @@ class InstallController extends ShaarliVisitorController
114 117
115 $login = $request->getParam('setlogin'); 118 $login = $request->getParam('setlogin');
116 $this->container->conf->set('credentials.login', $login); 119 $this->container->conf->set('credentials.login', $login);
117 $salt = sha1(uniqid('', true) .'_'. mt_rand()); 120 $salt = sha1(uniqid('', true) . '_' . mt_rand());
118 $this->container->conf->set('credentials.salt', $salt); 121 $this->container->conf->set('credentials.salt', $salt);
119 $this->container->conf->set('credentials.hash', sha1($request->getParam('setpassword') . $login . $salt)); 122 $this->container->conf->set('credentials.hash', sha1($request->getParam('setpassword') . $login . $salt));
120 123
@@ -123,7 +126,7 @@ class InstallController extends ShaarliVisitorController
123 } else { 126 } else {
124 $this->container->conf->set( 127 $this->container->conf->set(
125 'general.title', 128 'general.title',
126 'Shared bookmarks on '.escape(index_url($this->container->environment)) 129 'Shared bookmarks on ' . escape(index_url($this->container->environment))
127 ); 130 );
128 } 131 }
129 132
diff --git a/application/front/controller/visitor/LoginController.php b/application/front/controller/visitor/LoginController.php
index f5038fe3..4b881535 100644
--- a/application/front/controller/visitor/LoginController.php
+++ b/application/front/controller/visitor/LoginController.php
@@ -43,7 +43,7 @@ class LoginController extends ShaarliVisitorController
43 $this 43 $this
44 ->assignView('returnurl', escape($returnUrl)) 44 ->assignView('returnurl', escape($returnUrl))
45 ->assignView('remember_user_default', $this->container->conf->get('privacy.remember_user_default', true)) 45 ->assignView('remember_user_default', $this->container->conf->get('privacy.remember_user_default', true))
46 ->assignView('pagetitle', t('Login') .' - '. $this->container->conf->get('general.title', 'Shaarli')) 46 ->assignView('pagetitle', t('Login') . ' - ' . $this->container->conf->get('general.title', 'Shaarli'))
47 ; 47 ;
48 48
49 return $response->write($this->render(TemplatePage::LOGIN)); 49 return $response->write($this->render(TemplatePage::LOGIN));
@@ -64,7 +64,8 @@ class LoginController extends ShaarliVisitorController
64 return $this->redirect($response, '/'); 64 return $this->redirect($response, '/');
65 } 65 }
66 66
67 if (!$this->container->loginManager->checkCredentials( 67 if (
68 !$this->container->loginManager->checkCredentials(
68 client_ip_id($this->container->environment), 69 client_ip_id($this->container->environment),
69 $request->getParam('login'), 70 $request->getParam('login'),
70 $request->getParam('password') 71 $request->getParam('password')
@@ -101,7 +102,8 @@ class LoginController extends ShaarliVisitorController
101 */ 102 */
102 protected function checkLoginState(): bool 103 protected function checkLoginState(): bool
103 { 104 {
104 if ($this->container->loginManager->isLoggedIn() 105 if (
106 $this->container->loginManager->isLoggedIn()
105 || $this->container->conf->get('security.open_shaarli', false) 107 || $this->container->conf->get('security.open_shaarli', false)
106 ) { 108 ) {
107 throw new CantLoginException(); 109 throw new CantLoginException();
diff --git a/application/front/controller/visitor/PictureWallController.php b/application/front/controller/visitor/PictureWallController.php
index 3c57f8dd..23553ee6 100644
--- a/application/front/controller/visitor/PictureWallController.php
+++ b/application/front/controller/visitor/PictureWallController.php
@@ -26,7 +26,7 @@ class PictureWallController extends ShaarliVisitorController
26 26
27 $this->assignView( 27 $this->assignView(
28 'pagetitle', 28 'pagetitle',
29 t('Picture wall') .' - '. $this->container->conf->get('general.title', 'Shaarli') 29 t('Picture wall') . ' - ' . $this->container->conf->get('general.title', 'Shaarli')
30 ); 30 );
31 31
32 // Optionally filter the results: 32 // Optionally filter the results:
diff --git a/application/front/controller/visitor/ShaarliVisitorController.php b/application/front/controller/visitor/ShaarliVisitorController.php
index 54f9fe03..ae946c59 100644
--- a/application/front/controller/visitor/ShaarliVisitorController.php
+++ b/application/front/controller/visitor/ShaarliVisitorController.php
@@ -144,7 +144,8 @@ abstract class ShaarliVisitorController
144 if (null !== $referer) { 144 if (null !== $referer) {
145 $currentUrl = parse_url($referer); 145 $currentUrl = parse_url($referer);
146 // If the referer is not related to Shaarli instance, redirect to default 146 // If the referer is not related to Shaarli instance, redirect to default
147 if (isset($currentUrl['host']) 147 if (
148 isset($currentUrl['host'])
148 && strpos(index_url($this->container->environment), $currentUrl['host']) === false 149 && strpos(index_url($this->container->environment), $currentUrl['host']) === false
149 ) { 150 ) {
150 return $response->withRedirect($defaultPath); 151 return $response->withRedirect($defaultPath);
@@ -173,7 +174,7 @@ abstract class ShaarliVisitorController
173 } 174 }
174 } 175 }
175 176
176 $queryString = count($params) > 0 ? '?'. http_build_query($params) : ''; 177 $queryString = count($params) > 0 ? '?' . http_build_query($params) : '';
177 $anchor = $anchor ? '#' . $anchor : ''; 178 $anchor = $anchor ? '#' . $anchor : '';
178 179
179 return $response->withRedirect($path . $queryString . $anchor); 180 return $response->withRedirect($path . $queryString . $anchor);
diff --git a/application/front/controller/visitor/TagCloudController.php b/application/front/controller/visitor/TagCloudController.php
index 560cad08..46d62779 100644
--- a/application/front/controller/visitor/TagCloudController.php
+++ b/application/front/controller/visitor/TagCloudController.php
@@ -84,10 +84,10 @@ class TagCloudController extends ShaarliVisitorController
84 $this->executePageHooks('render_tag' . $type, $data, 'tag.' . $type); 84 $this->executePageHooks('render_tag' . $type, $data, 'tag.' . $type);
85 $this->assignAllView($data); 85 $this->assignAllView($data);
86 86
87 $searchTags = !empty($searchTags) ? trim(str_replace($tagsSeparator, ' ', $searchTags)) .' - ' : ''; 87 $searchTags = !empty($searchTags) ? trim(str_replace($tagsSeparator, ' ', $searchTags)) . ' - ' : '';
88 $this->assignView( 88 $this->assignView(
89 'pagetitle', 89 'pagetitle',
90 $searchTags . t('Tag '. $type) .' - '. $this->container->conf->get('general.title', 'Shaarli') 90 $searchTags . t('Tag ' . $type) . ' - ' . $this->container->conf->get('general.title', 'Shaarli')
91 ); 91 );
92 92
93 return $response->write($this->render('tag.' . $type)); 93 return $response->write($this->render('tag.' . $type));
diff --git a/application/front/controller/visitor/TagController.php b/application/front/controller/visitor/TagController.php
index 7a3377a7..3aa58542 100644
--- a/application/front/controller/visitor/TagController.php
+++ b/application/front/controller/visitor/TagController.php
@@ -27,7 +27,7 @@ class TagController extends ShaarliVisitorController
27 // In case browser does not send HTTP_REFERER, we search a single tag 27 // In case browser does not send HTTP_REFERER, we search a single tag
28 if (null === $referer) { 28 if (null === $referer) {
29 if (null !== $newTag) { 29 if (null !== $newTag) {
30 return $this->redirect($response, '/?searchtags='. urlencode($newTag)); 30 return $this->redirect($response, '/?searchtags=' . urlencode($newTag));
31 } 31 }
32 32
33 return $this->redirect($response, '/'); 33 return $this->redirect($response, '/');
@@ -37,7 +37,7 @@ class TagController extends ShaarliVisitorController
37 parse_str($currentUrl['query'] ?? '', $params); 37 parse_str($currentUrl['query'] ?? '', $params);
38 38
39 if (null === $newTag) { 39 if (null === $newTag) {
40 return $response->withRedirect(($currentUrl['path'] ?? './') .'?'. http_build_query($params)); 40 return $response->withRedirect(($currentUrl['path'] ?? './') . '?' . http_build_query($params));
41 } 41 }
42 42
43 // Prevent redirection loop 43 // Prevent redirection loop
@@ -68,7 +68,7 @@ class TagController extends ShaarliVisitorController
68 // 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)
69 unset($params['page']); 69 unset($params['page']);
70 70
71 return $response->withRedirect(($currentUrl['path'] ?? './') .'?'. http_build_query($params)); 71 return $response->withRedirect(($currentUrl['path'] ?? './') . '?' . http_build_query($params));
72 } 72 }
73 73
74 /** 74 /**
@@ -90,7 +90,7 @@ class TagController extends ShaarliVisitorController
90 parse_str($currentUrl['query'] ?? '', $params); 90 parse_str($currentUrl['query'] ?? '', $params);
91 91
92 if (null === $tagToRemove) { 92 if (null === $tagToRemove) {
93 return $response->withRedirect(($currentUrl['path'] ?? './') .'?'. http_build_query($params)); 93 return $response->withRedirect(($currentUrl['path'] ?? './') . '?' . http_build_query($params));
94 } 94 }
95 95
96 // Prevent redirection loop 96 // Prevent redirection loop
diff --git a/application/helper/ApplicationUtils.php b/application/helper/ApplicationUtils.php
index 4b34e114..212dd8e2 100644
--- a/application/helper/ApplicationUtils.php
+++ b/application/helper/ApplicationUtils.php
@@ -1,4 +1,5 @@
1<?php 1<?php
2
2namespace Shaarli\Helper; 3namespace Shaarli\Helper;
3 4
4use Exception; 5use Exception;
@@ -16,7 +17,7 @@ class ApplicationUtils
16 17
17 public static $GITHUB_URL = 'https://github.com/shaarli/Shaarli'; 18 public static $GITHUB_URL = 'https://github.com/shaarli/Shaarli';
18 public static $GIT_RAW_URL = 'https://raw.githubusercontent.com/shaarli/Shaarli'; 19 public static $GIT_RAW_URL = 'https://raw.githubusercontent.com/shaarli/Shaarli';
19 public static $GIT_BRANCHES = array('latest', 'stable'); 20 public static $GIT_BRANCHES = ['latest', 'stable'];
20 private static $VERSION_START_TAG = '<?php /* '; 21 private static $VERSION_START_TAG = '<?php /* ';
21 private static $VERSION_END_TAG = ' */ ?>'; 22 private static $VERSION_END_TAG = ' */ ?>';
22 23
@@ -64,8 +65,8 @@ class ApplicationUtils
64 } 65 }
65 66
66 return str_replace( 67 return str_replace(
67 array(self::$VERSION_START_TAG, self::$VERSION_END_TAG, PHP_EOL), 68 [self::$VERSION_START_TAG, self::$VERSION_END_TAG, PHP_EOL],
68 array('', '', ''), 69 ['', '', ''],
69 $data 70 $data
70 ); 71 );
71 } 72 }
@@ -184,13 +185,15 @@ class ApplicationUtils
184 $rainTplDir = rtrim($conf->get('resource.raintpl_tpl'), '/'); 185 $rainTplDir = rtrim($conf->get('resource.raintpl_tpl'), '/');
185 186
186 // Check script and template directories are readable 187 // Check script and template directories are readable
187 foreach ([ 188 foreach (
188 'application', 189 [
189 'inc', 190 'application',
190 'plugins', 191 'inc',
191 $rainTplDir, 192 'plugins',
192 $rainTplDir . '/' . $conf->get('resource.theme'), 193 $rainTplDir,
193 ] as $path) { 194 $rainTplDir . '/' . $conf->get('resource.theme'),
195 ] as $path
196 ) {
194 if (!is_readable(realpath($path))) { 197 if (!is_readable(realpath($path))) {
195 $errors[] = '"' . $path . '" ' . t('directory is not readable'); 198 $errors[] = '"' . $path . '" ' . t('directory is not readable');
196 } 199 }
@@ -203,10 +206,10 @@ class ApplicationUtils
203 ]; 206 ];
204 } else { 207 } else {
205 $folders = [ 208 $folders = [
206 $conf->get('resource.thumbnails_cache'), 209 $conf->get('resource.thumbnails_cache'),
207 $conf->get('resource.data_dir'), 210 $conf->get('resource.data_dir'),
208 $conf->get('resource.page_cache'), 211 $conf->get('resource.page_cache'),
209 $conf->get('resource.raintpl_tmp'), 212 $conf->get('resource.raintpl_tmp'),
210 ]; 213 ];
211 } 214 }
212 215
@@ -224,13 +227,15 @@ class ApplicationUtils
224 } 227 }
225 228
226 // Check configuration files are readable and writable 229 // Check configuration files are readable and writable
227 foreach (array( 230 foreach (
228 $conf->getConfigFileExt(), 231 [
229 $conf->get('resource.datastore'), 232 $conf->getConfigFileExt(),
230 $conf->get('resource.ban_file'), 233 $conf->get('resource.datastore'),
231 $conf->get('resource.log'), 234 $conf->get('resource.ban_file'),
232 $conf->get('resource.update_check'), 235 $conf->get('resource.log'),
233 ) as $path) { 236 $conf->get('resource.update_check'),
237 ] as $path
238 ) {
234 if (!is_file(realpath($path))) { 239 if (!is_file(realpath($path))) {
235 # the file may not exist yet 240 # the file may not exist yet
236 continue; 241 continue;
diff --git a/application/helper/FileUtils.php b/application/helper/FileUtils.php
index 2eac0793..e8a2168c 100644
--- a/application/helper/FileUtils.php
+++ b/application/helper/FileUtils.php
@@ -105,7 +105,7 @@ class FileUtils
105 } 105 }
106 106
107 foreach (new \DirectoryIterator($path) as $file) { 107 foreach (new \DirectoryIterator($path) as $file) {
108 if($file->isDot()) { 108 if ($file->isDot()) {
109 continue; 109 continue;
110 } 110 }
111 111
@@ -116,7 +116,7 @@ class FileUtils
116 116
117 if ($file->isFile()) { 117 if ($file->isFile()) {
118 unlink($file->getPathname()); 118 unlink($file->getPathname());
119 } elseif($file->isDir()) { 119 } elseif ($file->isDir()) {
120 $skipped = static::clearFolder($file->getRealPath(), true, $exclude) || $skipped; 120 $skipped = static::clearFolder($file->getRealPath(), true, $exclude) || $skipped;
121 } 121 }
122 } 122 }
diff --git a/application/http/HttpUtils.php b/application/http/HttpUtils.php
index ed1002b0..4bde1d5b 100644
--- a/application/http/HttpUtils.php
+++ b/application/http/HttpUtils.php
@@ -48,7 +48,7 @@ function get_http_response(
48 $cleanUrl = $urlObj->idnToAscii(); 48 $cleanUrl = $urlObj->idnToAscii();
49 49
50 if (!filter_var($cleanUrl, FILTER_VALIDATE_URL) || !$urlObj->isHttp()) { 50 if (!filter_var($cleanUrl, FILTER_VALIDATE_URL) || !$urlObj->isHttp()) {
51 return array(array(0 => 'Invalid HTTP UrlUtils'), false); 51 return [[0 => 'Invalid HTTP UrlUtils'], false];
52 } 52 }
53 53
54 $userAgent = 54 $userAgent =
@@ -71,7 +71,7 @@ function get_http_response(
71 71
72 $ch = curl_init($cleanUrl); 72 $ch = curl_init($cleanUrl);
73 if ($ch === false) { 73 if ($ch === false) {
74 return array(array(0 => 'curl_init() error'), false); 74 return [[0 => 'curl_init() error'], false];
75 } 75 }
76 76
77 // General cURL settings 77 // General cURL settings
@@ -82,7 +82,7 @@ function get_http_response(
82 curl_setopt( 82 curl_setopt(
83 $ch, 83 $ch,
84 CURLOPT_HTTPHEADER, 84 CURLOPT_HTTPHEADER,
85 array('Accept-Language: ' . $acceptLanguage) 85 ['Accept-Language: ' . $acceptLanguage]
86 ); 86 );
87 curl_setopt($ch, CURLOPT_MAXREDIRS, $maxRedirs); 87 curl_setopt($ch, CURLOPT_MAXREDIRS, $maxRedirs);
88 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 88 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
@@ -90,7 +90,7 @@ function get_http_response(
90 curl_setopt($ch, CURLOPT_USERAGENT, $userAgent); 90 curl_setopt($ch, CURLOPT_USERAGENT, $userAgent);
91 91
92 // Max download size management 92 // Max download size management
93 curl_setopt($ch, CURLOPT_BUFFERSIZE, 1024*16); 93 curl_setopt($ch, CURLOPT_BUFFERSIZE, 1024 * 16);
94 curl_setopt($ch, CURLOPT_NOPROGRESS, false); 94 curl_setopt($ch, CURLOPT_NOPROGRESS, false);
95 if (is_callable($curlHeaderFunction)) { 95 if (is_callable($curlHeaderFunction)) {
96 curl_setopt($ch, CURLOPT_HEADERFUNCTION, $curlHeaderFunction); 96 curl_setopt($ch, CURLOPT_HEADERFUNCTION, $curlHeaderFunction);
@@ -122,9 +122,9 @@ function get_http_response(
122 * Removing this would require updating 122 * Removing this would require updating
123 * GetHttpUrlTest::testGetInvalidRemoteUrl() 123 * GetHttpUrlTest::testGetInvalidRemoteUrl()
124 */ 124 */
125 return array(false, false); 125 return [false, false];
126 } 126 }
127 return array(array(0 => 'curl_exec() error: ' . $errorStr), false); 127 return [[0 => 'curl_exec() error: ' . $errorStr], false];
128 } 128 }
129 129
130 // Formatting output like the fallback method 130 // Formatting output like the fallback method
@@ -135,7 +135,7 @@ function get_http_response(
135 $rawHeadersLastRedir = end($rawHeadersArrayRedirs); 135 $rawHeadersLastRedir = end($rawHeadersArrayRedirs);
136 136
137 $content = substr($response, $headSize); 137 $content = substr($response, $headSize);
138 $headers = array(); 138 $headers = [];
139 foreach (preg_split('~[\r\n]+~', $rawHeadersLastRedir) as $line) { 139 foreach (preg_split('~[\r\n]+~', $rawHeadersLastRedir) as $line) {
140 if (empty($line) || ctype_space($line)) { 140 if (empty($line) || ctype_space($line)) {
141 continue; 141 continue;
@@ -146,7 +146,7 @@ function get_http_response(
146 $value = $splitLine[1]; 146 $value = $splitLine[1];
147 if (array_key_exists($key, $headers)) { 147 if (array_key_exists($key, $headers)) {
148 if (!is_array($headers[$key])) { 148 if (!is_array($headers[$key])) {
149 $headers[$key] = array(0 => $headers[$key]); 149 $headers[$key] = [0 => $headers[$key]];
150 } 150 }
151 $headers[$key][] = $value; 151 $headers[$key][] = $value;
152 } else { 152 } else {
@@ -157,7 +157,7 @@ function get_http_response(
157 } 157 }
158 } 158 }
159 159
160 return array($headers, $content); 160 return [$headers, $content];
161} 161}
162 162
163/** 163/**
@@ -188,15 +188,15 @@ function get_http_response_fallback(
188 $acceptLanguage, 188 $acceptLanguage,
189 $maxRedr 189 $maxRedr
190) { 190) {
191 $options = array( 191 $options = [
192 'http' => array( 192 'http' => [
193 'method' => 'GET', 193 'method' => 'GET',
194 'timeout' => $timeout, 194 'timeout' => $timeout,
195 'user_agent' => $userAgent, 195 'user_agent' => $userAgent,
196 'header' => "Accept: */*\r\n" 196 'header' => "Accept: */*\r\n"
197 . 'Accept-Language: ' . $acceptLanguage 197 . 'Accept-Language: ' . $acceptLanguage
198 ) 198 ]
199 ); 199 ];
200 200
201 stream_context_set_default($options); 201 stream_context_set_default($options);
202 list($headers, $finalUrl) = get_redirected_headers($cleanUrl, $maxRedr); 202 list($headers, $finalUrl) = get_redirected_headers($cleanUrl, $maxRedr);
@@ -207,7 +207,7 @@ function get_http_response_fallback(
207 } 207 }
208 208
209 if (! $headers) { 209 if (! $headers) {
210 return array($headers, false); 210 return [$headers, false];
211 } 211 }
212 212
213 try { 213 try {
@@ -215,10 +215,10 @@ function get_http_response_fallback(
215 $context = stream_context_create($options); 215 $context = stream_context_create($options);
216 $content = file_get_contents($finalUrl, false, $context, -1, $maxBytes); 216 $content = file_get_contents($finalUrl, false, $context, -1, $maxBytes);
217 } catch (Exception $exc) { 217 } catch (Exception $exc) {
218 return array(array(0 => 'HTTP Error'), $exc->getMessage()); 218 return [[0 => 'HTTP Error'], $exc->getMessage()];
219 } 219 }
220 220
221 return array($headers, $content); 221 return [$headers, $content];
222} 222}
223 223
224/** 224/**
@@ -237,10 +237,12 @@ function get_redirected_headers($url, $redirectionLimit = 3)
237 } 237 }
238 238
239 // Headers found, redirection found, and limit not reached. 239 // Headers found, redirection found, and limit not reached.
240 if ($redirectionLimit-- > 0 240 if (
241 $redirectionLimit-- > 0
241 && !empty($headers) 242 && !empty($headers)
242 && (strpos($headers[0], '301') !== false || strpos($headers[0], '302') !== false) 243 && (strpos($headers[0], '301') !== false || strpos($headers[0], '302') !== false)
243 && !empty($headers['Location'])) { 244 && !empty($headers['Location'])
245 ) {
244 $redirection = is_array($headers['Location']) ? end($headers['Location']) : $headers['Location']; 246 $redirection = is_array($headers['Location']) ? end($headers['Location']) : $headers['Location'];
245 if ($redirection != $url) { 247 if ($redirection != $url) {
246 $redirection = getAbsoluteUrl($url, $redirection); 248 $redirection = getAbsoluteUrl($url, $redirection);
@@ -248,7 +250,7 @@ function get_redirected_headers($url, $redirectionLimit = 3)
248 } 250 }
249 } 251 }
250 252
251 return array($headers, $url); 253 return [$headers, $url];
252} 254}
253 255
254/** 256/**
@@ -270,7 +272,7 @@ function getAbsoluteUrl($originalUrl, $newUrl)
270 } 272 }
271 273
272 $parts = parse_url($originalUrl); 274 $parts = parse_url($originalUrl);
273 $final = $parts['scheme'] .'://'. $parts['host']; 275 $final = $parts['scheme'] . '://' . $parts['host'];
274 $final .= (!empty($parts['port'])) ? $parts['port'] : ''; 276 $final .= (!empty($parts['port'])) ? $parts['port'] : '';
275 $final .= '/'; 277 $final .= '/';
276 if ($newUrl[0] != '/') { 278 if ($newUrl[0] != '/') {
@@ -323,7 +325,8 @@ function server_url($server)
323 $scheme = 'https'; 325 $scheme = 'https';
324 } 326 }
325 327
326 if (($scheme == 'http' && $port != '80') 328 if (
329 ($scheme == 'http' && $port != '80')
327 || ($scheme == 'https' && $port != '443') 330 || ($scheme == 'https' && $port != '443')
328 ) { 331 ) {
329 $port = ':' . $port; 332 $port = ':' . $port;
@@ -344,22 +347,26 @@ function server_url($server)
344 $host = $server['SERVER_NAME']; 347 $host = $server['SERVER_NAME'];
345 } 348 }
346 349
347 return $scheme.'://'.$host.$port; 350 return $scheme . '://' . $host . $port;
348 } 351 }
349 352
350 // SSL detection 353 // SSL detection
351 if ((! empty($server['HTTPS']) && strtolower($server['HTTPS']) == 'on') 354 if (
352 || (isset($server['SERVER_PORT']) && $server['SERVER_PORT'] == '443')) { 355 (! empty($server['HTTPS']) && strtolower($server['HTTPS']) == 'on')
356 || (isset($server['SERVER_PORT']) && $server['SERVER_PORT'] == '443')
357 ) {
353 $scheme = 'https'; 358 $scheme = 'https';
354 } 359 }
355 360
356 // Do not append standard port values 361 // Do not append standard port values
357 if (($scheme == 'http' && $server['SERVER_PORT'] != '80') 362 if (
358 || ($scheme == 'https' && $server['SERVER_PORT'] != '443')) { 363 ($scheme == 'http' && $server['SERVER_PORT'] != '80')
359 $port = ':'.$server['SERVER_PORT']; 364 || ($scheme == 'https' && $server['SERVER_PORT'] != '443')
365 ) {
366 $port = ':' . $server['SERVER_PORT'];
360 } 367 }
361 368
362 return $scheme.'://'.$server['SERVER_NAME'].$port; 369 return $scheme . '://' . $server['SERVER_NAME'] . $port;
363} 370}
364 371
365/** 372/**
@@ -567,7 +574,10 @@ function get_curl_download_callback(
567 * 574 *
568 * @return int|bool length of $data or false if we need to stop the download 575 * @return int|bool length of $data or false if we need to stop the download
569 */ 576 */
570 return function ($ch, $data) use ( 577 return function (
578 $ch,
579 $data
580 ) use (
571 $retrieveDescription, 581 $retrieveDescription,
572 $tagsSeparator, 582 $tagsSeparator,
573 &$charset, 583 &$charset,
@@ -601,7 +611,7 @@ function get_curl_download_callback(
601 $foundChunk = $currentChunk; 611 $foundChunk = $currentChunk;
602 // Keywords use the format tag1, tag2 multiple words, tag 612 // Keywords use the format tag1, tag2 multiple words, tag
603 // So we split the result with `,`, then if a tag contains the separator we replace it by `-`. 613 // So we split the result with `,`, then if a tag contains the separator we replace it by `-`.
604 $keywords = tags_array2str(array_map(function(string $keyword) use ($tagsSeparator): string { 614 $keywords = tags_array2str(array_map(function (string $keyword) use ($tagsSeparator): string {
605 return tags_array2str(tags_str2array($keyword, $tagsSeparator), '-'); 615 return tags_array2str(tags_str2array($keyword, $tagsSeparator), '-');
606 }, tags_str2array($keywords, ',')), $tagsSeparator); 616 }, tags_str2array($keywords, ',')), $tagsSeparator);
607 } 617 }
@@ -611,7 +621,8 @@ function get_curl_download_callback(
611 // If we already found either the title, description or keywords, 621 // If we already found either the title, description or keywords,
612 // it's highly unlikely that we'll found the other metas further than 622 // it's highly unlikely that we'll found the other metas further than
613 // in the same chunk of data or the next one. So we also stop the download after that. 623 // in the same chunk of data or the next one. So we also stop the download after that.
614 if ((!empty($responseCode) && !empty($contentType) && !empty($charset)) && $foundChunk !== null 624 if (
625 (!empty($responseCode) && !empty($contentType) && !empty($charset)) && $foundChunk !== null
615 && (! $retrieveDescription 626 && (! $retrieveDescription
616 || $foundChunk < $currentChunk 627 || $foundChunk < $currentChunk
617 || (!empty($title) && !empty($description) && !empty($keywords)) 628 || (!empty($title) && !empty($description) && !empty($keywords))
diff --git a/application/http/Url.php b/application/http/Url.php
index 90444a2f..fe87088f 100644
--- a/application/http/Url.php
+++ b/application/http/Url.php
@@ -17,7 +17,7 @@ namespace Shaarli\Http;
17 */ 17 */
18class Url 18class Url
19{ 19{
20 private static $annoyingQueryParams = array( 20 private static $annoyingQueryParams = [
21 // Facebook 21 // Facebook
22 'action_object_map=', 22 'action_object_map=',
23 'action_ref_map=', 23 'action_ref_map=',
@@ -37,15 +37,15 @@ class Url
37 37
38 // Other 38 // Other
39 'campaign_' 39 'campaign_'
40 ); 40 ];
41 41
42 private static $annoyingFragments = array( 42 private static $annoyingFragments = [
43 // ATInternet 43 // ATInternet
44 'xtor=RSS-', 44 'xtor=RSS-',
45 45
46 // Misc. 46 // Misc.
47 'tk.rss_all' 47 'tk.rss_all'
48 ); 48 ];
49 49
50 /* 50 /*
51 * URL parts represented as an array 51 * URL parts represented as an array
@@ -120,7 +120,7 @@ class Url
120 foreach (self::$annoyingQueryParams as $annoying) { 120 foreach (self::$annoyingQueryParams as $annoying) {
121 foreach ($queryParams as $param) { 121 foreach ($queryParams as $param) {
122 if (startsWith($param, $annoying)) { 122 if (startsWith($param, $annoying)) {
123 $queryParams = array_diff($queryParams, array($param)); 123 $queryParams = array_diff($queryParams, [$param]);
124 continue; 124 continue;
125 } 125 }
126 } 126 }
diff --git a/application/http/UrlUtils.php b/application/http/UrlUtils.php
index e8d1a283..de5b7db1 100644
--- a/application/http/UrlUtils.php
+++ b/application/http/UrlUtils.php
@@ -1,4 +1,5 @@
1<?php 1<?php
2
2/** 3/**
3 * Converts an array-represented URL to a string 4 * Converts an array-represented URL to a string
4 * 5 *
@@ -12,15 +13,15 @@
12 */ 13 */
13function unparse_url($parsedUrl) 14function unparse_url($parsedUrl)
14{ 15{
15 $scheme = isset($parsedUrl['scheme']) ? $parsedUrl['scheme'].'://' : ''; 16 $scheme = isset($parsedUrl['scheme']) ? $parsedUrl['scheme'] . '://' : '';
16 $host = isset($parsedUrl['host']) ? $parsedUrl['host'] : ''; 17 $host = isset($parsedUrl['host']) ? $parsedUrl['host'] : '';
17 $port = isset($parsedUrl['port']) ? ':'.$parsedUrl['port'] : ''; 18 $port = isset($parsedUrl['port']) ? ':' . $parsedUrl['port'] : '';
18 $user = isset($parsedUrl['user']) ? $parsedUrl['user'] : ''; 19 $user = isset($parsedUrl['user']) ? $parsedUrl['user'] : '';
19 $pass = isset($parsedUrl['pass']) ? ':'.$parsedUrl['pass'] : ''; 20 $pass = isset($parsedUrl['pass']) ? ':' . $parsedUrl['pass'] : '';
20 $pass = ($user || $pass) ? "$pass@" : ''; 21 $pass = ($user || $pass) ? "$pass@" : '';
21 $path = isset($parsedUrl['path']) ? $parsedUrl['path'] : ''; 22 $path = isset($parsedUrl['path']) ? $parsedUrl['path'] : '';
22 $query = isset($parsedUrl['query']) ? '?'.$parsedUrl['query'] : ''; 23 $query = isset($parsedUrl['query']) ? '?' . $parsedUrl['query'] : '';
23 $fragment = isset($parsedUrl['fragment']) ? '#'.$parsedUrl['fragment'] : ''; 24 $fragment = isset($parsedUrl['fragment']) ? '#' . $parsedUrl['fragment'] : '';
24 25
25 return "$scheme$user$pass$host$port$path$query$fragment"; 26 return "$scheme$user$pass$host$port$path$query$fragment";
26} 27}
diff --git a/application/legacy/LegacyController.php b/application/legacy/LegacyController.php
index 826604e7..1fed418b 100644
--- a/application/legacy/LegacyController.php
+++ b/application/legacy/LegacyController.php
@@ -51,7 +51,7 @@ class LegacyController extends ShaarliVisitorController
51 51
52 if (!$this->container->loginManager->isLoggedIn()) { 52 if (!$this->container->loginManager->isLoggedIn()) {
53 $parameters = $buildParameters($request->getQueryParams(), true); 53 $parameters = $buildParameters($request->getQueryParams(), true);
54 return $this->redirect($response, '/login?returnurl='. $this->getBasePath() . $route . $parameters); 54 return $this->redirect($response, '/login?returnurl=' . $this->getBasePath() . $route . $parameters);
55 } 55 }
56 56
57 $parameters = $buildParameters($request->getQueryParams(), false); 57 $parameters = $buildParameters($request->getQueryParams(), false);
diff --git a/application/legacy/LegacyLinkDB.php b/application/legacy/LegacyLinkDB.php
index 5c02a21b..d3beafe0 100644
--- a/application/legacy/LegacyLinkDB.php
+++ b/application/legacy/LegacyLinkDB.php
@@ -62,7 +62,7 @@ class LegacyLinkDB implements Iterator, Countable, ArrayAccess
62 private $datastore; 62 private $datastore;
63 63
64 // Link date storage format 64 // Link date storage format
65 const LINK_DATE_FORMAT = 'Ymd_His'; 65 public const LINK_DATE_FORMAT = 'Ymd_His';
66 66
67 // List of bookmarks (associative array) 67 // List of bookmarks (associative array)
68 // - key: link date (e.g. "20110823_124546"), 68 // - key: link date (e.g. "20110823_124546"),
@@ -240,8 +240,8 @@ class LegacyLinkDB implements Iterator, Countable, ArrayAccess
240 } 240 }
241 241
242 // Create a dummy database for example 242 // Create a dummy database for example
243 $this->links = array(); 243 $this->links = [];
244 $link = array( 244 $link = [
245 'id' => 1, 245 'id' => 1,
246 'title' => t('The personal, minimalist, super-fast, database free, bookmarking service'), 246 'title' => t('The personal, minimalist, super-fast, database free, bookmarking service'),
247 'url' => 'https://shaarli.readthedocs.io', 247 'url' => 'https://shaarli.readthedocs.io',
@@ -257,11 +257,11 @@ You use the community supported version of the original Shaarli project, by Seba
257 'created' => new DateTime(), 257 'created' => new DateTime(),
258 'tags' => 'opensource software', 258 'tags' => 'opensource software',
259 'sticky' => false, 259 'sticky' => false,
260 ); 260 ];
261 $link['shorturl'] = link_small_hash($link['created'], $link['id']); 261 $link['shorturl'] = link_small_hash($link['created'], $link['id']);
262 $this->links[1] = $link; 262 $this->links[1] = $link;
263 263
264 $link = array( 264 $link = [
265 'id' => 0, 265 'id' => 0,
266 'title' => t('My secret stuff... - Pastebin.com'), 266 'title' => t('My secret stuff... - Pastebin.com'),
267 'url' => 'http://sebsauvage.net/paste/?8434b27936c09649#bR7XsXhoTiLcqCpQbmOpBi3rq2zzQUC5hBI7ZT1O3x8=', 267 'url' => 'http://sebsauvage.net/paste/?8434b27936c09649#bR7XsXhoTiLcqCpQbmOpBi3rq2zzQUC5hBI7ZT1O3x8=',
@@ -270,7 +270,7 @@ You use the community supported version of the original Shaarli project, by Seba
270 'created' => new DateTime('1 minute ago'), 270 'created' => new DateTime('1 minute ago'),
271 'tags' => 'secretstuff', 271 'tags' => 'secretstuff',
272 'sticky' => false, 272 'sticky' => false,
273 ); 273 ];
274 $link['shorturl'] = link_small_hash($link['created'], $link['id']); 274 $link['shorturl'] = link_small_hash($link['created'], $link['id']);
275 $this->links[0] = $link; 275 $this->links[0] = $link;
276 276
@@ -285,7 +285,7 @@ You use the community supported version of the original Shaarli project, by Seba
285 { 285 {
286 // Public bookmarks are hidden and user not logged in => nothing to show 286 // Public bookmarks are hidden and user not logged in => nothing to show
287 if ($this->hidePublicLinks && !$this->loggedIn) { 287 if ($this->hidePublicLinks && !$this->loggedIn) {
288 $this->links = array(); 288 $this->links = [];
289 return; 289 return;
290 } 290 }
291 291
@@ -293,7 +293,7 @@ You use the community supported version of the original Shaarli project, by Seba
293 $this->ids = []; 293 $this->ids = [];
294 $this->links = FileUtils::readFlatDB($this->datastore, []); 294 $this->links = FileUtils::readFlatDB($this->datastore, []);
295 295
296 $toremove = array(); 296 $toremove = [];
297 foreach ($this->links as $key => &$link) { 297 foreach ($this->links as $key => &$link) {
298 if (!$this->loggedIn && $link['private'] != 0) { 298 if (!$this->loggedIn && $link['private'] != 0) {
299 // Transition for not upgraded databases. 299 // Transition for not upgraded databases.
@@ -414,7 +414,7 @@ You use the community supported version of the original Shaarli project, by Seba
414 * @return array filtered bookmarks, all bookmarks if no suitable filter was provided. 414 * @return array filtered bookmarks, all bookmarks if no suitable filter was provided.
415 */ 415 */
416 public function filterSearch( 416 public function filterSearch(
417 $filterRequest = array(), 417 $filterRequest = [],
418 $casesensitive = false, 418 $casesensitive = false,
419 $visibility = 'all', 419 $visibility = 'all',
420 $untaggedonly = false 420 $untaggedonly = false
@@ -512,7 +512,7 @@ You use the community supported version of the original Shaarli project, by Seba
512 */ 512 */
513 public function days() 513 public function days()
514 { 514 {
515 $linkDays = array(); 515 $linkDays = [];
516 foreach ($this->links as $link) { 516 foreach ($this->links as $link) {
517 $linkDays[$link['created']->format('Ymd')] = 0; 517 $linkDays[$link['created']->format('Ymd')] = 0;
518 } 518 }
diff --git a/application/legacy/LegacyLinkFilter.php b/application/legacy/LegacyLinkFilter.php
index 7cf93d60..e6d186c4 100644
--- a/application/legacy/LegacyLinkFilter.php
+++ b/application/legacy/LegacyLinkFilter.php
@@ -120,7 +120,7 @@ class LegacyLinkFilter
120 return $this->links; 120 return $this->links;
121 } 121 }
122 122
123 $out = array(); 123 $out = [];
124 foreach ($this->links as $key => $value) { 124 foreach ($this->links as $key => $value) {
125 if ($value['private'] && $visibility === 'private') { 125 if ($value['private'] && $visibility === 'private') {
126 $out[$key] = $value; 126 $out[$key] = $value;
@@ -143,7 +143,7 @@ class LegacyLinkFilter
143 */ 143 */
144 private function filterSmallHash($smallHash) 144 private function filterSmallHash($smallHash)
145 { 145 {
146 $filtered = array(); 146 $filtered = [];
147 foreach ($this->links as $key => $l) { 147 foreach ($this->links as $key => $l) {
148 if ($smallHash == $l['shorturl']) { 148 if ($smallHash == $l['shorturl']) {
149 // Yes, this is ugly and slow 149 // Yes, this is ugly and slow
@@ -186,7 +186,7 @@ class LegacyLinkFilter
186 return $this->noFilter($visibility); 186 return $this->noFilter($visibility);
187 } 187 }
188 188
189 $filtered = array(); 189 $filtered = [];
190 $search = mb_convert_case(html_entity_decode($searchterms), MB_CASE_LOWER, 'UTF-8'); 190 $search = mb_convert_case(html_entity_decode($searchterms), MB_CASE_LOWER, 'UTF-8');
191 $exactRegex = '/"([^"]+)"/'; 191 $exactRegex = '/"([^"]+)"/';
192 // Retrieve exact search terms. 192 // Retrieve exact search terms.
@@ -198,8 +198,8 @@ class LegacyLinkFilter
198 $explodedSearchAnd = array_values(array_filter($explodedSearchAnd)); 198 $explodedSearchAnd = array_values(array_filter($explodedSearchAnd));
199 199
200 // Filter excluding terms and update andSearch. 200 // Filter excluding terms and update andSearch.
201 $excludeSearch = array(); 201 $excludeSearch = [];
202 $andSearch = array(); 202 $andSearch = [];
203 foreach ($explodedSearchAnd as $needle) { 203 foreach ($explodedSearchAnd as $needle) {
204 if ($needle[0] == '-' && strlen($needle) > 1) { 204 if ($needle[0] == '-' && strlen($needle) > 1) {
205 $excludeSearch[] = substr($needle, 1); 205 $excludeSearch[] = substr($needle, 1);
@@ -208,7 +208,7 @@ class LegacyLinkFilter
208 } 208 }
209 } 209 }
210 210
211 $keys = array('title', 'description', 'url', 'tags'); 211 $keys = ['title', 'description', 'url', 'tags'];
212 212
213 // Iterate over every stored link. 213 // Iterate over every stored link.
214 foreach ($this->links as $id => $link) { 214 foreach ($this->links as $id => $link) {
@@ -336,7 +336,7 @@ class LegacyLinkFilter
336 } 336 }
337 337
338 // create resulting array 338 // create resulting array
339 $filtered = array(); 339 $filtered = [];
340 340
341 // iterate over each link 341 // iterate over each link
342 foreach ($this->links as $key => $link) { 342 foreach ($this->links as $key => $link) {
@@ -352,7 +352,7 @@ class LegacyLinkFilter
352 $search = $link['tags']; // build search string, start with tags of current link 352 $search = $link['tags']; // build search string, start with tags of current link
353 if (strlen(trim($link['description'])) && strpos($link['description'], '#') !== false) { 353 if (strlen(trim($link['description'])) && strpos($link['description'], '#') !== false) {
354 // description given and at least one possible tag found 354 // description given and at least one possible tag found
355 $descTags = array(); 355 $descTags = [];
356 // find all tags in the form of #tag in the description 356 // find all tags in the form of #tag in the description
357 preg_match_all( 357 preg_match_all(
358 '/(?<![' . self::$HASHTAG_CHARS . '])#([' . self::$HASHTAG_CHARS . ']+?)\b/sm', 358 '/(?<![' . self::$HASHTAG_CHARS . '])#([' . self::$HASHTAG_CHARS . ']+?)\b/sm',
@@ -419,7 +419,7 @@ class LegacyLinkFilter
419 throw new Exception('Invalid date format'); 419 throw new Exception('Invalid date format');
420 } 420 }
421 421
422 $filtered = array(); 422 $filtered = [];
423 foreach ($this->links as $key => $l) { 423 foreach ($this->links as $key => $l) {
424 if ($l['created']->format('Ymd') == $day) { 424 if ($l['created']->format('Ymd') == $day) {
425 $filtered[$key] = $l; 425 $filtered[$key] = $l;
diff --git a/application/legacy/LegacyUpdater.php b/application/legacy/LegacyUpdater.php
index ed949b1e..9bda54b8 100644
--- a/application/legacy/LegacyUpdater.php
+++ b/application/legacy/LegacyUpdater.php
@@ -93,7 +93,7 @@ class LegacyUpdater
93 */ 93 */
94 public function update() 94 public function update()
95 { 95 {
96 $updatesRan = array(); 96 $updatesRan = [];
97 97
98 // If the user isn't logged in, exit without updating. 98 // If the user isn't logged in, exit without updating.
99 if ($this->isLoggedIn !== true) { 99 if ($this->isLoggedIn !== true) {
@@ -106,7 +106,8 @@ class LegacyUpdater
106 106
107 foreach ($this->methods as $method) { 107 foreach ($this->methods as $method) {
108 // Not an update method or already done, pass. 108 // Not an update method or already done, pass.
109 if (!startsWith($method->getName(), 'updateMethod') 109 if (
110 !startsWith($method->getName(), 'updateMethod')
110 || in_array($method->getName(), $this->doneUpdates) 111 || in_array($method->getName(), $this->doneUpdates)
111 ) { 112 ) {
112 continue; 113 continue;
@@ -189,7 +190,7 @@ class LegacyUpdater
189 } 190 }
190 191
191 // Set sub config keys (config and plugins) 192 // Set sub config keys (config and plugins)
192 $subConfig = array('config', 'plugins'); 193 $subConfig = ['config', 'plugins'];
193 foreach ($subConfig as $sub) { 194 foreach ($subConfig as $sub) {
194 foreach ($oldConfig[$sub] as $key => $value) { 195 foreach ($oldConfig[$sub] as $key => $value) {
195 if (isset($legacyMap[$sub . '.' . $key])) { 196 if (isset($legacyMap[$sub . '.' . $key])) {
@@ -259,7 +260,7 @@ class LegacyUpdater
259 $save = $this->conf->get('resource.data_dir') . '/datastore.' . date('YmdHis') . '.php'; 260 $save = $this->conf->get('resource.data_dir') . '/datastore.' . date('YmdHis') . '.php';
260 copy($this->conf->get('resource.datastore'), $save); 261 copy($this->conf->get('resource.datastore'), $save);
261 262
262 $links = array(); 263 $links = [];
263 foreach ($this->linkDB as $offset => $value) { 264 foreach ($this->linkDB as $offset => $value) {
264 $links[] = $value; 265 $links[] = $value;
265 unset($this->linkDB[$offset]); 266 unset($this->linkDB[$offset]);
@@ -498,7 +499,8 @@ class LegacyUpdater
498 */ 499 */
499 public function updateMethodDownloadSizeAndTimeoutConf() 500 public function updateMethodDownloadSizeAndTimeoutConf()
500 { 501 {
501 if ($this->conf->exists('general.download_max_size') 502 if (
503 $this->conf->exists('general.download_max_size')
502 && $this->conf->exists('general.download_timeout') 504 && $this->conf->exists('general.download_timeout')
503 ) { 505 ) {
504 return true; 506 return true;
diff --git a/application/netscape/NetscapeBookmarkUtils.php b/application/netscape/NetscapeBookmarkUtils.php
index 6ca728b7..2d97b4c8 100644
--- a/application/netscape/NetscapeBookmarkUtils.php
+++ b/application/netscape/NetscapeBookmarkUtils.php
@@ -59,11 +59,11 @@ class NetscapeBookmarkUtils
59 $indexUrl 59 $indexUrl
60 ) { 60 ) {
61 // see tpl/export.html for possible values 61 // see tpl/export.html for possible values
62 if (!in_array($selection, array('all', 'public', 'private'))) { 62 if (!in_array($selection, ['all', 'public', 'private'])) {
63 throw new Exception(t('Invalid export selection:') . ' "' . $selection . '"'); 63 throw new Exception(t('Invalid export selection:') . ' "' . $selection . '"');
64 } 64 }
65 65
66 $bookmarkLinks = array(); 66 $bookmarkLinks = [];
67 foreach ($this->bookmarkService->search([], $selection) as $bookmark) { 67 foreach ($this->bookmarkService->search([], $selection) as $bookmark) {
68 $link = $formatter->format($bookmark); 68 $link = $formatter->format($bookmark);
69 $link['taglist'] = implode(',', $bookmark->getTags()); 69 $link['taglist'] = implode(',', $bookmark->getTags());
diff --git a/application/plugin/PluginManager.php b/application/plugin/PluginManager.php
index da66dea3..3ea55728 100644
--- a/application/plugin/PluginManager.php
+++ b/application/plugin/PluginManager.php
@@ -1,4 +1,5 @@
1<?php 1<?php
2
2namespace Shaarli\Plugin; 3namespace Shaarli\Plugin;
3 4
4use Shaarli\Config\ConfigManager; 5use Shaarli\Config\ConfigManager;
@@ -23,7 +24,7 @@ class PluginManager
23 * 24 *
24 * @var array $loadedPlugins 25 * @var array $loadedPlugins
25 */ 26 */
26 private $loadedPlugins = array(); 27 private $loadedPlugins = [];
27 28
28 /** 29 /**
29 * @var ConfigManager Configuration Manager instance. 30 * @var ConfigManager Configuration Manager instance.
@@ -57,7 +58,7 @@ class PluginManager
57 public function __construct(&$conf) 58 public function __construct(&$conf)
58 { 59 {
59 $this->conf = $conf; 60 $this->conf = $conf;
60 $this->errors = array(); 61 $this->errors = [];
61 } 62 }
62 63
63 /** 64 /**
@@ -98,7 +99,7 @@ class PluginManager
98 * 99 *
99 * @return void 100 * @return void
100 */ 101 */
101 public function executeHooks($hook, &$data, $params = array()) 102 public function executeHooks($hook, &$data, $params = [])
102 { 103 {
103 $metadataParameters = [ 104 $metadataParameters = [
104 'target' => '_PAGE_', 105 'target' => '_PAGE_',
@@ -196,7 +197,7 @@ class PluginManager
196 */ 197 */
197 public function getPluginsMeta() 198 public function getPluginsMeta()
198 { 199 {
199 $metaData = array(); 200 $metaData = [];
200 $dirs = glob(self::$PLUGINS_PATH . '/*', GLOB_ONLYDIR | GLOB_MARK); 201 $dirs = glob(self::$PLUGINS_PATH . '/*', GLOB_ONLYDIR | GLOB_MARK);
201 202
202 // Browse all plugin directories. 203 // Browse all plugin directories.
@@ -217,9 +218,9 @@ class PluginManager
217 if (isset($metaData[$plugin]['parameters'])) { 218 if (isset($metaData[$plugin]['parameters'])) {
218 $params = explode(';', $metaData[$plugin]['parameters']); 219 $params = explode(';', $metaData[$plugin]['parameters']);
219 } else { 220 } else {
220 $params = array(); 221 $params = [];
221 } 222 }
222 $metaData[$plugin]['parameters'] = array(); 223 $metaData[$plugin]['parameters'] = [];
223 foreach ($params as $param) { 224 foreach ($params as $param) {
224 if (empty($param)) { 225 if (empty($param)) {
225 continue; 226 continue;
diff --git a/application/plugin/exception/PluginFileNotFoundException.php b/application/plugin/exception/PluginFileNotFoundException.php
index e5386f02..21ac6604 100644
--- a/application/plugin/exception/PluginFileNotFoundException.php
+++ b/application/plugin/exception/PluginFileNotFoundException.php
@@ -1,4 +1,5 @@
1<?php 1<?php
2
2namespace Shaarli\Plugin\Exception; 3namespace Shaarli\Plugin\Exception;
3 4
4use Exception; 5use Exception;
diff --git a/application/render/ThemeUtils.php b/application/render/ThemeUtils.php
index 86096c64..18471f0a 100644
--- a/application/render/ThemeUtils.php
+++ b/application/render/ThemeUtils.php
@@ -23,10 +23,10 @@ class ThemeUtils
23 public static function getThemes($tplDir) 23 public static function getThemes($tplDir)
24 { 24 {
25 $tplDir = rtrim($tplDir, '/'); 25 $tplDir = rtrim($tplDir, '/');
26 $allTheme = glob($tplDir.'/*', GLOB_ONLYDIR); 26 $allTheme = glob($tplDir . '/*', GLOB_ONLYDIR);
27 $themes = []; 27 $themes = [];
28 foreach ($allTheme as $value) { 28 foreach ($allTheme as $value) {
29 $themes[] = str_replace($tplDir.'/', '', $value); 29 $themes[] = str_replace($tplDir . '/', '', $value);
30 } 30 }
31 31
32 return $themes; 32 return $themes;
diff --git a/application/security/BanManager.php b/application/security/BanManager.php
index 288cbde0..7077af5b 100644
--- a/application/security/BanManager.php
+++ b/application/security/BanManager.php
@@ -1,6 +1,5 @@
1<?php 1<?php
2 2
3
4namespace Shaarli\Security; 3namespace Shaarli\Security;
5 4
6use Psr\Log\LoggerInterface; 5use Psr\Log\LoggerInterface;
@@ -47,7 +46,8 @@ class BanManager
47 * @param string $banFile Path to the file containing IP bans and failures 46 * @param string $banFile Path to the file containing IP bans and failures
48 * @param LoggerInterface $logger PSR-3 logger to save login attempts in log directory 47 * @param LoggerInterface $logger PSR-3 logger to save login attempts in log directory
49 */ 48 */
50 public function __construct($trustedProxies, $nbAttempts, $banDuration, $banFile, LoggerInterface $logger) { 49 public function __construct($trustedProxies, $nbAttempts, $banDuration, $banFile, LoggerInterface $logger)
50 {
51 $this->trustedProxies = $trustedProxies; 51 $this->trustedProxies = $trustedProxies;
52 $this->nbAttempts = $nbAttempts; 52 $this->nbAttempts = $nbAttempts;
53 $this->banDuration = $banDuration; 53 $this->banDuration = $banDuration;
@@ -80,7 +80,7 @@ class BanManager
80 80
81 if ($this->failures[$ip] >= $this->nbAttempts) { 81 if ($this->failures[$ip] >= $this->nbAttempts) {
82 $this->bans[$ip] = time() + $this->banDuration; 82 $this->bans[$ip] = time() + $this->banDuration;
83 $this->logger->info(format_log('IP address banned from login: '. $ip, $ip)); 83 $this->logger->info(format_log('IP address banned from login: ' . $ip, $ip));
84 } 84 }
85 $this->writeBanFile(); 85 $this->writeBanFile();
86 } 86 }
@@ -136,7 +136,7 @@ class BanManager
136 unset($this->failures[$ip]); 136 unset($this->failures[$ip]);
137 } 137 }
138 unset($this->bans[$ip]); 138 unset($this->bans[$ip]);
139 $this->logger->info(format_log('Ban lifted for: '. $ip, $ip)); 139 $this->logger->info(format_log('Ban lifted for: ' . $ip, $ip));
140 140
141 $this->writeBanFile(); 141 $this->writeBanFile();
142 return false; 142 return false;
diff --git a/application/security/LoginManager.php b/application/security/LoginManager.php
index 426e785e..b795b80e 100644
--- a/application/security/LoginManager.php
+++ b/application/security/LoginManager.php
@@ -1,4 +1,5 @@
1<?php 1<?php
2
2namespace Shaarli\Security; 3namespace Shaarli\Security;
3 4
4use Exception; 5use Exception;
@@ -106,7 +107,8 @@ class LoginManager
106 // The user client has a valid stay-signed-in cookie 107 // The user client has a valid stay-signed-in cookie
107 // Session information is updated with the current client information 108 // Session information is updated with the current client information
108 $this->sessionManager->storeLoginInfo($clientIpId); 109 $this->sessionManager->storeLoginInfo($clientIpId);
109 } elseif ($this->sessionManager->hasSessionExpired() 110 } elseif (
111 $this->sessionManager->hasSessionExpired()
110 || $this->sessionManager->hasClientIpChanged($clientIpId) 112 || $this->sessionManager->hasClientIpChanged($clientIpId)
111 ) { 113 ) {
112 $this->sessionManager->logout(); 114 $this->sessionManager->logout();
@@ -145,7 +147,8 @@ class LoginManager
145 // Check credentials 147 // Check credentials
146 try { 148 try {
147 $useLdapLogin = !empty($this->configManager->get('ldap.host')); 149 $useLdapLogin = !empty($this->configManager->get('ldap.host'));
148 if ($login === $this->configManager->get('credentials.login') 150 if (
151 $login === $this->configManager->get('credentials.login')
149 && ( 152 && (
150 (false === $useLdapLogin && $this->checkCredentialsFromLocalConfig($login, $password)) 153 (false === $useLdapLogin && $this->checkCredentialsFromLocalConfig($login, $password))
151 || (true === $useLdapLogin && $this->checkCredentialsFromLdap($login, $password)) 154 || (true === $useLdapLogin && $this->checkCredentialsFromLdap($login, $password))
@@ -156,7 +159,7 @@ class LoginManager
156 159
157 return true; 160 return true;
158 } 161 }
159 } catch(Exception $exception) { 162 } catch (Exception $exception) {
160 $this->logger->info(format_log('Exception while checking credentials: ' . $exception, $clientIpId)); 163 $this->logger->info(format_log('Exception while checking credentials: ' . $exception, $clientIpId));
161 } 164 }
162 165
@@ -174,7 +177,8 @@ class LoginManager
174 * 177 *
175 * @return bool true if the provided credentials are valid, false otherwise 178 * @return bool true if the provided credentials are valid, false otherwise
176 */ 179 */
177 public function checkCredentialsFromLocalConfig($login, $password) { 180 public function checkCredentialsFromLocalConfig($login, $password)
181 {
178 $hash = sha1($password . $login . $this->configManager->get('credentials.salt')); 182 $hash = sha1($password . $login . $this->configManager->get('credentials.salt'));
179 183
180 return $login == $this->configManager->get('credentials.login') 184 return $login == $this->configManager->get('credentials.login')
@@ -193,14 +197,14 @@ class LoginManager
193 */ 197 */
194 public function checkCredentialsFromLdap($login, $password, $connect = null, $bind = null) 198 public function checkCredentialsFromLdap($login, $password, $connect = null, $bind = null)
195 { 199 {
196 $connect = $connect ?? function($host) { 200 $connect = $connect ?? function ($host) {
197 $resource = ldap_connect($host); 201 $resource = ldap_connect($host);
198 202
199 ldap_set_option($resource, LDAP_OPT_PROTOCOL_VERSION, 3); 203 ldap_set_option($resource, LDAP_OPT_PROTOCOL_VERSION, 3);
200 204
201 return $resource; 205 return $resource;
202 }; 206 };
203 $bind = $bind ?? function($handle, $dn, $password) { 207 $bind = $bind ?? function ($handle, $dn, $password) {
204 return ldap_bind($handle, $dn, $password); 208 return ldap_bind($handle, $dn, $password);
205 }; 209 };
206 210
diff --git a/application/security/SessionManager.php b/application/security/SessionManager.php
index 96bf193c..f957b91a 100644
--- a/application/security/SessionManager.php
+++ b/application/security/SessionManager.php
@@ -1,4 +1,5 @@
1<?php 1<?php
2
2namespace Shaarli\Security; 3namespace Shaarli\Security;
3 4
4use Shaarli\Config\ConfigManager; 5use Shaarli\Config\ConfigManager;
@@ -79,7 +80,7 @@ class SessionManager
79 */ 80 */
80 public function generateToken() 81 public function generateToken()
81 { 82 {
82 $token = sha1(uniqid('', true) .'_'. mt_rand() . $this->conf->get('credentials.salt')); 83 $token = sha1(uniqid('', true) . '_' . mt_rand() . $this->conf->get('credentials.salt'));
83 $this->session['tokens'][$token] = 1; 84 $this->session['tokens'][$token] = 1;
84 return $token; 85 return $token;
85 } 86 }
diff --git a/application/updater/Updater.php b/application/updater/Updater.php
index 88a7bc7b..4f557d0f 100644
--- a/application/updater/Updater.php
+++ b/application/updater/Updater.php
@@ -88,7 +88,8 @@ class Updater
88 88
89 foreach ($this->methods as $method) { 89 foreach ($this->methods as $method) {
90 // Not an update method or already done, pass. 90 // Not an update method or already done, pass.
91 if (! startsWith($method->getName(), 'updateMethod') 91 if (
92 ! startsWith($method->getName(), 'updateMethod')
92 || in_array($method->getName(), $this->doneUpdates) 93 || in_array($method->getName(), $this->doneUpdates)
93 ) { 94 ) {
94 continue; 95 continue;
@@ -121,12 +122,12 @@ class Updater
121 122
122 public function readUpdates(string $updatesFilepath): array 123 public function readUpdates(string $updatesFilepath): array
123 { 124 {
124 return UpdaterUtils::read_updates_file($updatesFilepath); 125 return UpdaterUtils::readUpdatesFile($updatesFilepath);
125 } 126 }
126 127
127 public function writeUpdates(string $updatesFilepath, array $updates): void 128 public function writeUpdates(string $updatesFilepath, array $updates): void
128 { 129 {
129 UpdaterUtils::write_updates_file($updatesFilepath, $updates); 130 UpdaterUtils::writeUpdatesFile($updatesFilepath, $updates);
130 } 131 }
131 132
132 /** 133 /**
@@ -152,7 +153,8 @@ class Updater
152 $updated = false; 153 $updated = false;
153 154
154 foreach ($this->bookmarkService->search() as $bookmark) { 155 foreach ($this->bookmarkService->search() as $bookmark) {
155 if ($bookmark->isNote() 156 if (
157 $bookmark->isNote()
156 && startsWith($bookmark->getUrl(), '?') 158 && startsWith($bookmark->getUrl(), '?')
157 && 1 === preg_match('/^\?([a-zA-Z0-9-_@]{6})($|&|#)/', $bookmark->getUrl(), $match) 159 && 1 === preg_match('/^\?([a-zA-Z0-9-_@]{6})($|&|#)/', $bookmark->getUrl(), $match)
158 ) { 160 ) {
diff --git a/application/updater/UpdaterUtils.php b/application/updater/UpdaterUtils.php
index 828a49fc..206f826e 100644
--- a/application/updater/UpdaterUtils.php
+++ b/application/updater/UpdaterUtils.php
@@ -11,7 +11,7 @@ class UpdaterUtils
11 * 11 *
12 * @return array Already done update methods. 12 * @return array Already done update methods.
13 */ 13 */
14 public static function read_updates_file($updatesFilepath) 14 public static function readUpdatesFile($updatesFilepath)
15 { 15 {
16 if (! empty($updatesFilepath) && is_file($updatesFilepath)) { 16 if (! empty($updatesFilepath) && is_file($updatesFilepath)) {
17 $content = file_get_contents($updatesFilepath); 17 $content = file_get_contents($updatesFilepath);
@@ -19,7 +19,7 @@ class UpdaterUtils
19 return explode(';', $content); 19 return explode(';', $content);
20 } 20 }
21 } 21 }
22 return array(); 22 return [];
23 } 23 }
24 24
25 /** 25 /**
@@ -30,7 +30,7 @@ class UpdaterUtils
30 * 30 *
31 * @throws \Exception Couldn't write version number. 31 * @throws \Exception Couldn't write version number.
32 */ 32 */
33 public static function write_updates_file($updatesFilepath, $updates) 33 public static function writeUpdatesFile($updatesFilepath, $updates)
34 { 34 {
35 if (empty($updatesFilepath)) { 35 if (empty($updatesFilepath)) {
36 throw new \Exception('Updates file path is not set, can\'t write updates.'); 36 throw new \Exception('Updates file path is not set, can\'t write updates.');
@@ -38,7 +38,7 @@ class UpdaterUtils
38 38
39 $res = file_put_contents($updatesFilepath, implode(';', $updates)); 39 $res = file_put_contents($updatesFilepath, implode(';', $updates));
40 if ($res === false) { 40 if ($res === false) {
41 throw new \Exception('Unable to write updates in '. $updatesFilepath . '.'); 41 throw new \Exception('Unable to write updates in ' . $updatesFilepath . '.');
42 } 42 }
43 } 43 }
44} 44}