diff options
Diffstat (limited to 'application')
36 files changed, 493 insertions, 400 deletions
diff --git a/application/ApplicationUtils.php b/application/ApplicationUtils.php index a3b2dcb1..7fe3cb32 100644 --- a/application/ApplicationUtils.php +++ b/application/ApplicationUtils.php | |||
@@ -1,4 +1,9 @@ | |||
1 | <?php | 1 | <?php |
2 | namespace Shaarli; | ||
3 | |||
4 | use Exception; | ||
5 | use Shaarli\Config\ConfigManager; | ||
6 | |||
2 | /** | 7 | /** |
3 | * Shaarli (application) utilities | 8 | * Shaarli (application) utilities |
4 | */ | 9 | */ |
@@ -51,7 +56,7 @@ class ApplicationUtils | |||
51 | return false; | 56 | return false; |
52 | } | 57 | } |
53 | } else { | 58 | } else { |
54 | if (! is_file($remote)) { | 59 | if (!is_file($remote)) { |
55 | return false; | 60 | return false; |
56 | } | 61 | } |
57 | $data = file_get_contents($remote); | 62 | $data = file_get_contents($remote); |
@@ -97,7 +102,7 @@ class ApplicationUtils | |||
97 | // Do not check versions for visitors | 102 | // Do not check versions for visitors |
98 | // Do not check if the user doesn't want to | 103 | // Do not check if the user doesn't want to |
99 | // Do not check with dev version | 104 | // Do not check with dev version |
100 | if (! $isLoggedIn || empty($enableCheck) || $currentVersion === 'dev') { | 105 | if (!$isLoggedIn || empty($enableCheck) || $currentVersion === 'dev') { |
101 | return false; | 106 | return false; |
102 | } | 107 | } |
103 | 108 | ||
@@ -111,7 +116,7 @@ class ApplicationUtils | |||
111 | return false; | 116 | return false; |
112 | } | 117 | } |
113 | 118 | ||
114 | if (! in_array($branch, self::$GIT_BRANCHES)) { | 119 | if (!in_array($branch, self::$GIT_BRANCHES)) { |
115 | throw new Exception( | 120 | throw new Exception( |
116 | 'Invalid branch selected for updates: "' . $branch . '"' | 121 | 'Invalid branch selected for updates: "' . $branch . '"' |
117 | ); | 122 | ); |
@@ -123,7 +128,7 @@ class ApplicationUtils | |||
123 | self::$GIT_URL . '/' . $branch . '/' . self::$VERSION_FILE | 128 | self::$GIT_URL . '/' . $branch . '/' . self::$VERSION_FILE |
124 | ); | 129 | ); |
125 | 130 | ||
126 | if (! $latestVersion) { | 131 | if (!$latestVersion) { |
127 | // Only update the file's modification date | 132 | // Only update the file's modification date |
128 | file_put_contents($updateFile, $currentVersion); | 133 | file_put_contents($updateFile, $currentVersion); |
129 | return false; | 134 | return false; |
@@ -152,9 +157,9 @@ class ApplicationUtils | |||
152 | if (version_compare($curVersion, $minVersion) < 0) { | 157 | if (version_compare($curVersion, $minVersion) < 0) { |
153 | $msg = t( | 158 | $msg = t( |
154 | 'Your PHP version is obsolete!' | 159 | 'Your PHP version is obsolete!' |
155 | . ' Shaarli requires at least PHP %s, and thus cannot run.' | 160 | . ' Shaarli requires at least PHP %s, and thus cannot run.' |
156 | . ' Your PHP version has known security vulnerabilities and should be' | 161 | . ' Your PHP version has known security vulnerabilities and should be' |
157 | . ' updated as soon as possible.' | 162 | . ' updated as soon as possible.' |
158 | ); | 163 | ); |
159 | throw new Exception(sprintf($msg, $minVersion)); | 164 | throw new Exception(sprintf($msg, $minVersion)); |
160 | } | 165 | } |
@@ -174,50 +179,50 @@ class ApplicationUtils | |||
174 | 179 | ||
175 | // Check script and template directories are readable | 180 | // Check script and template directories are readable |
176 | foreach (array( | 181 | foreach (array( |
177 | 'application', | 182 | 'application', |
178 | 'inc', | 183 | 'inc', |
179 | 'plugins', | 184 | 'plugins', |
180 | $rainTplDir, | 185 | $rainTplDir, |
181 | $rainTplDir.'/'.$conf->get('resource.theme'), | 186 | $rainTplDir . '/' . $conf->get('resource.theme'), |
182 | ) as $path) { | 187 | ) as $path) { |
183 | if (! is_readable(realpath($path))) { | 188 | if (!is_readable(realpath($path))) { |
184 | $errors[] = '"'.$path.'" '. t('directory is not readable'); | 189 | $errors[] = '"' . $path . '" ' . t('directory is not readable'); |
185 | } | 190 | } |
186 | } | 191 | } |
187 | 192 | ||
188 | // Check cache and data directories are readable and writable | 193 | // Check cache and data directories are readable and writable |
189 | foreach (array( | 194 | foreach (array( |
190 | $conf->get('resource.thumbnails_cache'), | 195 | $conf->get('resource.thumbnails_cache'), |
191 | $conf->get('resource.data_dir'), | 196 | $conf->get('resource.data_dir'), |
192 | $conf->get('resource.page_cache'), | 197 | $conf->get('resource.page_cache'), |
193 | $conf->get('resource.raintpl_tmp'), | 198 | $conf->get('resource.raintpl_tmp'), |
194 | ) as $path) { | 199 | ) as $path) { |
195 | if (! is_readable(realpath($path))) { | 200 | if (!is_readable(realpath($path))) { |
196 | $errors[] = '"'.$path.'" '. t('directory is not readable'); | 201 | $errors[] = '"' . $path . '" ' . t('directory is not readable'); |
197 | } | 202 | } |
198 | if (! is_writable(realpath($path))) { | 203 | if (!is_writable(realpath($path))) { |
199 | $errors[] = '"'.$path.'" '. t('directory is not writable'); | 204 | $errors[] = '"' . $path . '" ' . t('directory is not writable'); |
200 | } | 205 | } |
201 | } | 206 | } |
202 | 207 | ||
203 | // Check configuration files are readable and writable | 208 | // Check configuration files are readable and writable |
204 | foreach (array( | 209 | foreach (array( |
205 | $conf->getConfigFileExt(), | 210 | $conf->getConfigFileExt(), |
206 | $conf->get('resource.datastore'), | 211 | $conf->get('resource.datastore'), |
207 | $conf->get('resource.ban_file'), | 212 | $conf->get('resource.ban_file'), |
208 | $conf->get('resource.log'), | 213 | $conf->get('resource.log'), |
209 | $conf->get('resource.update_check'), | 214 | $conf->get('resource.update_check'), |
210 | ) as $path) { | 215 | ) as $path) { |
211 | if (! is_file(realpath($path))) { | 216 | if (!is_file(realpath($path))) { |
212 | # the file may not exist yet | 217 | # the file may not exist yet |
213 | continue; | 218 | continue; |
214 | } | 219 | } |
215 | 220 | ||
216 | if (! is_readable(realpath($path))) { | 221 | if (!is_readable(realpath($path))) { |
217 | $errors[] = '"'.$path.'" '. t('file is not readable'); | 222 | $errors[] = '"' . $path . '" ' . t('file is not readable'); |
218 | } | 223 | } |
219 | if (! is_writable(realpath($path))) { | 224 | if (!is_writable(realpath($path))) { |
220 | $errors[] = '"'.$path.'" '. t('file is not writable'); | 225 | $errors[] = '"' . $path . '" ' . t('file is not writable'); |
221 | } | 226 | } |
222 | } | 227 | } |
223 | 228 | ||
diff --git a/application/FileUtils.php b/application/FileUtils.php index b89ea12b..30560bfc 100644 --- a/application/FileUtils.php +++ b/application/FileUtils.php | |||
@@ -1,6 +1,8 @@ | |||
1 | <?php | 1 | <?php |
2 | 2 | ||
3 | require_once 'exceptions/IOException.php'; | 3 | namespace Shaarli; |
4 | |||
5 | use Shaarli\Exceptions\IOException; | ||
4 | 6 | ||
5 | /** | 7 | /** |
6 | * Class FileUtils | 8 | * Class FileUtils |
@@ -44,7 +46,7 @@ class FileUtils | |||
44 | 46 | ||
45 | return file_put_contents( | 47 | return file_put_contents( |
46 | $file, | 48 | $file, |
47 | self::$phpPrefix.base64_encode(gzdeflate(serialize($content))).self::$phpSuffix | 49 | self::$phpPrefix . base64_encode(gzdeflate(serialize($content))) . self::$phpSuffix |
48 | ); | 50 | ); |
49 | } | 51 | } |
50 | 52 | ||
@@ -62,7 +64,7 @@ class FileUtils | |||
62 | { | 64 | { |
63 | // Note that gzinflate is faster than gzuncompress. | 65 | // Note that gzinflate is faster than gzuncompress. |
64 | // See: http://www.php.net/manual/en/function.gzdeflate.php#96439 | 66 | // See: http://www.php.net/manual/en/function.gzdeflate.php#96439 |
65 | if (! is_readable($file)) { | 67 | if (!is_readable($file)) { |
66 | return $default; | 68 | return $default; |
67 | } | 69 | } |
68 | 70 | ||
diff --git a/application/History.php b/application/History.php index 35ec016a..a5846652 100644 --- a/application/History.php +++ b/application/History.php | |||
@@ -1,4 +1,8 @@ | |||
1 | <?php | 1 | <?php |
2 | namespace Shaarli; | ||
3 | |||
4 | use DateTime; | ||
5 | use Exception; | ||
2 | 6 | ||
3 | /** | 7 | /** |
4 | * Class History | 8 | * Class History |
@@ -66,7 +70,7 @@ class History | |||
66 | * History constructor. | 70 | * History constructor. |
67 | * | 71 | * |
68 | * @param string $historyFilePath History file path. | 72 | * @param string $historyFilePath History file path. |
69 | * @param int $retentionTime History content rentention time in seconds. | 73 | * @param int $retentionTime History content retention time in seconds. |
70 | * | 74 | * |
71 | * @throws Exception if something goes wrong. | 75 | * @throws Exception if something goes wrong. |
72 | */ | 76 | */ |
@@ -166,11 +170,11 @@ class History | |||
166 | */ | 170 | */ |
167 | protected function check() | 171 | protected function check() |
168 | { | 172 | { |
169 | if (! is_file($this->historyFilePath)) { | 173 | if (!is_file($this->historyFilePath)) { |
170 | FileUtils::writeFlatDB($this->historyFilePath, []); | 174 | FileUtils::writeFlatDB($this->historyFilePath, []); |
171 | } | 175 | } |
172 | 176 | ||
173 | if (! is_writable($this->historyFilePath)) { | 177 | if (!is_writable($this->historyFilePath)) { |
174 | throw new Exception(t('History file isn\'t readable or writable')); | 178 | throw new Exception(t('History file isn\'t readable or writable')); |
175 | } | 179 | } |
176 | } | 180 | } |
@@ -191,7 +195,7 @@ class History | |||
191 | */ | 195 | */ |
192 | protected function write() | 196 | protected function write() |
193 | { | 197 | { |
194 | $comparaison = new DateTime('-'. $this->retentionTime . ' seconds'); | 198 | $comparaison = new DateTime('-' . $this->retentionTime . ' seconds'); |
195 | foreach ($this->history as $key => $value) { | 199 | foreach ($this->history as $key => $value) { |
196 | if ($value['datetime'] < $comparaison) { | 200 | if ($value['datetime'] < $comparaison) { |
197 | unset($this->history[$key]); | 201 | unset($this->history[$key]); |
diff --git a/application/Languages.php b/application/Languages.php index b9c5d0e8..5cda802e 100644 --- a/application/Languages.php +++ b/application/Languages.php | |||
@@ -3,7 +3,6 @@ | |||
3 | namespace Shaarli; | 3 | namespace Shaarli; |
4 | 4 | ||
5 | use Gettext\GettextTranslator; | 5 | use Gettext\GettextTranslator; |
6 | use Gettext\Merge; | ||
7 | use Gettext\Translations; | 6 | use Gettext\Translations; |
8 | use Gettext\Translator; | 7 | use Gettext\Translator; |
9 | use Gettext\TranslatorInterface; | 8 | use Gettext\TranslatorInterface; |
diff --git a/application/Router.php b/application/Router.php index beb3165b..05877acd 100644 --- a/application/Router.php +++ b/application/Router.php | |||
@@ -1,4 +1,5 @@ | |||
1 | <?php | 1 | <?php |
2 | namespace Shaarli; | ||
2 | 3 | ||
3 | /** | 4 | /** |
4 | * Class Router | 5 | * Class Router |
@@ -75,43 +76,43 @@ class Router | |||
75 | return self::$PAGE_LINKLIST; | 76 | return self::$PAGE_LINKLIST; |
76 | } | 77 | } |
77 | 78 | ||
78 | if (startsWith($query, 'do='. self::$PAGE_LOGIN) && $loggedIn === false) { | 79 | if (startsWith($query, 'do=' . self::$PAGE_LOGIN) && $loggedIn === false) { |
79 | return self::$PAGE_LOGIN; | 80 | return self::$PAGE_LOGIN; |
80 | } | 81 | } |
81 | 82 | ||
82 | if (startsWith($query, 'do='. self::$PAGE_PICWALL)) { | 83 | if (startsWith($query, 'do=' . self::$PAGE_PICWALL)) { |
83 | return self::$PAGE_PICWALL; | 84 | return self::$PAGE_PICWALL; |
84 | } | 85 | } |
85 | 86 | ||
86 | if (startsWith($query, 'do='. self::$PAGE_TAGCLOUD)) { | 87 | if (startsWith($query, 'do=' . self::$PAGE_TAGCLOUD)) { |
87 | return self::$PAGE_TAGCLOUD; | 88 | return self::$PAGE_TAGCLOUD; |
88 | } | 89 | } |
89 | 90 | ||
90 | if (startsWith($query, 'do='. self::$PAGE_TAGLIST)) { | 91 | if (startsWith($query, 'do=' . self::$PAGE_TAGLIST)) { |
91 | return self::$PAGE_TAGLIST; | 92 | return self::$PAGE_TAGLIST; |
92 | } | 93 | } |
93 | 94 | ||
94 | if (startsWith($query, 'do='. self::$PAGE_OPENSEARCH)) { | 95 | if (startsWith($query, 'do=' . self::$PAGE_OPENSEARCH)) { |
95 | return self::$PAGE_OPENSEARCH; | 96 | return self::$PAGE_OPENSEARCH; |
96 | } | 97 | } |
97 | 98 | ||
98 | if (startsWith($query, 'do='. self::$PAGE_DAILY)) { | 99 | if (startsWith($query, 'do=' . self::$PAGE_DAILY)) { |
99 | return self::$PAGE_DAILY; | 100 | return self::$PAGE_DAILY; |
100 | } | 101 | } |
101 | 102 | ||
102 | if (startsWith($query, 'do='. self::$PAGE_FEED_ATOM)) { | 103 | if (startsWith($query, 'do=' . self::$PAGE_FEED_ATOM)) { |
103 | return self::$PAGE_FEED_ATOM; | 104 | return self::$PAGE_FEED_ATOM; |
104 | } | 105 | } |
105 | 106 | ||
106 | if (startsWith($query, 'do='. self::$PAGE_FEED_RSS)) { | 107 | if (startsWith($query, 'do=' . self::$PAGE_FEED_RSS)) { |
107 | return self::$PAGE_FEED_RSS; | 108 | return self::$PAGE_FEED_RSS; |
108 | } | 109 | } |
109 | 110 | ||
110 | if (startsWith($query, 'do='. self::$PAGE_THUMBS_UPDATE)) { | 111 | if (startsWith($query, 'do=' . self::$PAGE_THUMBS_UPDATE)) { |
111 | return self::$PAGE_THUMBS_UPDATE; | 112 | return self::$PAGE_THUMBS_UPDATE; |
112 | } | 113 | } |
113 | 114 | ||
114 | if (startsWith($query, 'do='. self::$AJAX_THUMB_UPDATE)) { | 115 | if (startsWith($query, 'do=' . self::$AJAX_THUMB_UPDATE)) { |
115 | return self::$AJAX_THUMB_UPDATE; | 116 | return self::$AJAX_THUMB_UPDATE; |
116 | } | 117 | } |
117 | 118 | ||
@@ -120,23 +121,23 @@ class Router | |||
120 | return self::$PAGE_LINKLIST; | 121 | return self::$PAGE_LINKLIST; |
121 | } | 122 | } |
122 | 123 | ||
123 | if (startsWith($query, 'do='. self::$PAGE_TOOLS)) { | 124 | if (startsWith($query, 'do=' . self::$PAGE_TOOLS)) { |
124 | return self::$PAGE_TOOLS; | 125 | return self::$PAGE_TOOLS; |
125 | } | 126 | } |
126 | 127 | ||
127 | if (startsWith($query, 'do='. self::$PAGE_CHANGEPASSWORD)) { | 128 | if (startsWith($query, 'do=' . self::$PAGE_CHANGEPASSWORD)) { |
128 | return self::$PAGE_CHANGEPASSWORD; | 129 | return self::$PAGE_CHANGEPASSWORD; |
129 | } | 130 | } |
130 | 131 | ||
131 | if (startsWith($query, 'do='. self::$PAGE_CONFIGURE)) { | 132 | if (startsWith($query, 'do=' . self::$PAGE_CONFIGURE)) { |
132 | return self::$PAGE_CONFIGURE; | 133 | return self::$PAGE_CONFIGURE; |
133 | } | 134 | } |
134 | 135 | ||
135 | if (startsWith($query, 'do='. self::$PAGE_CHANGETAG)) { | 136 | if (startsWith($query, 'do=' . self::$PAGE_CHANGETAG)) { |
136 | return self::$PAGE_CHANGETAG; | 137 | return self::$PAGE_CHANGETAG; |
137 | } | 138 | } |
138 | 139 | ||
139 | if (startsWith($query, 'do='. self::$PAGE_ADDLINK)) { | 140 | if (startsWith($query, 'do=' . self::$PAGE_ADDLINK)) { |
140 | return self::$PAGE_ADDLINK; | 141 | return self::$PAGE_ADDLINK; |
141 | } | 142 | } |
142 | 143 | ||
@@ -148,27 +149,27 @@ class Router | |||
148 | return self::$PAGE_DELETELINK; | 149 | return self::$PAGE_DELETELINK; |
149 | } | 150 | } |
150 | 151 | ||
151 | if (startsWith($query, 'do='. self::$PAGE_PINLINK)) { | 152 | if (startsWith($query, 'do=' . self::$PAGE_PINLINK)) { |
152 | return self::$PAGE_PINLINK; | 153 | return self::$PAGE_PINLINK; |
153 | } | 154 | } |
154 | 155 | ||
155 | if (startsWith($query, 'do='. self::$PAGE_EXPORT)) { | 156 | if (startsWith($query, 'do=' . self::$PAGE_EXPORT)) { |
156 | return self::$PAGE_EXPORT; | 157 | return self::$PAGE_EXPORT; |
157 | } | 158 | } |
158 | 159 | ||
159 | if (startsWith($query, 'do='. self::$PAGE_IMPORT)) { | 160 | if (startsWith($query, 'do=' . self::$PAGE_IMPORT)) { |
160 | return self::$PAGE_IMPORT; | 161 | return self::$PAGE_IMPORT; |
161 | } | 162 | } |
162 | 163 | ||
163 | if (startsWith($query, 'do='. self::$PAGE_PLUGINSADMIN)) { | 164 | if (startsWith($query, 'do=' . self::$PAGE_PLUGINSADMIN)) { |
164 | return self::$PAGE_PLUGINSADMIN; | 165 | return self::$PAGE_PLUGINSADMIN; |
165 | } | 166 | } |
166 | 167 | ||
167 | if (startsWith($query, 'do='. self::$PAGE_SAVE_PLUGINSADMIN)) { | 168 | if (startsWith($query, 'do=' . self::$PAGE_SAVE_PLUGINSADMIN)) { |
168 | return self::$PAGE_SAVE_PLUGINSADMIN; | 169 | return self::$PAGE_SAVE_PLUGINSADMIN; |
169 | } | 170 | } |
170 | 171 | ||
171 | if (startsWith($query, 'do='. self::$GET_TOKEN)) { | 172 | if (startsWith($query, 'do=' . self::$GET_TOKEN)) { |
172 | return self::$GET_TOKEN; | 173 | return self::$GET_TOKEN; |
173 | } | 174 | } |
174 | 175 | ||
diff --git a/application/Thumbnailer.php b/application/Thumbnailer.php index 37ed97a1..a23f98e9 100644 --- a/application/Thumbnailer.php +++ b/application/Thumbnailer.php | |||
@@ -3,9 +3,9 @@ | |||
3 | namespace Shaarli; | 3 | namespace Shaarli; |
4 | 4 | ||
5 | use Shaarli\Config\ConfigManager; | 5 | use Shaarli\Config\ConfigManager; |
6 | use WebThumbnailer\Application\ConfigManager as WTConfigManager; | ||
6 | use WebThumbnailer\Exception\WebThumbnailerException; | 7 | use WebThumbnailer\Exception\WebThumbnailerException; |
7 | use WebThumbnailer\WebThumbnailer; | 8 | use WebThumbnailer\WebThumbnailer; |
8 | use WebThumbnailer\Application\ConfigManager as WTConfigManager; | ||
9 | 9 | ||
10 | /** | 10 | /** |
11 | * Class Thumbnailer | 11 | * Class Thumbnailer |
diff --git a/application/api/ApiMiddleware.php b/application/api/ApiMiddleware.php index 66eac133..5ffb8c6d 100644 --- a/application/api/ApiMiddleware.php +++ b/application/api/ApiMiddleware.php | |||
@@ -1,9 +1,8 @@ | |||
1 | <?php | 1 | <?php |
2 | namespace Shaarli\Api; | 2 | namespace Shaarli\Api; |
3 | 3 | ||
4 | use Shaarli\Api\Exceptions\ApiException; | ||
5 | use Shaarli\Api\Exceptions\ApiAuthorizationException; | 4 | use Shaarli\Api\Exceptions\ApiAuthorizationException; |
6 | 5 | use Shaarli\Api\Exceptions\ApiException; | |
7 | use Shaarli\Config\ConfigManager; | 6 | use Shaarli\Config\ConfigManager; |
8 | use Slim\Container; | 7 | use Slim\Container; |
9 | use Slim\Http\Request; | 8 | use Slim\Http\Request; |
@@ -127,7 +126,7 @@ class ApiMiddleware | |||
127 | */ | 126 | */ |
128 | protected function setLinkDb($conf) | 127 | protected function setLinkDb($conf) |
129 | { | 128 | { |
130 | $linkDb = new \LinkDB( | 129 | $linkDb = new \Shaarli\Bookmark\LinkDB( |
131 | $conf->get('resource.datastore'), | 130 | $conf->get('resource.datastore'), |
132 | true, | 131 | true, |
133 | $conf->get('privacy.hide_public_links'), | 132 | $conf->get('privacy.hide_public_links'), |
diff --git a/application/api/ApiUtils.php b/application/api/ApiUtils.php index fc5ecaf1..1824b5d0 100644 --- a/application/api/ApiUtils.php +++ b/application/api/ApiUtils.php | |||
@@ -1,8 +1,8 @@ | |||
1 | <?php | 1 | <?php |
2 | namespace Shaarli\Api; | 2 | namespace Shaarli\Api; |
3 | 3 | ||
4 | use Shaarli\Base64Url; | ||
5 | use Shaarli\Api\Exceptions\ApiAuthorizationException; | 4 | use Shaarli\Api\Exceptions\ApiAuthorizationException; |
5 | use Shaarli\Http\Base64Url; | ||
6 | 6 | ||
7 | /** | 7 | /** |
8 | * REST API utilities | 8 | * REST API utilities |
@@ -12,7 +12,7 @@ class ApiUtils | |||
12 | /** | 12 | /** |
13 | * Validates a JWT token authenticity. | 13 | * Validates a JWT token authenticity. |
14 | * | 14 | * |
15 | * @param string $token JWT token extracted from the headers. | 15 | * @param string $token JWT token extracted from the headers. |
16 | * @param string $secret API secret set in the settings. | 16 | * @param string $secret API secret set in the settings. |
17 | * | 17 | * |
18 | * @throws ApiAuthorizationException the token is not valid. | 18 | * @throws ApiAuthorizationException the token is not valid. |
@@ -50,7 +50,7 @@ class ApiUtils | |||
50 | /** | 50 | /** |
51 | * Format a Link for the REST API. | 51 | * Format a Link for the REST API. |
52 | * | 52 | * |
53 | * @param array $link Link data read from the datastore. | 53 | * @param array $link Link data read from the datastore. |
54 | * @param string $indexUrl Shaarli's index URL (used for relative URL). | 54 | * @param string $indexUrl Shaarli's index URL (used for relative URL). |
55 | * | 55 | * |
56 | * @return array Link data formatted for the REST API. | 56 | * @return array Link data formatted for the REST API. |
diff --git a/application/api/controllers/ApiController.php b/application/api/controllers/ApiController.php index 9edefcf6..a6e7cbab 100644 --- a/application/api/controllers/ApiController.php +++ b/application/api/controllers/ApiController.php | |||
@@ -2,8 +2,9 @@ | |||
2 | 2 | ||
3 | namespace Shaarli\Api\Controllers; | 3 | namespace Shaarli\Api\Controllers; |
4 | 4 | ||
5 | use Shaarli\Bookmark\LinkDB; | ||
5 | use Shaarli\Config\ConfigManager; | 6 | use Shaarli\Config\ConfigManager; |
6 | use \Slim\Container; | 7 | use Slim\Container; |
7 | 8 | ||
8 | /** | 9 | /** |
9 | * Abstract Class ApiController | 10 | * Abstract Class ApiController |
@@ -25,12 +26,12 @@ abstract class ApiController | |||
25 | protected $conf; | 26 | protected $conf; |
26 | 27 | ||
27 | /** | 28 | /** |
28 | * @var \LinkDB | 29 | * @var LinkDB |
29 | */ | 30 | */ |
30 | protected $linkDb; | 31 | protected $linkDb; |
31 | 32 | ||
32 | /** | 33 | /** |
33 | * @var \History | 34 | * @var HistoryController |
34 | */ | 35 | */ |
35 | protected $history; | 36 | protected $history; |
36 | 37 | ||
diff --git a/application/api/controllers/History.php b/application/api/controllers/HistoryController.php index 4582e8b2..9afcfa26 100644 --- a/application/api/controllers/History.php +++ b/application/api/controllers/HistoryController.php | |||
@@ -14,7 +14,7 @@ use Slim\Http\Response; | |||
14 | * | 14 | * |
15 | * @package Shaarli\Api\Controllers | 15 | * @package Shaarli\Api\Controllers |
16 | */ | 16 | */ |
17 | class History extends ApiController | 17 | class HistoryController extends ApiController |
18 | { | 18 | { |
19 | /** | 19 | /** |
20 | * Service providing operation regarding Shaarli datastore and settings. | 20 | * Service providing operation regarding Shaarli datastore and settings. |
diff --git a/application/api/controllers/Tags.php b/application/api/controllers/Tags.php index 6dd78750..82f3ef74 100644 --- a/application/api/controllers/Tags.php +++ b/application/api/controllers/Tags.php | |||
@@ -4,7 +4,6 @@ namespace Shaarli\Api\Controllers; | |||
4 | 4 | ||
5 | use Shaarli\Api\ApiUtils; | 5 | use Shaarli\Api\ApiUtils; |
6 | use Shaarli\Api\Exceptions\ApiBadParametersException; | 6 | use Shaarli\Api\Exceptions\ApiBadParametersException; |
7 | use Shaarli\Api\Exceptions\ApiLinkNotFoundException; | ||
8 | use Shaarli\Api\Exceptions\ApiTagNotFoundException; | 7 | use Shaarli\Api\Exceptions\ApiTagNotFoundException; |
9 | use Slim\Http\Request; | 8 | use Slim\Http\Request; |
10 | use Slim\Http\Response; | 9 | use Slim\Http\Response; |
diff --git a/application/api/exceptions/ApiLinkNotFoundException.php b/application/api/exceptions/ApiLinkNotFoundException.php index c727f4f0..7c2bb56e 100644 --- a/application/api/exceptions/ApiLinkNotFoundException.php +++ b/application/api/exceptions/ApiLinkNotFoundException.php | |||
@@ -2,8 +2,6 @@ | |||
2 | 2 | ||
3 | namespace Shaarli\Api\Exceptions; | 3 | namespace Shaarli\Api\Exceptions; |
4 | 4 | ||
5 | use Slim\Http\Response; | ||
6 | |||
7 | /** | 5 | /** |
8 | * Class ApiLinkNotFoundException | 6 | * Class ApiLinkNotFoundException |
9 | * | 7 | * |
diff --git a/application/api/exceptions/ApiTagNotFoundException.php b/application/api/exceptions/ApiTagNotFoundException.php index eee152fe..66ace8bf 100644 --- a/application/api/exceptions/ApiTagNotFoundException.php +++ b/application/api/exceptions/ApiTagNotFoundException.php | |||
@@ -2,8 +2,6 @@ | |||
2 | 2 | ||
3 | namespace Shaarli\Api\Exceptions; | 3 | namespace Shaarli\Api\Exceptions; |
4 | 4 | ||
5 | use Slim\Http\Response; | ||
6 | |||
7 | /** | 5 | /** |
8 | * Class ApiTagNotFoundException | 6 | * Class ApiTagNotFoundException |
9 | * | 7 | * |
diff --git a/application/LinkDB.php b/application/bookmark/LinkDB.php index 4bbc2950..c13a1141 100644 --- a/application/LinkDB.php +++ b/application/bookmark/LinkDB.php | |||
@@ -1,4 +1,15 @@ | |||
1 | <?php | 1 | <?php |
2 | |||
3 | namespace Shaarli\Bookmark; | ||
4 | |||
5 | use ArrayAccess; | ||
6 | use Countable; | ||
7 | use DateTime; | ||
8 | use Iterator; | ||
9 | use Shaarli\Bookmark\Exception\LinkNotFoundException; | ||
10 | use Shaarli\Exceptions\IOException; | ||
11 | use Shaarli\FileUtils; | ||
12 | |||
2 | /** | 13 | /** |
3 | * Data storage for links. | 14 | * Data storage for links. |
4 | * | 15 | * |
@@ -108,6 +119,7 @@ class LinkDB implements Iterator, Countable, ArrayAccess | |||
108 | $redirector = '', | 119 | $redirector = '', |
109 | $redirectorEncode = true | 120 | $redirectorEncode = true |
110 | ) { | 121 | ) { |
122 | |||
111 | $this->datastore = $datastore; | 123 | $this->datastore = $datastore; |
112 | $this->loggedIn = $isLoggedIn; | 124 | $this->loggedIn = $isLoggedIn; |
113 | $this->hidePublicLinks = $hidePublicLinks; | 125 | $this->hidePublicLinks = $hidePublicLinks; |
@@ -137,7 +149,7 @@ class LinkDB implements Iterator, Countable, ArrayAccess | |||
137 | if (!isset($value['id']) || empty($value['url'])) { | 149 | if (!isset($value['id']) || empty($value['url'])) { |
138 | die(t('Internal Error: A link should always have an id and URL.')); | 150 | die(t('Internal Error: A link should always have an id and URL.')); |
139 | } | 151 | } |
140 | if (($offset !== null && ! is_int($offset)) || ! is_int($value['id'])) { | 152 | if (($offset !== null && !is_int($offset)) || !is_int($value['id'])) { |
141 | die(t('You must specify an integer as a key.')); | 153 | die(t('You must specify an integer as a key.')); |
142 | } | 154 | } |
143 | if ($offset !== null && $offset !== $value['id']) { | 155 | if ($offset !== null && $offset !== $value['id']) { |
@@ -247,31 +259,31 @@ class LinkDB implements Iterator, Countable, ArrayAccess | |||
247 | $this->links = array(); | 259 | $this->links = array(); |
248 | $link = array( | 260 | $link = array( |
249 | 'id' => 1, | 261 | 'id' => 1, |
250 | 'title'=> t('The personal, minimalist, super-fast, database free, bookmarking service'), | 262 | 'title' => t('The personal, minimalist, super-fast, database free, bookmarking service'), |
251 | 'url'=>'https://shaarli.readthedocs.io', | 263 | 'url' => 'https://shaarli.readthedocs.io', |
252 | 'description'=>t( | 264 | 'description' => t( |
253 | 'Welcome to Shaarli! This is your first public bookmark. ' | 265 | 'Welcome to Shaarli! This is your first public bookmark. ' |
254 | .'To edit or delete me, you must first login. | 266 | . 'To edit or delete me, you must first login. |
255 | 267 | ||
256 | To learn how to use Shaarli, consult the link "Documentation" at the bottom of this page. | 268 | To learn how to use Shaarli, consult the link "Documentation" at the bottom of this page. |
257 | 269 | ||
258 | You use the community supported version of the original Shaarli project, by Sebastien Sauvage.' | 270 | You use the community supported version of the original Shaarli project, by Sebastien Sauvage.' |
259 | ), | 271 | ), |
260 | 'private'=>0, | 272 | 'private' => 0, |
261 | 'created'=> new DateTime(), | 273 | 'created' => new DateTime(), |
262 | 'tags'=>'opensource software' | 274 | 'tags' => 'opensource software' |
263 | ); | 275 | ); |
264 | $link['shorturl'] = link_small_hash($link['created'], $link['id']); | 276 | $link['shorturl'] = link_small_hash($link['created'], $link['id']); |
265 | $this->links[1] = $link; | 277 | $this->links[1] = $link; |
266 | 278 | ||
267 | $link = array( | 279 | $link = array( |
268 | 'id' => 0, | 280 | 'id' => 0, |
269 | 'title'=> t('My secret stuff... - Pastebin.com'), | 281 | 'title' => t('My secret stuff... - Pastebin.com'), |
270 | 'url'=>'http://sebsauvage.net/paste/?8434b27936c09649#bR7XsXhoTiLcqCpQbmOpBi3rq2zzQUC5hBI7ZT1O3x8=', | 282 | 'url' => 'http://sebsauvage.net/paste/?8434b27936c09649#bR7XsXhoTiLcqCpQbmOpBi3rq2zzQUC5hBI7ZT1O3x8=', |
271 | 'description'=> t('Shhhh! I\'m a private link only YOU can see. You can delete me too.'), | 283 | 'description' => t('Shhhh! I\'m a private link only YOU can see. You can delete me too.'), |
272 | 'private'=>1, | 284 | 'private' => 1, |
273 | 'created'=> new DateTime('1 minute ago'), | 285 | 'created' => new DateTime('1 minute ago'), |
274 | 'tags'=>'secretstuff', | 286 | 'tags' => 'secretstuff', |
275 | ); | 287 | ); |
276 | $link['shorturl'] = link_small_hash($link['created'], $link['id']); | 288 | $link['shorturl'] = link_small_hash($link['created'], $link['id']); |
277 | $this->links[0] = $link; | 289 | $this->links[0] = $link; |
@@ -297,7 +309,7 @@ You use the community supported version of the original Shaarli project, by Seba | |||
297 | 309 | ||
298 | $toremove = array(); | 310 | $toremove = array(); |
299 | foreach ($this->links as $key => &$link) { | 311 | foreach ($this->links as $key => &$link) { |
300 | if (! $this->loggedIn && $link['private'] != 0) { | 312 | if (!$this->loggedIn && $link['private'] != 0) { |
301 | // Transition for not upgraded databases. | 313 | // Transition for not upgraded databases. |
302 | unset($this->links[$key]); | 314 | unset($this->links[$key]); |
303 | continue; | 315 | continue; |
@@ -307,7 +319,7 @@ You use the community supported version of the original Shaarli project, by Seba | |||
307 | sanitizeLink($link); | 319 | sanitizeLink($link); |
308 | 320 | ||
309 | // Remove private tags if the user is not logged in. | 321 | // Remove private tags if the user is not logged in. |
310 | if (! $this->loggedIn) { | 322 | if (!$this->loggedIn) { |
311 | $link['tags'] = preg_replace('/(^|\s+)\.[^($|\s)]+\s*/', ' ', $link['tags']); | 323 | $link['tags'] = preg_replace('/(^|\s+)\.[^($|\s)]+\s*/', ' ', $link['tags']); |
312 | } | 324 | } |
313 | 325 | ||
@@ -324,10 +336,10 @@ You use the community supported version of the original Shaarli project, by Seba | |||
324 | } | 336 | } |
325 | 337 | ||
326 | // To be able to load links before running the update, and prepare the update | 338 | // To be able to load links before running the update, and prepare the update |
327 | if (! isset($link['created'])) { | 339 | if (!isset($link['created'])) { |
328 | $link['id'] = $link['linkdate']; | 340 | $link['id'] = $link['linkdate']; |
329 | $link['created'] = DateTime::createFromFormat(self::LINK_DATE_FORMAT, $link['linkdate']); | 341 | $link['created'] = DateTime::createFromFormat(self::LINK_DATE_FORMAT, $link['linkdate']); |
330 | if (! empty($link['updated'])) { | 342 | if (!empty($link['updated'])) { |
331 | $link['updated'] = DateTime::createFromFormat(self::LINK_DATE_FORMAT, $link['updated']); | 343 | $link['updated'] = DateTime::createFromFormat(self::LINK_DATE_FORMAT, $link['updated']); |
332 | } | 344 | } |
333 | $link['shorturl'] = smallHash($link['linkdate']); | 345 | $link['shorturl'] = smallHash($link['linkdate']); |
@@ -413,12 +425,12 @@ You use the community supported version of the original Shaarli project, by Seba | |||
413 | /** | 425 | /** |
414 | * Filter links according to search parameters. | 426 | * Filter links according to search parameters. |
415 | * | 427 | * |
416 | * @param array $filterRequest Search request content. Supported keys: | 428 | * @param array $filterRequest Search request content. Supported keys: |
417 | * - searchtags: list of tags | 429 | * - searchtags: list of tags |
418 | * - searchterm: term search | 430 | * - searchterm: term search |
419 | * @param bool $casesensitive Optional: Perform case sensitive filter | 431 | * @param bool $casesensitive Optional: Perform case sensitive filter |
420 | * @param string $visibility return only all/private/public links | 432 | * @param string $visibility return only all/private/public links |
421 | * @param string $untaggedonly return only untagged links | 433 | * @param bool $untaggedonly return only untagged links |
422 | * | 434 | * |
423 | * @return array filtered links, all links if no suitable filter was provided. | 435 | * @return array filtered links, all links if no suitable filter was provided. |
424 | */ | 436 | */ |
@@ -428,6 +440,7 @@ You use the community supported version of the original Shaarli project, by Seba | |||
428 | $visibility = 'all', | 440 | $visibility = 'all', |
429 | $untaggedonly = false | 441 | $untaggedonly = false |
430 | ) { | 442 | ) { |
443 | |||
431 | // Filter link database according to parameters. | 444 | // Filter link database according to parameters. |
432 | $searchtags = isset($filterRequest['searchtags']) ? escape($filterRequest['searchtags']) : ''; | 445 | $searchtags = isset($filterRequest['searchtags']) ? escape($filterRequest['searchtags']) : ''; |
433 | $searchterm = isset($filterRequest['searchterm']) ? escape($filterRequest['searchterm']) : ''; | 446 | $searchterm = isset($filterRequest['searchterm']) ? escape($filterRequest['searchterm']) : ''; |
@@ -443,8 +456,8 @@ You use the community supported version of the original Shaarli project, by Seba | |||
443 | /** | 456 | /** |
444 | * Returns the list tags appearing in the links with the given tags | 457 | * Returns the list tags appearing in the links with the given tags |
445 | * | 458 | * |
446 | * @param array $filteringTags tags selecting the links to consider | 459 | * @param array $filteringTags tags selecting the links to consider |
447 | * @param string $visibility process only all/private/public links | 460 | * @param string $visibility process only all/private/public links |
448 | * | 461 | * |
449 | * @return array tag => linksCount | 462 | * @return array tag => linksCount |
450 | */ | 463 | */ |
diff --git a/application/LinkFilter.php b/application/bookmark/LinkFilter.php index 8f147974..9b966307 100644 --- a/application/LinkFilter.php +++ b/application/bookmark/LinkFilter.php | |||
@@ -1,5 +1,10 @@ | |||
1 | <?php | 1 | <?php |
2 | 2 | ||
3 | namespace Shaarli\Bookmark; | ||
4 | |||
5 | use Exception; | ||
6 | use Shaarli\Bookmark\Exception\LinkNotFoundException; | ||
7 | |||
3 | /** | 8 | /** |
4 | * Class LinkFilter. | 9 | * Class LinkFilter. |
5 | * | 10 | * |
@@ -10,22 +15,22 @@ class LinkFilter | |||
10 | /** | 15 | /** |
11 | * @var string permalinks. | 16 | * @var string permalinks. |
12 | */ | 17 | */ |
13 | public static $FILTER_HASH = 'permalink'; | 18 | public static $FILTER_HASH = 'permalink'; |
14 | 19 | ||
15 | /** | 20 | /** |
16 | * @var string text search. | 21 | * @var string text search. |
17 | */ | 22 | */ |
18 | public static $FILTER_TEXT = 'fulltext'; | 23 | public static $FILTER_TEXT = 'fulltext'; |
19 | 24 | ||
20 | /** | 25 | /** |
21 | * @var string tag filter. | 26 | * @var string tag filter. |
22 | */ | 27 | */ |
23 | public static $FILTER_TAG = 'tags'; | 28 | public static $FILTER_TAG = 'tags'; |
24 | 29 | ||
25 | /** | 30 | /** |
26 | * @var string filter by day. | 31 | * @var string filter by day. |
27 | */ | 32 | */ |
28 | public static $FILTER_DAY = 'FILTER_DAY'; | 33 | public static $FILTER_DAY = 'FILTER_DAY'; |
29 | 34 | ||
30 | /** | 35 | /** |
31 | * @var string Allowed characters for hashtags (regex syntax). | 36 | * @var string Allowed characters for hashtags (regex syntax). |
@@ -58,7 +63,7 @@ class LinkFilter | |||
58 | */ | 63 | */ |
59 | public function filter($type, $request, $casesensitive = false, $visibility = 'all', $untaggedonly = false) | 64 | public function filter($type, $request, $casesensitive = false, $visibility = 'all', $untaggedonly = false) |
60 | { | 65 | { |
61 | if (! in_array($visibility, ['all', 'public', 'private'])) { | 66 | if (!in_array($visibility, ['all', 'public', 'private'])) { |
62 | $visibility = 'all'; | 67 | $visibility = 'all'; |
63 | } | 68 | } |
64 | 69 | ||
@@ -117,7 +122,7 @@ class LinkFilter | |||
117 | foreach ($this->links as $key => $value) { | 122 | foreach ($this->links as $key => $value) { |
118 | if ($value['private'] && $visibility === 'private') { | 123 | if ($value['private'] && $visibility === 'private') { |
119 | $out[$key] = $value; | 124 | $out[$key] = $value; |
120 | } elseif (! $value['private'] && $visibility === 'public') { | 125 | } elseif (!$value['private'] && $visibility === 'public') { |
121 | $out[$key] = $value; | 126 | $out[$key] = $value; |
122 | } | 127 | } |
123 | } | 128 | } |
@@ -132,7 +137,7 @@ class LinkFilter | |||
132 | * | 137 | * |
133 | * @return array $filtered array containing permalink data. | 138 | * @return array $filtered array containing permalink data. |
134 | * | 139 | * |
135 | * @throws LinkNotFoundException if the smallhash doesn't match any link. | 140 | * @throws \Shaarli\Bookmark\Exception\LinkNotFoundException if the smallhash doesn't match any link. |
136 | */ | 141 | */ |
137 | private function filterSmallHash($smallHash) | 142 | private function filterSmallHash($smallHash) |
138 | { | 143 | { |
@@ -169,7 +174,7 @@ class LinkFilter | |||
169 | * - see https://github.com/shaarli/Shaarli/issues/75 for examples | 174 | * - see https://github.com/shaarli/Shaarli/issues/75 for examples |
170 | * | 175 | * |
171 | * @param string $searchterms search query. | 176 | * @param string $searchterms search query. |
172 | * @param string $visibility Optional: return only all/private/public links. | 177 | * @param string $visibility Optional: return only all/private/public links. |
173 | * | 178 | * |
174 | * @return array search results. | 179 | * @return array search results. |
175 | */ | 180 | */ |
@@ -207,7 +212,7 @@ class LinkFilter | |||
207 | foreach ($this->links as $id => $link) { | 212 | foreach ($this->links as $id => $link) { |
208 | // ignore non private links when 'privatonly' is on. | 213 | // ignore non private links when 'privatonly' is on. |
209 | if ($visibility !== 'all') { | 214 | if ($visibility !== 'all') { |
210 | if (! $link['private'] && $visibility === 'private') { | 215 | if (!$link['private'] && $visibility === 'private') { |
211 | continue; | 216 | continue; |
212 | } elseif ($link['private'] && $visibility === 'public') { | 217 | } elseif ($link['private'] && $visibility === 'public') { |
213 | continue; | 218 | continue; |
@@ -250,7 +255,9 @@ class LinkFilter | |||
250 | 255 | ||
251 | /** | 256 | /** |
252 | * generate a regex fragment out of a tag | 257 | * generate a regex fragment out of a tag |
258 | * | ||
253 | * @param string $tag to to generate regexs from. may start with '-' to negate, contain '*' as wildcard | 259 | * @param string $tag to to generate regexs from. may start with '-' to negate, contain '*' as wildcard |
260 | * | ||
254 | * @return string generated regex fragment | 261 | * @return string generated regex fragment |
255 | */ | 262 | */ |
256 | private static function tag2regex($tag) | 263 | private static function tag2regex($tag) |
@@ -334,7 +341,7 @@ class LinkFilter | |||
334 | // check level of visibility | 341 | // check level of visibility |
335 | // ignore non private links when 'privateonly' is on. | 342 | // ignore non private links when 'privateonly' is on. |
336 | if ($visibility !== 'all') { | 343 | if ($visibility !== 'all') { |
337 | if (! $link['private'] && $visibility === 'private') { | 344 | if (!$link['private'] && $visibility === 'private') { |
338 | continue; | 345 | continue; |
339 | } elseif ($link['private'] && $visibility === 'public') { | 346 | } elseif ($link['private'] && $visibility === 'public') { |
340 | continue; | 347 | continue; |
@@ -377,7 +384,7 @@ class LinkFilter | |||
377 | $filtered = []; | 384 | $filtered = []; |
378 | foreach ($this->links as $key => $link) { | 385 | foreach ($this->links as $key => $link) { |
379 | if ($visibility !== 'all') { | 386 | if ($visibility !== 'all') { |
380 | if (! $link['private'] && $visibility === 'private') { | 387 | if (!$link['private'] && $visibility === 'private') { |
381 | continue; | 388 | continue; |
382 | } elseif ($link['private'] && $visibility === 'public') { | 389 | } elseif ($link['private'] && $visibility === 'public') { |
383 | continue; | 390 | continue; |
@@ -406,7 +413,7 @@ class LinkFilter | |||
406 | */ | 413 | */ |
407 | public function filterDay($day) | 414 | public function filterDay($day) |
408 | { | 415 | { |
409 | if (! checkDateFormat('Ymd', $day)) { | 416 | if (!checkDateFormat('Ymd', $day)) { |
410 | throw new Exception('Invalid date format'); | 417 | throw new Exception('Invalid date format'); |
411 | } | 418 | } |
412 | 419 | ||
@@ -440,14 +447,3 @@ class LinkFilter | |||
440 | return preg_split('/\s+/', $tagsOut, -1, PREG_SPLIT_NO_EMPTY); | 447 | return preg_split('/\s+/', $tagsOut, -1, PREG_SPLIT_NO_EMPTY); |
441 | } | 448 | } |
442 | } | 449 | } |
443 | |||
444 | class LinkNotFoundException extends Exception | ||
445 | { | ||
446 | /** | ||
447 | * LinkNotFoundException constructor. | ||
448 | */ | ||
449 | public function __construct() | ||
450 | { | ||
451 | $this->message = t('The link you are trying to reach does not exist or has been deleted.'); | ||
452 | } | ||
453 | } | ||
diff --git a/application/LinkUtils.php b/application/bookmark/LinkUtils.php index d56e019f..de5b61cb 100644 --- a/application/LinkUtils.php +++ b/application/bookmark/LinkUtils.php | |||
@@ -1,11 +1,13 @@ | |||
1 | <?php | 1 | <?php |
2 | 2 | ||
3 | use Shaarli\Bookmark\LinkDB; | ||
4 | |||
3 | /** | 5 | /** |
4 | * Get cURL callback function for CURLOPT_WRITEFUNCTION | 6 | * Get cURL callback function for CURLOPT_WRITEFUNCTION |
5 | * | 7 | * |
6 | * @param string $charset to extract from the downloaded page (reference) | 8 | * @param string $charset to extract from the downloaded page (reference) |
7 | * @param string $title to extract from the downloaded page (reference) | 9 | * @param string $title to extract from the downloaded page (reference) |
8 | * @param string $curlGetInfo Optionnaly overrides curl_getinfo function | 10 | * @param string $curlGetInfo Optionally overrides curl_getinfo function |
9 | * | 11 | * |
10 | * @return Closure | 12 | * @return Closure |
11 | */ | 13 | */ |
@@ -196,7 +198,7 @@ function space2nbsp($text) | |||
196 | * | 198 | * |
197 | * @param string $description shaare's description. | 199 | * @param string $description shaare's description. |
198 | * @param string $redirector if a redirector is set, use it to gerenate links. | 200 | * @param string $redirector if a redirector is set, use it to gerenate links. |
199 | * @param bool $urlEncode Use `urlencode()` on the URL after the redirector or not. | 201 | * @param bool $urlEncode Use `urlencode()` on the URL after the redirector or not. |
200 | * @param string $indexUrl URL to Shaarli's index. | 202 | * @param string $indexUrl URL to Shaarli's index. |
201 | 203 | ||
202 | * @return string formatted description. | 204 | * @return string formatted description. |
diff --git a/application/bookmark/exception/LinkNotFoundException.php b/application/bookmark/exception/LinkNotFoundException.php new file mode 100644 index 00000000..f9414428 --- /dev/null +++ b/application/bookmark/exception/LinkNotFoundException.php | |||
@@ -0,0 +1,15 @@ | |||
1 | <?php | ||
2 | namespace Shaarli\Bookmark\Exception; | ||
3 | |||
4 | use Exception; | ||
5 | |||
6 | class LinkNotFoundException extends Exception | ||
7 | { | ||
8 | /** | ||
9 | * LinkNotFoundException constructor. | ||
10 | */ | ||
11 | public function __construct() | ||
12 | { | ||
13 | $this->message = t('The link you are trying to reach does not exist or has been deleted.'); | ||
14 | } | ||
15 | } | ||
diff --git a/application/config/ConfigJson.php b/application/config/ConfigJson.php index 8c8d5610..4509357c 100644 --- a/application/config/ConfigJson.php +++ b/application/config/ConfigJson.php | |||
@@ -47,7 +47,7 @@ class ConfigJson implements ConfigIO | |||
47 | $print = defined('JSON_PRETTY_PRINT') ? JSON_PRETTY_PRINT : 0; | 47 | $print = defined('JSON_PRETTY_PRINT') ? JSON_PRETTY_PRINT : 0; |
48 | $data = self::getPhpHeaders() . json_encode($conf, $print) . self::getPhpSuffix(); | 48 | $data = self::getPhpHeaders() . json_encode($conf, $print) . self::getPhpSuffix(); |
49 | if (!file_put_contents($filepath, $data)) { | 49 | if (!file_put_contents($filepath, $data)) { |
50 | throw new \IOException( | 50 | throw new \Shaarli\Exceptions\IOException( |
51 | $filepath, | 51 | $filepath, |
52 | t('Shaarli could not create the config file. '. | 52 | t('Shaarli could not create the config file. '. |
53 | 'Please make sure Shaarli has the right to write in the folder is it installed in.') | 53 | 'Please make sure Shaarli has the right to write in the folder is it installed in.') |
diff --git a/application/config/ConfigManager.php b/application/config/ConfigManager.php index 32aaea48..e6c35073 100644 --- a/application/config/ConfigManager.php +++ b/application/config/ConfigManager.php | |||
@@ -207,7 +207,7 @@ class ConfigManager | |||
207 | * | 207 | * |
208 | * @throws MissingFieldConfigException: a mandatory field has not been provided in $conf. | 208 | * @throws MissingFieldConfigException: a mandatory field has not been provided in $conf. |
209 | * @throws UnauthorizedConfigException: user is not authorize to change configuration. | 209 | * @throws UnauthorizedConfigException: user is not authorize to change configuration. |
210 | * @throws \IOException: an error occurred while writing the new config file. | 210 | * @throws \Shaarli\Exceptions\IOException: an error occurred while writing the new config file. |
211 | */ | 211 | */ |
212 | public function write($isLoggedIn) | 212 | public function write($isLoggedIn) |
213 | { | 213 | { |
diff --git a/application/config/ConfigPhp.php b/application/config/ConfigPhp.php index 9625fe1a..cad34594 100644 --- a/application/config/ConfigPhp.php +++ b/application/config/ConfigPhp.php | |||
@@ -27,7 +27,7 @@ class ConfigPhp implements ConfigIO | |||
27 | /** | 27 | /** |
28 | * Map legacy config keys with the new ones. | 28 | * Map legacy config keys with the new ones. |
29 | * If ConfigPhp is used, getting <newkey> will actually look for <legacykey>. | 29 | * If ConfigPhp is used, getting <newkey> will actually look for <legacykey>. |
30 | * The Updater will use this array to transform keys when switching to JSON. | 30 | * The updater will use this array to transform keys when switching to JSON. |
31 | * | 31 | * |
32 | * @var array current key => legacy key. | 32 | * @var array current key => legacy key. |
33 | */ | 33 | */ |
@@ -124,7 +124,7 @@ class ConfigPhp implements ConfigIO | |||
124 | if (!file_put_contents($filepath, $configStr) | 124 | if (!file_put_contents($filepath, $configStr) |
125 | || strcmp(file_get_contents($filepath), $configStr) != 0 | 125 | || strcmp(file_get_contents($filepath), $configStr) != 0 |
126 | ) { | 126 | ) { |
127 | throw new \IOException( | 127 | throw new \Shaarli\Exceptions\IOException( |
128 | $filepath, | 128 | $filepath, |
129 | t('Shaarli could not create the config file. '. | 129 | 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.') | 130 | 'Please make sure Shaarli has the right to write in the folder is it installed in.') |
diff --git a/application/exceptions/IOException.php b/application/exceptions/IOException.php index 18e46b77..2aa25e5c 100644 --- a/application/exceptions/IOException.php +++ b/application/exceptions/IOException.php | |||
@@ -1,4 +1,7 @@ | |||
1 | <?php | 1 | <?php |
2 | namespace Shaarli\Exceptions; | ||
3 | |||
4 | use Exception; | ||
2 | 5 | ||
3 | /** | 6 | /** |
4 | * Exception class thrown when a filesystem access failure happens | 7 | * Exception class thrown when a filesystem access failure happens |
@@ -17,6 +20,6 @@ class IOException extends Exception | |||
17 | { | 20 | { |
18 | $this->path = $path; | 21 | $this->path = $path; |
19 | $this->message = empty($message) ? t('Error accessing') : $message; | 22 | $this->message = empty($message) ? t('Error accessing') : $message; |
20 | $this->message .= ' "' . $this->path .'"'; | 23 | $this->message .= ' "' . $this->path . '"'; |
21 | } | 24 | } |
22 | } | 25 | } |
diff --git a/application/Cache.php b/application/feed/Cache.php index e5d43e61..e5d43e61 100644 --- a/application/Cache.php +++ b/application/feed/Cache.php | |||
diff --git a/application/CachedPage.php b/application/feed/CachedPage.php index e11cc52d..d809bdd9 100644 --- a/application/CachedPage.php +++ b/application/feed/CachedPage.php | |||
@@ -1,4 +1,7 @@ | |||
1 | <?php | 1 | <?php |
2 | |||
3 | namespace Shaarli\Feed; | ||
4 | |||
2 | /** | 5 | /** |
3 | * Simple cache system, mainly for the RSS/ATOM feeds | 6 | * Simple cache system, mainly for the RSS/ATOM feeds |
4 | */ | 7 | */ |
@@ -24,7 +27,7 @@ class CachedPage | |||
24 | { | 27 | { |
25 | // TODO: check write access to the cache directory | 28 | // TODO: check write access to the cache directory |
26 | $this->cacheDir = $cacheDir; | 29 | $this->cacheDir = $cacheDir; |
27 | $this->filename = $this->cacheDir.'/'.sha1($url).'.cache'; | 30 | $this->filename = $this->cacheDir . '/' . sha1($url) . '.cache'; |
28 | $this->shouldBeCached = $shouldBeCached; | 31 | $this->shouldBeCached = $shouldBeCached; |
29 | } | 32 | } |
30 | 33 | ||
diff --git a/application/FeedBuilder.php b/application/feed/FeedBuilder.php index 73fafcbe..b66f2f91 100644 --- a/application/FeedBuilder.php +++ b/application/feed/FeedBuilder.php | |||
@@ -1,4 +1,7 @@ | |||
1 | <?php | 1 | <?php |
2 | namespace Shaarli\Feed; | ||
3 | |||
4 | use DateTime; | ||
2 | 5 | ||
3 | /** | 6 | /** |
4 | * FeedBuilder class. | 7 | * FeedBuilder class. |
@@ -28,7 +31,7 @@ class FeedBuilder | |||
28 | public static $DEFAULT_NB_LINKS = 50; | 31 | public static $DEFAULT_NB_LINKS = 50; |
29 | 32 | ||
30 | /** | 33 | /** |
31 | * @var LinkDB instance. | 34 | * @var \Shaarli\Bookmark\LinkDB instance. |
32 | */ | 35 | */ |
33 | protected $linkDB; | 36 | protected $linkDB; |
34 | 37 | ||
@@ -38,12 +41,12 @@ class FeedBuilder | |||
38 | protected $feedType; | 41 | protected $feedType; |
39 | 42 | ||
40 | /** | 43 | /** |
41 | * @var array $_SERVER. | 44 | * @var array $_SERVER |
42 | */ | 45 | */ |
43 | protected $serverInfo; | 46 | protected $serverInfo; |
44 | 47 | ||
45 | /** | 48 | /** |
46 | * @var array $_GET. | 49 | * @var array $_GET |
47 | */ | 50 | */ |
48 | protected $userInput; | 51 | protected $userInput; |
49 | 52 | ||
@@ -75,11 +78,12 @@ class FeedBuilder | |||
75 | /** | 78 | /** |
76 | * Feed constructor. | 79 | * Feed constructor. |
77 | * | 80 | * |
78 | * @param LinkDB $linkDB LinkDB instance. | 81 | * @param \Shaarli\Bookmark\LinkDB $linkDB LinkDB instance. |
79 | * @param string $feedType Type of feed. | 82 | * @param string $feedType Type of feed. |
80 | * @param array $serverInfo $_SERVER. | 83 | * @param array $serverInfo $_SERVER. |
81 | * @param array $userInput $_GET. | 84 | * @param array $userInput $_GET. |
82 | * @param boolean $isLoggedIn True if the user is currently logged in, false otherwise. | 85 | * @param boolean $isLoggedIn True if the user is currently logged in, |
86 | * false otherwise. | ||
83 | */ | 87 | */ |
84 | public function __construct($linkDB, $feedType, $serverInfo, $userInput, $isLoggedIn) | 88 | public function __construct($linkDB, $feedType, $serverInfo, $userInput, $isLoggedIn) |
85 | { | 89 | { |
@@ -124,7 +128,7 @@ class FeedBuilder | |||
124 | $data['show_dates'] = !$this->hideDates || $this->isLoggedIn; | 128 | $data['show_dates'] = !$this->hideDates || $this->isLoggedIn; |
125 | // Remove leading slash from REQUEST_URI. | 129 | // Remove leading slash from REQUEST_URI. |
126 | $data['self_link'] = escape(server_url($this->serverInfo)) | 130 | $data['self_link'] = escape(server_url($this->serverInfo)) |
127 | . escape($this->serverInfo['REQUEST_URI']); | 131 | . escape($this->serverInfo['REQUEST_URI']); |
128 | $data['index_url'] = $pageaddr; | 132 | $data['index_url'] = $pageaddr; |
129 | $data['usepermalinks'] = $this->usePermalinks === true; | 133 | $data['usepermalinks'] = $this->usePermalinks === true; |
130 | $data['links'] = $linkDisplayed; | 134 | $data['links'] = $linkDisplayed; |
@@ -142,18 +146,18 @@ class FeedBuilder | |||
142 | */ | 146 | */ |
143 | protected function buildItem($link, $pageaddr) | 147 | protected function buildItem($link, $pageaddr) |
144 | { | 148 | { |
145 | $link['guid'] = $pageaddr .'?'. $link['shorturl']; | 149 | $link['guid'] = $pageaddr . '?' . $link['shorturl']; |
146 | // Check for both signs of a note: starting with ? and 7 chars long. | 150 | // Check for both signs of a note: starting with ? and 7 chars long. |
147 | if ($link['url'][0] === '?' && strlen($link['url']) === 7) { | 151 | if ($link['url'][0] === '?' && strlen($link['url']) === 7) { |
148 | $link['url'] = $pageaddr . $link['url']; | 152 | $link['url'] = $pageaddr . $link['url']; |
149 | } | 153 | } |
150 | if ($this->usePermalinks === true) { | 154 | if ($this->usePermalinks === true) { |
151 | $permalink = '<a href="'. $link['url'] .'" title="'. t('Direct link') .'">'. t('Direct link') .'</a>'; | 155 | $permalink = '<a href="' . $link['url'] . '" title="' . t('Direct link') . '">' . t('Direct link') . '</a>'; |
152 | } else { | 156 | } else { |
153 | $permalink = '<a href="'. $link['guid'] .'" title="'. t('Permalink') .'">'. t('Permalink') .'</a>'; | 157 | $permalink = '<a href="' . $link['guid'] . '" title="' . t('Permalink') . '">' . t('Permalink') . '</a>'; |
154 | } | 158 | } |
155 | $link['description'] = format_description($link['description'], '', false, $pageaddr); | 159 | $link['description'] = format_description($link['description'], '', false, $pageaddr); |
156 | $link['description'] .= PHP_EOL .'<br>— '. $permalink; | 160 | $link['description'] .= PHP_EOL . '<br>— ' . $permalink; |
157 | 161 | ||
158 | $pubDate = $link['created']; | 162 | $pubDate = $link['created']; |
159 | $link['pub_iso_date'] = $this->getIsoDate($pubDate); | 163 | $link['pub_iso_date'] = $this->getIsoDate($pubDate); |
@@ -164,7 +168,6 @@ class FeedBuilder | |||
164 | $link['up_iso_date'] = $this->getIsoDate($upDate, DateTime::ATOM); | 168 | $link['up_iso_date'] = $this->getIsoDate($upDate, DateTime::ATOM); |
165 | } else { | 169 | } else { |
166 | $link['up_iso_date'] = $this->getIsoDate($pubDate, DateTime::ATOM); | 170 | $link['up_iso_date'] = $this->getIsoDate($pubDate, DateTime::ATOM); |
167 | ; | ||
168 | } | 171 | } |
169 | 172 | ||
170 | // Save the more recent item. | 173 | // Save the more recent item. |
@@ -223,11 +226,11 @@ class FeedBuilder | |||
223 | public function getTypeLanguage() | 226 | public function getTypeLanguage() |
224 | { | 227 | { |
225 | // Use the locale do define the language, if available. | 228 | // Use the locale do define the language, if available. |
226 | if (! empty($this->locale) && preg_match('/^\w{2}[_\-]\w{2}/', $this->locale)) { | 229 | if (!empty($this->locale) && preg_match('/^\w{2}[_\-]\w{2}/', $this->locale)) { |
227 | $length = ($this->feedType == self::$FEED_RSS) ? 5 : 2; | 230 | $length = ($this->feedType === self::$FEED_RSS) ? 5 : 2; |
228 | return str_replace('_', '-', substr($this->locale, 0, $length)); | 231 | return str_replace('_', '-', substr($this->locale, 0, $length)); |
229 | } | 232 | } |
230 | return ($this->feedType == self::$FEED_RSS) ? 'en-en' : 'en'; | 233 | return ($this->feedType === self::$FEED_RSS) ? 'en-en' : 'en'; |
231 | } | 234 | } |
232 | 235 | ||
233 | /** | 236 | /** |
@@ -287,7 +290,7 @@ class FeedBuilder | |||
287 | } | 290 | } |
288 | 291 | ||
289 | $intNb = intval($this->userInput['nb']); | 292 | $intNb = intval($this->userInput['nb']); |
290 | if (! is_int($intNb) || $intNb == 0) { | 293 | if (!is_int($intNb) || $intNb == 0) { |
291 | return self::$DEFAULT_NB_LINKS; | 294 | return self::$DEFAULT_NB_LINKS; |
292 | } | 295 | } |
293 | 296 | ||
diff --git a/application/Base64Url.php b/application/http/Base64Url.php index 54d0fcd5..33fa7c1f 100644 --- a/application/Base64Url.php +++ b/application/http/Base64Url.php | |||
@@ -1,6 +1,6 @@ | |||
1 | <?php | 1 | <?php |
2 | 2 | ||
3 | namespace Shaarli; | 3 | namespace Shaarli\Http; |
4 | 4 | ||
5 | /** | 5 | /** |
6 | * URL-safe Base64 operations | 6 | * URL-safe Base64 operations |
diff --git a/application/HttpUtils.php b/application/http/HttpUtils.php index 9c438160..2ea9195d 100644 --- a/application/HttpUtils.php +++ b/application/http/HttpUtils.php | |||
@@ -1,4 +1,7 @@ | |||
1 | <?php | 1 | <?php |
2 | |||
3 | use Shaarli\Http\Url; | ||
4 | |||
2 | /** | 5 | /** |
3 | * GET an HTTP URL to retrieve its content | 6 | * GET an HTTP URL to retrieve its content |
4 | * Uses the cURL library or a fallback method | 7 | * Uses the cURL library or a fallback method |
@@ -38,7 +41,7 @@ function get_http_response($url, $timeout = 30, $maxBytes = 4194304, $curlWriteF | |||
38 | $cleanUrl = $urlObj->idnToAscii(); | 41 | $cleanUrl = $urlObj->idnToAscii(); |
39 | 42 | ||
40 | if (!filter_var($cleanUrl, FILTER_VALIDATE_URL) || !$urlObj->isHttp()) { | 43 | if (!filter_var($cleanUrl, FILTER_VALIDATE_URL) || !$urlObj->isHttp()) { |
41 | return array(array(0 => 'Invalid HTTP Url'), false); | 44 | return array(array(0 => 'Invalid HTTP UrlUtils'), false); |
42 | } | 45 | } |
43 | 46 | ||
44 | $userAgent = | 47 | $userAgent = |
diff --git a/application/Url.php b/application/http/Url.php index 3b7f19c2..90444a2f 100644 --- a/application/Url.php +++ b/application/http/Url.php | |||
@@ -1,91 +1,6 @@ | |||
1 | <?php | 1 | <?php |
2 | /** | ||
3 | * Converts an array-represented URL to a string | ||
4 | * | ||
5 | * Source: http://php.net/manual/en/function.parse-url.php#106731 | ||
6 | * | ||
7 | * @see http://php.net/manual/en/function.parse-url.php | ||
8 | * | ||
9 | * @param array $parsedUrl an array-represented URL | ||
10 | * | ||
11 | * @return string the string representation of the URL | ||
12 | */ | ||
13 | function unparse_url($parsedUrl) | ||
14 | { | ||
15 | $scheme = isset($parsedUrl['scheme']) ? $parsedUrl['scheme'].'://' : ''; | ||
16 | $host = isset($parsedUrl['host']) ? $parsedUrl['host'] : ''; | ||
17 | $port = isset($parsedUrl['port']) ? ':'.$parsedUrl['port'] : ''; | ||
18 | $user = isset($parsedUrl['user']) ? $parsedUrl['user'] : ''; | ||
19 | $pass = isset($parsedUrl['pass']) ? ':'.$parsedUrl['pass'] : ''; | ||
20 | $pass = ($user || $pass) ? "$pass@" : ''; | ||
21 | $path = isset($parsedUrl['path']) ? $parsedUrl['path'] : ''; | ||
22 | $query = isset($parsedUrl['query']) ? '?'.$parsedUrl['query'] : ''; | ||
23 | $fragment = isset($parsedUrl['fragment']) ? '#'.$parsedUrl['fragment'] : ''; | ||
24 | 2 | ||
25 | return "$scheme$user$pass$host$port$path$query$fragment"; | 3 | namespace Shaarli\Http; |
26 | } | ||
27 | |||
28 | /** | ||
29 | * Removes undesired query parameters and fragments | ||
30 | * | ||
31 | * @param string url Url to be cleaned | ||
32 | * | ||
33 | * @return string the string representation of this URL after cleanup | ||
34 | */ | ||
35 | function cleanup_url($url) | ||
36 | { | ||
37 | $obj_url = new Url($url); | ||
38 | return $obj_url->cleanup(); | ||
39 | } | ||
40 | |||
41 | /** | ||
42 | * Get URL scheme. | ||
43 | * | ||
44 | * @param string url Url for which the scheme is requested | ||
45 | * | ||
46 | * @return mixed the URL scheme or false if none is provided. | ||
47 | */ | ||
48 | function get_url_scheme($url) | ||
49 | { | ||
50 | $obj_url = new Url($url); | ||
51 | return $obj_url->getScheme(); | ||
52 | } | ||
53 | |||
54 | /** | ||
55 | * Adds a trailing slash at the end of URL if necessary. | ||
56 | * | ||
57 | * @param string $url URL to check/edit. | ||
58 | * | ||
59 | * @return string $url URL with a end trailing slash. | ||
60 | */ | ||
61 | function add_trailing_slash($url) | ||
62 | { | ||
63 | return $url . (!endsWith($url, '/') ? '/' : ''); | ||
64 | } | ||
65 | |||
66 | /** | ||
67 | * Replace not whitelisted protocols by 'http://' from given URL. | ||
68 | * | ||
69 | * @param string $url URL to clean | ||
70 | * @param array $protocols List of allowed protocols (aside from http(s)). | ||
71 | * | ||
72 | * @return string URL with allowed protocol | ||
73 | */ | ||
74 | function whitelist_protocols($url, $protocols) | ||
75 | { | ||
76 | if (startsWith($url, '?') || startsWith($url, '/')) { | ||
77 | return $url; | ||
78 | } | ||
79 | $protocols = array_merge(['http', 'https'], $protocols); | ||
80 | $protocol = preg_match('#^(\w+):/?/?#', $url, $match); | ||
81 | // Protocol not allowed: we remove it and replace it with http | ||
82 | if ($protocol === 1 && ! in_array($match[1], $protocols)) { | ||
83 | $url = str_replace($match[0], 'http://', $url); | ||
84 | } elseif ($protocol !== 1) { | ||
85 | $url = 'http://' . $url; | ||
86 | } | ||
87 | return $url; | ||
88 | } | ||
89 | 4 | ||
90 | /** | 5 | /** |
91 | * URL representation and cleanup utilities | 6 | * URL representation and cleanup utilities |
@@ -182,7 +97,7 @@ class Url | |||
182 | } | 97 | } |
183 | return $input; | 98 | return $input; |
184 | } | 99 | } |
185 | 100 | ||
186 | /** | 101 | /** |
187 | * Returns a string representation of this URL | 102 | * Returns a string representation of this URL |
188 | */ | 103 | */ |
@@ -196,7 +111,7 @@ class Url | |||
196 | */ | 111 | */ |
197 | protected function cleanupQuery() | 112 | protected function cleanupQuery() |
198 | { | 113 | { |
199 | if (! isset($this->parts['query'])) { | 114 | if (!isset($this->parts['query'])) { |
200 | return; | 115 | return; |
201 | } | 116 | } |
202 | 117 | ||
@@ -224,7 +139,7 @@ class Url | |||
224 | */ | 139 | */ |
225 | protected function cleanupFragment() | 140 | protected function cleanupFragment() |
226 | { | 141 | { |
227 | if (! isset($this->parts['fragment'])) { | 142 | if (!isset($this->parts['fragment'])) { |
228 | return; | 143 | return; |
229 | } | 144 | } |
230 | 145 | ||
@@ -257,7 +172,7 @@ class Url | |||
257 | public function idnToAscii() | 172 | public function idnToAscii() |
258 | { | 173 | { |
259 | $out = $this->cleanup(); | 174 | $out = $this->cleanup(); |
260 | if (! function_exists('idn_to_ascii') || ! isset($this->parts['host'])) { | 175 | if (!function_exists('idn_to_ascii') || !isset($this->parts['host'])) { |
261 | return $out; | 176 | return $out; |
262 | } | 177 | } |
263 | $asciiHost = idn_to_ascii($this->parts['host'], 0, INTL_IDNA_VARIANT_UTS46); | 178 | $asciiHost = idn_to_ascii($this->parts['host'], 0, INTL_IDNA_VARIANT_UTS46); |
@@ -291,7 +206,7 @@ class Url | |||
291 | } | 206 | } |
292 | 207 | ||
293 | /** | 208 | /** |
294 | * Test if the Url is an HTTP one. | 209 | * Test if the UrlUtils is an HTTP one. |
295 | * | 210 | * |
296 | * @return true is HTTP, false otherwise. | 211 | * @return true is HTTP, false otherwise. |
297 | */ | 212 | */ |
diff --git a/application/http/UrlUtils.php b/application/http/UrlUtils.php new file mode 100644 index 00000000..4bc84b82 --- /dev/null +++ b/application/http/UrlUtils.php | |||
@@ -0,0 +1,88 @@ | |||
1 | <?php | ||
2 | /** | ||
3 | * Converts an array-represented URL to a string | ||
4 | * | ||
5 | * Source: http://php.net/manual/en/function.parse-url.php#106731 | ||
6 | * | ||
7 | * @see http://php.net/manual/en/function.parse-url.php | ||
8 | * | ||
9 | * @param array $parsedUrl an array-represented URL | ||
10 | * | ||
11 | * @return string the string representation of the URL | ||
12 | */ | ||
13 | function unparse_url($parsedUrl) | ||
14 | { | ||
15 | $scheme = isset($parsedUrl['scheme']) ? $parsedUrl['scheme'].'://' : ''; | ||
16 | $host = isset($parsedUrl['host']) ? $parsedUrl['host'] : ''; | ||
17 | $port = isset($parsedUrl['port']) ? ':'.$parsedUrl['port'] : ''; | ||
18 | $user = isset($parsedUrl['user']) ? $parsedUrl['user'] : ''; | ||
19 | $pass = isset($parsedUrl['pass']) ? ':'.$parsedUrl['pass'] : ''; | ||
20 | $pass = ($user || $pass) ? "$pass@" : ''; | ||
21 | $path = isset($parsedUrl['path']) ? $parsedUrl['path'] : ''; | ||
22 | $query = isset($parsedUrl['query']) ? '?'.$parsedUrl['query'] : ''; | ||
23 | $fragment = isset($parsedUrl['fragment']) ? '#'.$parsedUrl['fragment'] : ''; | ||
24 | |||
25 | return "$scheme$user$pass$host$port$path$query$fragment"; | ||
26 | } | ||
27 | |||
28 | /** | ||
29 | * Removes undesired query parameters and fragments | ||
30 | * | ||
31 | * @param string url UrlUtils to be cleaned | ||
32 | * | ||
33 | * @return string the string representation of this URL after cleanup | ||
34 | */ | ||
35 | function cleanup_url($url) | ||
36 | { | ||
37 | $obj_url = new \Shaarli\Http\Url($url); | ||
38 | return $obj_url->cleanup(); | ||
39 | } | ||
40 | |||
41 | /** | ||
42 | * Get URL scheme. | ||
43 | * | ||
44 | * @param string url UrlUtils for which the scheme is requested | ||
45 | * | ||
46 | * @return mixed the URL scheme or false if none is provided. | ||
47 | */ | ||
48 | function get_url_scheme($url) | ||
49 | { | ||
50 | $obj_url = new \Shaarli\Http\Url($url); | ||
51 | return $obj_url->getScheme(); | ||
52 | } | ||
53 | |||
54 | /** | ||
55 | * Adds a trailing slash at the end of URL if necessary. | ||
56 | * | ||
57 | * @param string $url URL to check/edit. | ||
58 | * | ||
59 | * @return string $url URL with a end trailing slash. | ||
60 | */ | ||
61 | function add_trailing_slash($url) | ||
62 | { | ||
63 | return $url . (!endsWith($url, '/') ? '/' : ''); | ||
64 | } | ||
65 | |||
66 | /** | ||
67 | * Replace not whitelisted protocols by 'http://' from given URL. | ||
68 | * | ||
69 | * @param string $url URL to clean | ||
70 | * @param array $protocols List of allowed protocols (aside from http(s)). | ||
71 | * | ||
72 | * @return string URL with allowed protocol | ||
73 | */ | ||
74 | function whitelist_protocols($url, $protocols) | ||
75 | { | ||
76 | if (startsWith($url, '?') || startsWith($url, '/')) { | ||
77 | return $url; | ||
78 | } | ||
79 | $protocols = array_merge(['http', 'https'], $protocols); | ||
80 | $protocol = preg_match('#^(\w+):/?/?#', $url, $match); | ||
81 | // Protocol not allowed: we remove it and replace it with http | ||
82 | if ($protocol === 1 && ! in_array($match[1], $protocols)) { | ||
83 | $url = str_replace($match[0], 'http://', $url); | ||
84 | } elseif ($protocol !== 1) { | ||
85 | $url = 'http://' . $url; | ||
86 | } | ||
87 | return $url; | ||
88 | } | ||
diff --git a/application/NetscapeBookmarkUtils.php b/application/netscape/NetscapeBookmarkUtils.php index 84dd2b20..2fb1a4a6 100644 --- a/application/NetscapeBookmarkUtils.php +++ b/application/netscape/NetscapeBookmarkUtils.php | |||
@@ -1,9 +1,16 @@ | |||
1 | <?php | 1 | <?php |
2 | 2 | ||
3 | namespace Shaarli\Netscape; | ||
4 | |||
5 | use DateTime; | ||
6 | use DateTimeZone; | ||
7 | use Exception; | ||
8 | use Katzgrau\KLogger\Logger; | ||
3 | use Psr\Log\LogLevel; | 9 | use Psr\Log\LogLevel; |
10 | use Shaarli\Bookmark\LinkDB; | ||
4 | use Shaarli\Config\ConfigManager; | 11 | use Shaarli\Config\ConfigManager; |
12 | use Shaarli\History; | ||
5 | use Shaarli\NetscapeBookmarkParser\NetscapeBookmarkParser; | 13 | use Shaarli\NetscapeBookmarkParser\NetscapeBookmarkParser; |
6 | use Katzgrau\KLogger\Logger; | ||
7 | 14 | ||
8 | /** | 15 | /** |
9 | * Utilities to import and export bookmarks using the Netscape format | 16 | * Utilities to import and export bookmarks using the Netscape format |
@@ -31,8 +38,8 @@ class NetscapeBookmarkUtils | |||
31 | public static function filterAndFormat($linkDb, $selection, $prependNoteUrl, $indexUrl) | 38 | public static function filterAndFormat($linkDb, $selection, $prependNoteUrl, $indexUrl) |
32 | { | 39 | { |
33 | // see tpl/export.html for possible values | 40 | // see tpl/export.html for possible values |
34 | if (! in_array($selection, array('all', 'public', 'private'))) { | 41 | if (!in_array($selection, array('all', 'public', 'private'))) { |
35 | throw new Exception(t('Invalid export selection:') .' "'.$selection.'"'); | 42 | throw new Exception(t('Invalid export selection:') . ' "' . $selection . '"'); |
36 | } | 43 | } |
37 | 44 | ||
38 | $bookmarkLinks = array(); | 45 | $bookmarkLinks = array(); |
@@ -84,7 +91,7 @@ class NetscapeBookmarkUtils | |||
84 | $status .= vsprintf( | 91 | $status .= vsprintf( |
85 | t( | 92 | t( |
86 | 'was successfully processed in %d seconds: ' | 93 | 'was successfully processed in %d seconds: ' |
87 | .'%d links imported, %d links overwritten, %d links skipped.' | 94 | . '%d links imported, %d links overwritten, %d links skipped.' |
88 | ), | 95 | ), |
89 | [$duration, $importCount, $overwriteCount, $skipCount] | 96 | [$duration, $importCount, $overwriteCount, $skipCount] |
90 | ); | 97 | ); |
@@ -95,11 +102,11 @@ class NetscapeBookmarkUtils | |||
95 | /** | 102 | /** |
96 | * Imports Web bookmarks from an uploaded Netscape bookmark dump | 103 | * Imports Web bookmarks from an uploaded Netscape bookmark dump |
97 | * | 104 | * |
98 | * @param array $post Server $_POST parameters | 105 | * @param array $post Server $_POST parameters |
99 | * @param array $files Server $_FILES parameters | 106 | * @param array $files Server $_FILES parameters |
100 | * @param LinkDB $linkDb Loaded LinkDB instance | 107 | * @param LinkDB $linkDb Loaded LinkDB instance |
101 | * @param ConfigManager $conf instance | 108 | * @param ConfigManager $conf instance |
102 | * @param History $history History instance | 109 | * @param History $history History instance |
103 | * | 110 | * |
104 | * @return string Summary of the bookmark import status | 111 | * @return string Summary of the bookmark import status |
105 | */ | 112 | */ |
@@ -115,7 +122,7 @@ class NetscapeBookmarkUtils | |||
115 | } | 122 | } |
116 | 123 | ||
117 | // Overwrite existing links? | 124 | // Overwrite existing links? |
118 | $overwrite = ! empty($post['overwrite']); | 125 | $overwrite = !empty($post['overwrite']); |
119 | 126 | ||
120 | // Add tags to all imported links? | 127 | // Add tags to all imported links? |
121 | if (empty($post['default_tags'])) { | 128 | if (empty($post['default_tags'])) { |
@@ -138,7 +145,7 @@ class NetscapeBookmarkUtils | |||
138 | ); | 145 | ); |
139 | $logger = new Logger( | 146 | $logger = new Logger( |
140 | $conf->get('resource.data_dir'), | 147 | $conf->get('resource.data_dir'), |
141 | ! $conf->get('dev.debug') ? LogLevel::INFO : LogLevel::DEBUG, | 148 | !$conf->get('dev.debug') ? LogLevel::INFO : LogLevel::DEBUG, |
142 | [ | 149 | [ |
143 | 'prefix' => 'import.', | 150 | 'prefix' => 'import.', |
144 | 'extension' => 'log', | 151 | 'extension' => 'log', |
@@ -193,7 +200,7 @@ class NetscapeBookmarkUtils | |||
193 | } | 200 | } |
194 | 201 | ||
195 | // Add a new link - @ used for UNIX timestamps | 202 | // Add a new link - @ used for UNIX timestamps |
196 | $newLinkDate = new DateTime('@'.strval($bkm['time'])); | 203 | $newLinkDate = new DateTime('@' . strval($bkm['time'])); |
197 | $newLinkDate->setTimezone(new DateTimeZone(date_default_timezone_get())); | 204 | $newLinkDate->setTimezone(new DateTimeZone(date_default_timezone_get())); |
198 | $newLink['created'] = $newLinkDate; | 205 | $newLink['created'] = $newLinkDate; |
199 | $newLink['id'] = $linkDb->getNextId(); | 206 | $newLink['id'] = $linkDb->getNextId(); |
diff --git a/application/PluginManager.php b/application/plugin/PluginManager.php index 1ed4db4b..f7b24a8e 100644 --- a/application/PluginManager.php +++ b/application/plugin/PluginManager.php | |||
@@ -1,4 +1,8 @@ | |||
1 | <?php | 1 | <?php |
2 | namespace Shaarli\Plugin; | ||
3 | |||
4 | use Shaarli\Config\ConfigManager; | ||
5 | use Shaarli\Plugin\Exception\PluginFileNotFoundException; | ||
2 | 6 | ||
3 | /** | 7 | /** |
4 | * Class PluginManager | 8 | * Class PluginManager |
@@ -9,12 +13,14 @@ class PluginManager | |||
9 | { | 13 | { |
10 | /** | 14 | /** |
11 | * List of authorized plugins from configuration file. | 15 | * List of authorized plugins from configuration file. |
16 | * | ||
12 | * @var array $authorizedPlugins | 17 | * @var array $authorizedPlugins |
13 | */ | 18 | */ |
14 | private $authorizedPlugins; | 19 | private $authorizedPlugins; |
15 | 20 | ||
16 | /** | 21 | /** |
17 | * List of loaded plugins. | 22 | * List of loaded plugins. |
23 | * | ||
18 | * @var array $loadedPlugins | 24 | * @var array $loadedPlugins |
19 | */ | 25 | */ |
20 | private $loadedPlugins = array(); | 26 | private $loadedPlugins = array(); |
@@ -31,12 +37,14 @@ class PluginManager | |||
31 | 37 | ||
32 | /** | 38 | /** |
33 | * Plugins subdirectory. | 39 | * Plugins subdirectory. |
40 | * | ||
34 | * @var string $PLUGINS_PATH | 41 | * @var string $PLUGINS_PATH |
35 | */ | 42 | */ |
36 | public static $PLUGINS_PATH = 'plugins'; | 43 | public static $PLUGINS_PATH = 'plugins'; |
37 | 44 | ||
38 | /** | 45 | /** |
39 | * Plugins meta files extension. | 46 | * Plugins meta files extension. |
47 | * | ||
40 | * @var string $META_EXT | 48 | * @var string $META_EXT |
41 | */ | 49 | */ |
42 | public static $META_EXT = 'meta'; | 50 | public static $META_EXT = 'meta'; |
@@ -84,9 +92,9 @@ class PluginManager | |||
84 | /** | 92 | /** |
85 | * Execute all plugins registered hook. | 93 | * Execute all plugins registered hook. |
86 | * | 94 | * |
87 | * @param string $hook name of the hook to trigger. | 95 | * @param string $hook name of the hook to trigger. |
88 | * @param array $data list of data to manipulate passed by reference. | 96 | * @param array $data list of data to manipulate passed by reference. |
89 | * @param array $params additional parameters such as page target. | 97 | * @param array $params additional parameters such as page target. |
90 | * | 98 | * |
91 | * @return void | 99 | * @return void |
92 | */ | 100 | */ |
@@ -118,7 +126,7 @@ class PluginManager | |||
118 | * @param string $pluginName plugin's name. | 126 | * @param string $pluginName plugin's name. |
119 | * | 127 | * |
120 | * @return void | 128 | * @return void |
121 | * @throws PluginFileNotFoundException - plugin files not found. | 129 | * @throws \Shaarli\Plugin\Exception\PluginFileNotFoundException - plugin files not found. |
122 | */ | 130 | */ |
123 | private function loadPlugin($dir, $pluginName) | 131 | private function loadPlugin($dir, $pluginName) |
124 | { | 132 | { |
@@ -204,8 +212,8 @@ class PluginManager | |||
204 | 212 | ||
205 | $metaData[$plugin]['parameters'][$param]['value'] = ''; | 213 | $metaData[$plugin]['parameters'][$param]['value'] = ''; |
206 | // Optional parameter description in parameter.PARAM_NAME= | 214 | // Optional parameter description in parameter.PARAM_NAME= |
207 | if (isset($metaData[$plugin]['parameter.'. $param])) { | 215 | if (isset($metaData[$plugin]['parameter.' . $param])) { |
208 | $metaData[$plugin]['parameters'][$param]['desc'] = t($metaData[$plugin]['parameter.'. $param]); | 216 | $metaData[$plugin]['parameters'][$param]['desc'] = t($metaData[$plugin]['parameter.' . $param]); |
209 | } | 217 | } |
210 | } | 218 | } |
211 | } | 219 | } |
@@ -223,22 +231,3 @@ class PluginManager | |||
223 | return $this->errors; | 231 | return $this->errors; |
224 | } | 232 | } |
225 | } | 233 | } |
226 | |||
227 | /** | ||
228 | * Class PluginFileNotFoundException | ||
229 | * | ||
230 | * Raise when plugin files can't be found. | ||
231 | */ | ||
232 | class PluginFileNotFoundException extends Exception | ||
233 | { | ||
234 | /** | ||
235 | * Construct exception with plugin name. | ||
236 | * Generate message. | ||
237 | * | ||
238 | * @param string $pluginName name of the plugin not found | ||
239 | */ | ||
240 | public function __construct($pluginName) | ||
241 | { | ||
242 | $this->message = sprintf(t('Plugin "%s" files not found.'), $pluginName); | ||
243 | } | ||
244 | } | ||
diff --git a/application/plugin/exception/PluginFileNotFoundException.php b/application/plugin/exception/PluginFileNotFoundException.php new file mode 100644 index 00000000..e5386f02 --- /dev/null +++ b/application/plugin/exception/PluginFileNotFoundException.php | |||
@@ -0,0 +1,23 @@ | |||
1 | <?php | ||
2 | namespace Shaarli\Plugin\Exception; | ||
3 | |||
4 | use Exception; | ||
5 | |||
6 | /** | ||
7 | * Class PluginFileNotFoundException | ||
8 | * | ||
9 | * Raise when plugin files can't be found. | ||
10 | */ | ||
11 | class PluginFileNotFoundException extends Exception | ||
12 | { | ||
13 | /** | ||
14 | * Construct exception with plugin name. | ||
15 | * Generate message. | ||
16 | * | ||
17 | * @param string $pluginName name of the plugin not found | ||
18 | */ | ||
19 | public function __construct($pluginName) | ||
20 | { | ||
21 | $this->message = sprintf(t('Plugin "%s" files not found.'), $pluginName); | ||
22 | } | ||
23 | } | ||
diff --git a/application/PageBuilder.php b/application/render/PageBuilder.php index 2ca95832..0569b67f 100644 --- a/application/PageBuilder.php +++ b/application/render/PageBuilder.php | |||
@@ -1,5 +1,11 @@ | |||
1 | <?php | 1 | <?php |
2 | 2 | ||
3 | namespace Shaarli\Render; | ||
4 | |||
5 | use Exception; | ||
6 | use RainTPL; | ||
7 | use Shaarli\ApplicationUtils; | ||
8 | use Shaarli\Bookmark\LinkDB; | ||
3 | use Shaarli\Config\ConfigManager; | 9 | use Shaarli\Config\ConfigManager; |
4 | use Shaarli\Thumbnailer; | 10 | use Shaarli\Thumbnailer; |
5 | 11 | ||
@@ -37,7 +43,9 @@ class PageBuilder | |||
37 | */ | 43 | */ |
38 | protected $token; | 44 | protected $token; |
39 | 45 | ||
40 | /** @var bool $isLoggedIn Whether the user is logged in **/ | 46 | /** |
47 | * @var bool $isLoggedIn Whether the user is logged in | ||
48 | */ | ||
41 | protected $isLoggedIn = false; | 49 | protected $isLoggedIn = false; |
42 | 50 | ||
43 | /** | 51 | /** |
@@ -101,7 +109,7 @@ class PageBuilder | |||
101 | ApplicationUtils::getVersionHash(SHAARLI_VERSION, $this->conf->get('credentials.salt')) | 109 | ApplicationUtils::getVersionHash(SHAARLI_VERSION, $this->conf->get('credentials.salt')) |
102 | ); | 110 | ); |
103 | $this->tpl->assign('index_url', index_url($_SERVER)); | 111 | $this->tpl->assign('index_url', index_url($_SERVER)); |
104 | $visibility = ! empty($_SESSION['visibility']) ? $_SESSION['visibility'] : ''; | 112 | $visibility = !empty($_SESSION['visibility']) ? $_SESSION['visibility'] : ''; |
105 | $this->tpl->assign('visibility', $visibility); | 113 | $this->tpl->assign('visibility', $visibility); |
106 | $this->tpl->assign('untaggedonly', !empty($_SESSION['untaggedonly'])); | 114 | $this->tpl->assign('untaggedonly', !empty($_SESSION['untaggedonly'])); |
107 | $this->tpl->assign('pagetitle', $this->conf->get('general.title', 'Shaarli')); | 115 | $this->tpl->assign('pagetitle', $this->conf->get('general.title', 'Shaarli')); |
@@ -126,7 +134,7 @@ class PageBuilder | |||
126 | $this->tpl->assign('thumbnails_width', $this->conf->get('thumbnails.width')); | 134 | $this->tpl->assign('thumbnails_width', $this->conf->get('thumbnails.width')); |
127 | $this->tpl->assign('thumbnails_height', $this->conf->get('thumbnails.height')); | 135 | $this->tpl->assign('thumbnails_height', $this->conf->get('thumbnails.height')); |
128 | 136 | ||
129 | if (! empty($_SESSION['warnings'])) { | 137 | if (!empty($_SESSION['warnings'])) { |
130 | $this->tpl->assign('global_warnings', $_SESSION['warnings']); | 138 | $this->tpl->assign('global_warnings', $_SESSION['warnings']); |
131 | unset($_SESSION['warnings']); | 139 | unset($_SESSION['warnings']); |
132 | } | 140 | } |
@@ -189,16 +197,16 @@ class PageBuilder | |||
189 | 197 | ||
190 | /** | 198 | /** |
191 | * Render a 404 page (uses the template : tpl/404.tpl) | 199 | * Render a 404 page (uses the template : tpl/404.tpl) |
192 | * usage : $PAGE->render404('The link was deleted') | 200 | * usage: $PAGE->render404('The link was deleted') |
193 | * | 201 | * |
194 | * @param string $message A messate to display what is not found | 202 | * @param string $message A message to display what is not found |
195 | */ | 203 | */ |
196 | public function render404($message = '') | 204 | public function render404($message = '') |
197 | { | 205 | { |
198 | if (empty($message)) { | 206 | if (empty($message)) { |
199 | $message = t('The page you are trying to reach does not exist or has been deleted.'); | 207 | $message = t('The page you are trying to reach does not exist or has been deleted.'); |
200 | } | 208 | } |
201 | header($_SERVER['SERVER_PROTOCOL'] .' '. t('404 Not Found')); | 209 | header($_SERVER['SERVER_PROTOCOL'] . ' ' . t('404 Not Found')); |
202 | $this->tpl->assign('error_message', $message); | 210 | $this->tpl->assign('error_message', $message); |
203 | $this->renderPage('404'); | 211 | $this->renderPage('404'); |
204 | } | 212 | } |
diff --git a/application/ThemeUtils.php b/application/render/ThemeUtils.php index 16f2f6a2..86096c64 100644 --- a/application/ThemeUtils.php +++ b/application/render/ThemeUtils.php | |||
@@ -1,6 +1,6 @@ | |||
1 | <?php | 1 | <?php |
2 | 2 | ||
3 | namespace Shaarli; | 3 | namespace Shaarli\Render; |
4 | 4 | ||
5 | /** | 5 | /** |
6 | * Class ThemeUtils | 6 | * Class ThemeUtils |
diff --git a/application/Updater.php b/application/updater/Updater.php index 6b94c5e3..f12e3516 100644 --- a/application/Updater.php +++ b/application/updater/Updater.php | |||
@@ -1,11 +1,24 @@ | |||
1 | <?php | 1 | <?php |
2 | |||
3 | namespace Shaarli\Updater; | ||
4 | |||
5 | use Exception; | ||
6 | use RainTPL; | ||
7 | use ReflectionClass; | ||
8 | use ReflectionException; | ||
9 | use ReflectionMethod; | ||
10 | use Shaarli\ApplicationUtils; | ||
11 | use Shaarli\Bookmark\LinkDB; | ||
12 | use Shaarli\Bookmark\LinkFilter; | ||
2 | use Shaarli\Config\ConfigJson; | 13 | use Shaarli\Config\ConfigJson; |
3 | use Shaarli\Config\ConfigPhp; | ||
4 | use Shaarli\Config\ConfigManager; | 14 | use Shaarli\Config\ConfigManager; |
15 | use Shaarli\Config\ConfigPhp; | ||
16 | use Shaarli\Exceptions\IOException; | ||
5 | use Shaarli\Thumbnailer; | 17 | use Shaarli\Thumbnailer; |
18 | use Shaarli\Updater\Exception\UpdaterException; | ||
6 | 19 | ||
7 | /** | 20 | /** |
8 | * Class Updater. | 21 | * Class updater. |
9 | * Used to update stuff when a new Shaarli's version is reached. | 22 | * Used to update stuff when a new Shaarli's version is reached. |
10 | * Update methods are ran only once, and the stored in a JSON file. | 23 | * Update methods are ran only once, and the stored in a JSON file. |
11 | */ | 24 | */ |
@@ -83,12 +96,12 @@ class Updater | |||
83 | } | 96 | } |
84 | 97 | ||
85 | if ($this->methods === null) { | 98 | if ($this->methods === null) { |
86 | throw new UpdaterException(t('Couldn\'t retrieve Updater class methods.')); | 99 | throw new UpdaterException(t('Couldn\'t retrieve updater class methods.')); |
87 | } | 100 | } |
88 | 101 | ||
89 | foreach ($this->methods as $method) { | 102 | foreach ($this->methods as $method) { |
90 | // Not an update method or already done, pass. | 103 | // Not an update method or already done, pass. |
91 | if (! startsWith($method->getName(), 'updateMethod') | 104 | if (!startsWith($method->getName(), 'updateMethod') |
92 | || in_array($method->getName(), $this->doneUpdates) | 105 | || in_array($method->getName(), $this->doneUpdates) |
93 | ) { | 106 | ) { |
94 | continue; | 107 | continue; |
@@ -139,7 +152,7 @@ class Updater | |||
139 | } | 152 | } |
140 | } | 153 | } |
141 | $this->conf->write($this->isLoggedIn); | 154 | $this->conf->write($this->isLoggedIn); |
142 | unlink($this->conf->get('resource.data_dir').'/options.php'); | 155 | unlink($this->conf->get('resource.data_dir') . '/options.php'); |
143 | } | 156 | } |
144 | 157 | ||
145 | return true; | 158 | return true; |
@@ -174,10 +187,10 @@ class Updater | |||
174 | $subConfig = array('config', 'plugins'); | 187 | $subConfig = array('config', 'plugins'); |
175 | foreach ($subConfig as $sub) { | 188 | foreach ($subConfig as $sub) { |
176 | foreach ($oldConfig[$sub] as $key => $value) { | 189 | foreach ($oldConfig[$sub] as $key => $value) { |
177 | if (isset($legacyMap[$sub .'.'. $key])) { | 190 | if (isset($legacyMap[$sub . '.' . $key])) { |
178 | $configKey = $legacyMap[$sub .'.'. $key]; | 191 | $configKey = $legacyMap[$sub . '.' . $key]; |
179 | } else { | 192 | } else { |
180 | $configKey = $sub .'.'. $key; | 193 | $configKey = $sub . '.' . $key; |
181 | } | 194 | } |
182 | $this->conf->set($configKey, $value); | 195 | $this->conf->set($configKey, $value); |
183 | } | 196 | } |
@@ -233,7 +246,7 @@ class Updater | |||
233 | return true; | 246 | return true; |
234 | } | 247 | } |
235 | 248 | ||
236 | $save = $this->conf->get('resource.data_dir') .'/datastore.'. date('YmdHis') .'.php'; | 249 | $save = $this->conf->get('resource.data_dir') . '/datastore.' . date('YmdHis') . '.php'; |
237 | copy($this->conf->get('resource.datastore'), $save); | 250 | copy($this->conf->get('resource.datastore'), $save); |
238 | 251 | ||
239 | $links = array(); | 252 | $links = array(); |
@@ -307,7 +320,7 @@ class Updater | |||
307 | // We run the update only if this folder still contains the template files. | 320 | // We run the update only if this folder still contains the template files. |
308 | $tplDir = $this->conf->get('resource.raintpl_tpl'); | 321 | $tplDir = $this->conf->get('resource.raintpl_tpl'); |
309 | $tplFile = $tplDir . '/linklist.html'; | 322 | $tplFile = $tplDir . '/linklist.html'; |
310 | if (! file_exists($tplFile)) { | 323 | if (!file_exists($tplFile)) { |
311 | return true; | 324 | return true; |
312 | } | 325 | } |
313 | 326 | ||
@@ -331,7 +344,7 @@ class Updater | |||
331 | */ | 344 | */ |
332 | public function updateMethodMoveUserCss() | 345 | public function updateMethodMoveUserCss() |
333 | { | 346 | { |
334 | if (! is_file('inc/user.css')) { | 347 | if (!is_file('inc/user.css')) { |
335 | return true; | 348 | return true; |
336 | } | 349 | } |
337 | 350 | ||
@@ -367,11 +380,11 @@ class Updater | |||
367 | */ | 380 | */ |
368 | public function updateMethodPiwikUrl() | 381 | public function updateMethodPiwikUrl() |
369 | { | 382 | { |
370 | if (! $this->conf->exists('plugins.PIWIK_URL') || startsWith($this->conf->get('plugins.PIWIK_URL'), 'http')) { | 383 | if (!$this->conf->exists('plugins.PIWIK_URL') || startsWith($this->conf->get('plugins.PIWIK_URL'), 'http')) { |
371 | return true; | 384 | return true; |
372 | } | 385 | } |
373 | 386 | ||
374 | $this->conf->set('plugins.PIWIK_URL', 'http://'. $this->conf->get('plugins.PIWIK_URL')); | 387 | $this->conf->set('plugins.PIWIK_URL', 'http://' . $this->conf->get('plugins.PIWIK_URL')); |
375 | $this->conf->write($this->isLoggedIn); | 388 | $this->conf->write($this->isLoggedIn); |
376 | 389 | ||
377 | return true; | 390 | return true; |
@@ -481,11 +494,11 @@ class Updater | |||
481 | return true; | 494 | return true; |
482 | } | 495 | } |
483 | 496 | ||
484 | if (! $this->conf->exists('general.download_max_size')) { | 497 | if (!$this->conf->exists('general.download_max_size')) { |
485 | $this->conf->set('general.download_max_size', 1024*1024*4); | 498 | $this->conf->set('general.download_max_size', 1024 * 1024 * 4); |
486 | } | 499 | } |
487 | 500 | ||
488 | if (! $this->conf->exists('general.download_timeout')) { | 501 | if (!$this->conf->exists('general.download_timeout')) { |
489 | $this->conf->set('general.download_timeout', 30); | 502 | $this->conf->set('general.download_timeout', 30); |
490 | } | 503 | } |
491 | 504 | ||
@@ -538,96 +551,3 @@ class Updater | |||
538 | return true; | 551 | return true; |
539 | } | 552 | } |
540 | } | 553 | } |
541 | |||
542 | /** | ||
543 | * Class UpdaterException. | ||
544 | */ | ||
545 | class UpdaterException extends Exception | ||
546 | { | ||
547 | /** | ||
548 | * @var string Method where the error occurred. | ||
549 | */ | ||
550 | protected $method; | ||
551 | |||
552 | /** | ||
553 | * @var Exception The parent exception. | ||
554 | */ | ||
555 | protected $previous; | ||
556 | |||
557 | /** | ||
558 | * Constructor. | ||
559 | * | ||
560 | * @param string $message Force the error message if set. | ||
561 | * @param string $method Method where the error occurred. | ||
562 | * @param Exception|bool $previous Parent exception. | ||
563 | */ | ||
564 | public function __construct($message = '', $method = '', $previous = false) | ||
565 | { | ||
566 | $this->method = $method; | ||
567 | $this->previous = $previous; | ||
568 | $this->message = $this->buildMessage($message); | ||
569 | } | ||
570 | |||
571 | /** | ||
572 | * Build the exception error message. | ||
573 | * | ||
574 | * @param string $message Optional given error message. | ||
575 | * | ||
576 | * @return string The built error message. | ||
577 | */ | ||
578 | private function buildMessage($message) | ||
579 | { | ||
580 | $out = ''; | ||
581 | if (! empty($message)) { | ||
582 | $out .= $message . PHP_EOL; | ||
583 | } | ||
584 | |||
585 | if (! empty($this->method)) { | ||
586 | $out .= t('An error occurred while running the update ') . $this->method . PHP_EOL; | ||
587 | } | ||
588 | |||
589 | if (! empty($this->previous)) { | ||
590 | $out .= ' '. $this->previous->getMessage(); | ||
591 | } | ||
592 | |||
593 | return $out; | ||
594 | } | ||
595 | } | ||
596 | |||
597 | /** | ||
598 | * Read the updates file, and return already done updates. | ||
599 | * | ||
600 | * @param string $updatesFilepath Updates file path. | ||
601 | * | ||
602 | * @return array Already done update methods. | ||
603 | */ | ||
604 | function read_updates_file($updatesFilepath) | ||
605 | { | ||
606 | if (! empty($updatesFilepath) && is_file($updatesFilepath)) { | ||
607 | $content = file_get_contents($updatesFilepath); | ||
608 | if (! empty($content)) { | ||
609 | return explode(';', $content); | ||
610 | } | ||
611 | } | ||
612 | return array(); | ||
613 | } | ||
614 | |||
615 | /** | ||
616 | * Write updates file. | ||
617 | * | ||
618 | * @param string $updatesFilepath Updates file path. | ||
619 | * @param array $updates Updates array to write. | ||
620 | * | ||
621 | * @throws Exception Couldn't write version number. | ||
622 | */ | ||
623 | function write_updates_file($updatesFilepath, $updates) | ||
624 | { | ||
625 | if (empty($updatesFilepath)) { | ||
626 | throw new Exception(t('Updates file path is not set, can\'t write updates.')); | ||
627 | } | ||
628 | |||
629 | $res = file_put_contents($updatesFilepath, implode(';', $updates)); | ||
630 | if ($res === false) { | ||
631 | throw new Exception(t('Unable to write updates in '. $updatesFilepath . '.')); | ||
632 | } | ||
633 | } | ||
diff --git a/application/updater/UpdaterUtils.php b/application/updater/UpdaterUtils.php new file mode 100644 index 00000000..34d4f422 --- /dev/null +++ b/application/updater/UpdaterUtils.php | |||
@@ -0,0 +1,39 @@ | |||
1 | <?php | ||
2 | |||
3 | /** | ||
4 | * Read the updates file, and return already done updates. | ||
5 | * | ||
6 | * @param string $updatesFilepath Updates file path. | ||
7 | * | ||
8 | * @return array Already done update methods. | ||
9 | */ | ||
10 | function read_updates_file($updatesFilepath) | ||
11 | { | ||
12 | if (! empty($updatesFilepath) && is_file($updatesFilepath)) { | ||
13 | $content = file_get_contents($updatesFilepath); | ||
14 | if (! empty($content)) { | ||
15 | return explode(';', $content); | ||
16 | } | ||
17 | } | ||
18 | return array(); | ||
19 | } | ||
20 | |||
21 | /** | ||
22 | * Write updates file. | ||
23 | * | ||
24 | * @param string $updatesFilepath Updates file path. | ||
25 | * @param array $updates Updates array to write. | ||
26 | * | ||
27 | * @throws Exception Couldn't write version number. | ||
28 | */ | ||
29 | function write_updates_file($updatesFilepath, $updates) | ||
30 | { | ||
31 | if (empty($updatesFilepath)) { | ||
32 | throw new Exception(t('Updates file path is not set, can\'t write updates.')); | ||
33 | } | ||
34 | |||
35 | $res = file_put_contents($updatesFilepath, implode(';', $updates)); | ||
36 | if ($res === false) { | ||
37 | throw new Exception(t('Unable to write updates in '. $updatesFilepath . '.')); | ||
38 | } | ||
39 | } | ||
diff --git a/application/updater/exception/UpdaterException.php b/application/updater/exception/UpdaterException.php new file mode 100644 index 00000000..20aceccf --- /dev/null +++ b/application/updater/exception/UpdaterException.php | |||
@@ -0,0 +1,60 @@ | |||
1 | <?php | ||
2 | |||
3 | namespace Shaarli\Updater\Exception; | ||
4 | |||
5 | use Exception; | ||
6 | |||
7 | /** | ||
8 | * Class UpdaterException. | ||
9 | */ | ||
10 | class UpdaterException extends Exception | ||
11 | { | ||
12 | /** | ||
13 | * @var string Method where the error occurred. | ||
14 | */ | ||
15 | protected $method; | ||
16 | |||
17 | /** | ||
18 | * @var Exception The parent exception. | ||
19 | */ | ||
20 | protected $previous; | ||
21 | |||
22 | /** | ||
23 | * Constructor. | ||
24 | * | ||
25 | * @param string $message Force the error message if set. | ||
26 | * @param string $method Method where the error occurred. | ||
27 | * @param Exception|bool $previous Parent exception. | ||
28 | */ | ||
29 | public function __construct($message = '', $method = '', $previous = false) | ||
30 | { | ||
31 | $this->method = $method; | ||
32 | $this->previous = $previous; | ||
33 | $this->message = $this->buildMessage($message); | ||
34 | } | ||
35 | |||
36 | /** | ||
37 | * Build the exception error message. | ||
38 | * | ||
39 | * @param string $message Optional given error message. | ||
40 | * | ||
41 | * @return string The built error message. | ||
42 | */ | ||
43 | private function buildMessage($message) | ||
44 | { | ||
45 | $out = ''; | ||
46 | if (!empty($message)) { | ||
47 | $out .= $message . PHP_EOL; | ||
48 | } | ||
49 | |||
50 | if (!empty($this->method)) { | ||
51 | $out .= t('An error occurred while running the update ') . $this->method . PHP_EOL; | ||
52 | } | ||
53 | |||
54 | if (!empty($this->previous)) { | ||
55 | $out .= ' ' . $this->previous->getMessage(); | ||
56 | } | ||
57 | |||
58 | return $out; | ||
59 | } | ||
60 | } | ||