diff options
-rw-r--r-- | application/ApplicationUtils.php | 93 | ||||
-rw-r--r-- | application/FileUtils.php | 56 | ||||
-rw-r--r-- | application/front/controller/admin/ServerController.php | 87 | ||||
-rw-r--r-- | application/front/controller/visitor/BookmarkListController.php | 28 | ||||
-rw-r--r-- | application/front/controller/visitor/InstallController.php | 12 | ||||
-rw-r--r-- | assets/default/scss/shaarli.scss | 56 | ||||
-rw-r--r-- | inc/languages/fr/LC_MESSAGES/shaarli.po | 294 | ||||
-rw-r--r-- | index.php | 2 | ||||
-rw-r--r-- | tests/ApplicationUtilsTest.php | 62 | ||||
-rw-r--r-- | tests/FileUtilsTest.php | 88 | ||||
-rw-r--r-- | tests/front/controller/admin/ServerControllerTest.php | 184 | ||||
-rw-r--r-- | tests/front/controller/visitor/InstallControllerTest.php | 9 | ||||
-rw-r--r-- | tpl/default/install.html | 10 | ||||
-rw-r--r-- | tpl/default/server.html | 129 | ||||
-rw-r--r-- | tpl/default/server.requirements.html | 68 | ||||
-rw-r--r-- | tpl/default/tools.html | 14 |
16 files changed, 1087 insertions, 105 deletions
diff --git a/application/ApplicationUtils.php b/application/ApplicationUtils.php index 3aa21829..bd1c7cf3 100644 --- a/application/ApplicationUtils.php +++ b/application/ApplicationUtils.php | |||
@@ -14,8 +14,9 @@ class ApplicationUtils | |||
14 | */ | 14 | */ |
15 | public static $VERSION_FILE = 'shaarli_version.php'; | 15 | public static $VERSION_FILE = 'shaarli_version.php'; |
16 | 16 | ||
17 | private static $GIT_URL = 'https://raw.githubusercontent.com/shaarli/Shaarli'; | 17 | public static $GITHUB_URL = 'https://github.com/shaarli/Shaarli'; |
18 | private static $GIT_BRANCHES = array('latest', 'stable'); | 18 | public static $GIT_RAW_URL = 'https://raw.githubusercontent.com/shaarli/Shaarli'; |
19 | public static $GIT_BRANCHES = array('latest', 'stable'); | ||
19 | private static $VERSION_START_TAG = '<?php /* '; | 20 | private static $VERSION_START_TAG = '<?php /* '; |
20 | private static $VERSION_END_TAG = ' */ ?>'; | 21 | private static $VERSION_END_TAG = ' */ ?>'; |
21 | 22 | ||
@@ -125,7 +126,7 @@ class ApplicationUtils | |||
125 | // Late Static Binding allows overriding within tests | 126 | // Late Static Binding allows overriding within tests |
126 | // See http://php.net/manual/en/language.oop5.late-static-bindings.php | 127 | // See http://php.net/manual/en/language.oop5.late-static-bindings.php |
127 | $latestVersion = static::getVersion( | 128 | $latestVersion = static::getVersion( |
128 | self::$GIT_URL . '/' . $branch . '/' . self::$VERSION_FILE | 129 | self::$GIT_RAW_URL . '/' . $branch . '/' . self::$VERSION_FILE |
129 | ); | 130 | ); |
130 | 131 | ||
131 | if (!$latestVersion) { | 132 | if (!$latestVersion) { |
@@ -171,35 +172,45 @@ class ApplicationUtils | |||
171 | /** | 172 | /** |
172 | * Checks Shaarli has the proper access permissions to its resources | 173 | * Checks Shaarli has the proper access permissions to its resources |
173 | * | 174 | * |
174 | * @param ConfigManager $conf Configuration Manager instance. | 175 | * @param ConfigManager $conf Configuration Manager instance. |
176 | * @param bool $minimalMode In minimal mode we only check permissions to be able to display a template. | ||
177 | * Currently we only need to be able to read the theme and write in raintpl cache. | ||
175 | * | 178 | * |
176 | * @return array A list of the detected configuration issues | 179 | * @return array A list of the detected configuration issues |
177 | */ | 180 | */ |
178 | public static function checkResourcePermissions($conf) | 181 | public static function checkResourcePermissions(ConfigManager $conf, bool $minimalMode = false): array |
179 | { | 182 | { |
180 | $errors = array(); | 183 | $errors = []; |
181 | $rainTplDir = rtrim($conf->get('resource.raintpl_tpl'), '/'); | 184 | $rainTplDir = rtrim($conf->get('resource.raintpl_tpl'), '/'); |
182 | 185 | ||
183 | // Check script and template directories are readable | 186 | // Check script and template directories are readable |
184 | foreach (array( | 187 | foreach ([ |
185 | 'application', | 188 | 'application', |
186 | 'inc', | 189 | 'inc', |
187 | 'plugins', | 190 | 'plugins', |
188 | $rainTplDir, | 191 | $rainTplDir, |
189 | $rainTplDir . '/' . $conf->get('resource.theme'), | 192 | $rainTplDir . '/' . $conf->get('resource.theme'), |
190 | ) as $path) { | 193 | ] as $path) { |
191 | if (!is_readable(realpath($path))) { | 194 | if (!is_readable(realpath($path))) { |
192 | $errors[] = '"' . $path . '" ' . t('directory is not readable'); | 195 | $errors[] = '"' . $path . '" ' . t('directory is not readable'); |
193 | } | 196 | } |
194 | } | 197 | } |
195 | 198 | ||
196 | // Check cache and data directories are readable and writable | 199 | // Check cache and data directories are readable and writable |
197 | foreach (array( | 200 | if ($minimalMode) { |
198 | $conf->get('resource.thumbnails_cache'), | 201 | $folders = [ |
199 | $conf->get('resource.data_dir'), | 202 | $conf->get('resource.raintpl_tmp'), |
200 | $conf->get('resource.page_cache'), | 203 | ]; |
201 | $conf->get('resource.raintpl_tmp'), | 204 | } else { |
202 | ) as $path) { | 205 | $folders = [ |
206 | $conf->get('resource.thumbnails_cache'), | ||
207 | $conf->get('resource.data_dir'), | ||
208 | $conf->get('resource.page_cache'), | ||
209 | $conf->get('resource.raintpl_tmp'), | ||
210 | ]; | ||
211 | } | ||
212 | |||
213 | foreach ($folders as $path) { | ||
203 | if (!is_readable(realpath($path))) { | 214 | if (!is_readable(realpath($path))) { |
204 | $errors[] = '"' . $path . '" ' . t('directory is not readable'); | 215 | $errors[] = '"' . $path . '" ' . t('directory is not readable'); |
205 | } | 216 | } |
@@ -208,6 +219,10 @@ class ApplicationUtils | |||
208 | } | 219 | } |
209 | } | 220 | } |
210 | 221 | ||
222 | if ($minimalMode) { | ||
223 | return $errors; | ||
224 | } | ||
225 | |||
211 | // Check configuration files are readable and writable | 226 | // Check configuration files are readable and writable |
212 | foreach (array( | 227 | foreach (array( |
213 | $conf->getConfigFileExt(), | 228 | $conf->getConfigFileExt(), |
@@ -246,4 +261,54 @@ class ApplicationUtils | |||
246 | { | 261 | { |
247 | return hash_hmac('sha256', $currentVersion, $salt); | 262 | return hash_hmac('sha256', $currentVersion, $salt); |
248 | } | 263 | } |
264 | |||
265 | /** | ||
266 | * Get a list of PHP extensions used by Shaarli. | ||
267 | * | ||
268 | * @return array[] List of extension with following keys: | ||
269 | * - name: extension name | ||
270 | * - required: whether the extension is required to use Shaarli | ||
271 | * - desc: short description of extension usage in Shaarli | ||
272 | * - loaded: whether the extension is properly loaded or not | ||
273 | */ | ||
274 | public static function getPhpExtensionsRequirement(): array | ||
275 | { | ||
276 | $extensions = [ | ||
277 | ['name' => 'json', 'required' => true, 'desc' => t('Configuration parsing')], | ||
278 | ['name' => 'simplexml', 'required' => true, 'desc' => t('Slim Framework (routing, etc.)')], | ||
279 | ['name' => 'mbstring', 'required' => true, 'desc' => t('Multibyte (Unicode) string support')], | ||
280 | ['name' => 'gd', 'required' => false, 'desc' => t('Required to use thumbnails')], | ||
281 | ['name' => 'intl', 'required' => false, 'desc' => t('Localized text sorting (e.g. e->รจ->f)')], | ||
282 | ['name' => 'curl', 'required' => false, 'desc' => t('Better retrieval of bookmark metadata and thumbnail')], | ||
283 | ['name' => 'gettext', 'required' => false, 'desc' => t('Use the translation system in gettext mode')], | ||
284 | ['name' => 'ldap', 'required' => false, 'desc' => t('Login using LDAP server')], | ||
285 | ]; | ||
286 | |||
287 | foreach ($extensions as &$extension) { | ||
288 | $extension['loaded'] = extension_loaded($extension['name']); | ||
289 | } | ||
290 | |||
291 | return $extensions; | ||
292 | } | ||
293 | |||
294 | /** | ||
295 | * Return the EOL date of given PHP version. If the version is unknown, | ||
296 | * we return today + 2 years. | ||
297 | * | ||
298 | * @param string $fullVersion PHP version, e.g. 7.4.7 | ||
299 | * | ||
300 | * @return string Date format: YYYY-MM-DD | ||
301 | */ | ||
302 | public static function getPhpEol(string $fullVersion): string | ||
303 | { | ||
304 | preg_match('/(\d+\.\d+)\.\d+/', $fullVersion, $matches); | ||
305 | |||
306 | return [ | ||
307 | '7.1' => '2019-12-01', | ||
308 | '7.2' => '2020-11-30', | ||
309 | '7.3' => '2021-12-06', | ||
310 | '7.4' => '2022-11-28', | ||
311 | '8.0' => '2023-12-01', | ||
312 | ][$matches[1]] ?? (new \DateTime('+2 year'))->format('Y-m-d'); | ||
313 | } | ||
249 | } | 314 | } |
diff --git a/application/FileUtils.php b/application/FileUtils.php index 30560bfc..3f940751 100644 --- a/application/FileUtils.php +++ b/application/FileUtils.php | |||
@@ -81,4 +81,60 @@ class FileUtils | |||
81 | ) | 81 | ) |
82 | ); | 82 | ); |
83 | } | 83 | } |
84 | |||
85 | /** | ||
86 | * Recursively deletes a folder content, and deletes itself optionally. | ||
87 | * If an excluded file is found, folders won't be deleted. | ||
88 | * | ||
89 | * Additional security: raise an exception if it tries to delete a folder outside of Shaarli directory. | ||
90 | * | ||
91 | * @param string $path | ||
92 | * @param bool $selfDelete Delete the provided folder if true, only its content if false. | ||
93 | * @param array $exclude | ||
94 | */ | ||
95 | public static function clearFolder(string $path, bool $selfDelete, array $exclude = []): bool | ||
96 | { | ||
97 | $skipped = false; | ||
98 | |||
99 | if (!is_dir($path)) { | ||
100 | throw new IOException(t('Provided path is not a directory.')); | ||
101 | } | ||
102 | |||
103 | if (!static::isPathInShaarliFolder($path)) { | ||
104 | throw new IOException(t('Trying to delete a folder outside of Shaarli path.')); | ||
105 | } | ||
106 | |||
107 | foreach (new \DirectoryIterator($path) as $file) { | ||
108 | if($file->isDot()) { | ||
109 | continue; | ||
110 | } | ||
111 | |||
112 | if (in_array($file->getBasename(), $exclude, true)) { | ||
113 | $skipped = true; | ||
114 | continue; | ||
115 | } | ||
116 | |||
117 | if ($file->isFile()) { | ||
118 | unlink($file->getPathname()); | ||
119 | } elseif($file->isDir()) { | ||
120 | $skipped = static::clearFolder($file->getRealPath(), true, $exclude) || $skipped; | ||
121 | } | ||
122 | } | ||
123 | |||
124 | if ($selfDelete && !$skipped) { | ||
125 | rmdir($path); | ||
126 | } | ||
127 | |||
128 | return $skipped; | ||
129 | } | ||
130 | |||
131 | /** | ||
132 | * Checks that the given path is inside Shaarli directory. | ||
133 | */ | ||
134 | public static function isPathInShaarliFolder(string $path): bool | ||
135 | { | ||
136 | $rootDirectory = dirname(dirname(__FILE__)); | ||
137 | |||
138 | return strpos(realpath($path), $rootDirectory) !== false; | ||
139 | } | ||
84 | } | 140 | } |
diff --git a/application/front/controller/admin/ServerController.php b/application/front/controller/admin/ServerController.php new file mode 100644 index 00000000..85654a43 --- /dev/null +++ b/application/front/controller/admin/ServerController.php | |||
@@ -0,0 +1,87 @@ | |||
1 | <?php | ||
2 | |||
3 | declare(strict_types=1); | ||
4 | |||
5 | namespace Shaarli\Front\Controller\Admin; | ||
6 | |||
7 | use Shaarli\ApplicationUtils; | ||
8 | use Shaarli\FileUtils; | ||
9 | use Slim\Http\Request; | ||
10 | use Slim\Http\Response; | ||
11 | |||
12 | /** | ||
13 | * Slim controller used to handle Server administration page, and actions. | ||
14 | */ | ||
15 | class ServerController extends ShaarliAdminController | ||
16 | { | ||
17 | /** @var string Cache type - main - by default pagecache/ and tmp/ */ | ||
18 | protected const CACHE_MAIN = 'main'; | ||
19 | |||
20 | /** @var string Cache type - thumbnails - by default cache/ */ | ||
21 | protected const CACHE_THUMB = 'thumbnails'; | ||
22 | |||
23 | /** | ||
24 | * GET /admin/server - Display page Server administration | ||
25 | */ | ||
26 | public function index(Request $request, Response $response): Response | ||
27 | { | ||
28 | $latestVersion = 'v' . ApplicationUtils::getVersion( | ||
29 | ApplicationUtils::$GIT_RAW_URL . '/latest/' . ApplicationUtils::$VERSION_FILE | ||
30 | ); | ||
31 | $currentVersion = ApplicationUtils::getVersion('./shaarli_version.php'); | ||
32 | $currentVersion = $currentVersion === 'dev' ? $currentVersion : 'v' . $currentVersion; | ||
33 | $phpEol = new \DateTimeImmutable(ApplicationUtils::getPhpEol(PHP_VERSION)); | ||
34 | |||
35 | $this->assignView('php_version', PHP_VERSION); | ||
36 | $this->assignView('php_eol', format_date($phpEol, false)); | ||
37 | $this->assignView('php_has_reached_eol', $phpEol < new \DateTimeImmutable()); | ||
38 | $this->assignView('php_extensions', ApplicationUtils::getPhpExtensionsRequirement()); | ||
39 | $this->assignView('permissions', ApplicationUtils::checkResourcePermissions($this->container->conf)); | ||
40 | $this->assignView('release_url', ApplicationUtils::$GITHUB_URL . '/releases/tag/' . $latestVersion); | ||
41 | $this->assignView('latest_version', $latestVersion); | ||
42 | $this->assignView('current_version', $currentVersion); | ||
43 | $this->assignView('thumbnails_mode', $this->container->conf->get('thumbnails.mode')); | ||
44 | $this->assignView('index_url', index_url($this->container->environment)); | ||
45 | $this->assignView('client_ip', client_ip_id($this->container->environment)); | ||
46 | $this->assignView('trusted_proxies', $this->container->conf->get('security.trusted_proxies', [])); | ||
47 | |||
48 | $this->assignView( | ||
49 | 'pagetitle', | ||
50 | t('Server administration') . ' - ' . $this->container->conf->get('general.title', 'Shaarli') | ||
51 | ); | ||
52 | |||
53 | return $response->write($this->render('server')); | ||
54 | } | ||
55 | |||
56 | /** | ||
57 | * GET /admin/clear-cache?type={$type} - Action to trigger cache folder clearing (either main or thumbnails). | ||
58 | */ | ||
59 | public function clearCache(Request $request, Response $response): Response | ||
60 | { | ||
61 | $exclude = ['.htaccess']; | ||
62 | |||
63 | if ($request->getQueryParam('type') === static::CACHE_THUMB) { | ||
64 | $folders = [$this->container->conf->get('resource.thumbnails_cache')]; | ||
65 | |||
66 | $this->saveWarningMessage( | ||
67 | t('Thumbnails cache has been cleared.') . ' ' . | ||
68 | '<a href="'. $this->container->basePath .'/admin/thumbnails">' . t('Please synchronize them.') .'</a>' | ||
69 | ); | ||
70 | } else { | ||
71 | $folders = [ | ||
72 | $this->container->conf->get('resource.page_cache'), | ||
73 | $this->container->conf->get('resource.raintpl_tmp'), | ||
74 | ]; | ||
75 | |||
76 | $this->saveSuccessMessage(t('Shaarli\'s cache folder has been cleared!')); | ||
77 | } | ||
78 | |||
79 | // Make sure that we don't delete root cache folder | ||
80 | $folders = array_map('realpath', array_values(array_filter(array_map('trim', $folders)))); | ||
81 | foreach ($folders as $folder) { | ||
82 | FileUtils::clearFolder($folder, false, $exclude); | ||
83 | } | ||
84 | |||
85 | return $this->redirect($response, '/admin/server'); | ||
86 | } | ||
87 | } | ||
diff --git a/application/front/controller/visitor/BookmarkListController.php b/application/front/controller/visitor/BookmarkListController.php index a8019ead..5267c8f5 100644 --- a/application/front/controller/visitor/BookmarkListController.php +++ b/application/front/controller/visitor/BookmarkListController.php | |||
@@ -169,16 +169,24 @@ class BookmarkListController extends ShaarliVisitorController | |||
169 | */ | 169 | */ |
170 | protected function updateThumbnail(Bookmark $bookmark, bool $writeDatastore = true): bool | 170 | protected function updateThumbnail(Bookmark $bookmark, bool $writeDatastore = true): bool |
171 | { | 171 | { |
172 | // Logged in, not async retrieval, thumbnails enabled, and thumbnail should be updated | 172 | if (false === $this->container->loginManager->isLoggedIn()) { |
173 | if ($this->container->loginManager->isLoggedIn() | 173 | return false; |
174 | && true !== $this->container->conf->get('general.enable_async_metadata', true) | 174 | } |
175 | && $this->container->conf->get('thumbnails.mode', Thumbnailer::MODE_NONE) !== Thumbnailer::MODE_NONE | 175 | |
176 | && $bookmark->shouldUpdateThumbnail() | 176 | // If thumbnail should be updated, we reset it to null |
177 | ) { | 177 | if ($bookmark->shouldUpdateThumbnail()) { |
178 | $bookmark->setThumbnail($this->container->thumbnailer->get($bookmark->getUrl())); | 178 | $bookmark->setThumbnail(null); |
179 | $this->container->bookmarkService->set($bookmark, $writeDatastore); | 179 | |
180 | 180 | // Requires an update, not async retrieval, thumbnails enabled | |
181 | return true; | 181 | if ($bookmark->shouldUpdateThumbnail() |
182 | && true !== $this->container->conf->get('general.enable_async_metadata', true) | ||
183 | && $this->container->conf->get('thumbnails.mode', Thumbnailer::MODE_NONE) !== Thumbnailer::MODE_NONE | ||
184 | ) { | ||
185 | $bookmark->setThumbnail($this->container->thumbnailer->get($bookmark->getUrl())); | ||
186 | $this->container->bookmarkService->set($bookmark, $writeDatastore); | ||
187 | |||
188 | return true; | ||
189 | } | ||
182 | } | 190 | } |
183 | 191 | ||
184 | return false; | 192 | return false; |
diff --git a/application/front/controller/visitor/InstallController.php b/application/front/controller/visitor/InstallController.php index 7cb32777..564a5777 100644 --- a/application/front/controller/visitor/InstallController.php +++ b/application/front/controller/visitor/InstallController.php | |||
@@ -53,6 +53,16 @@ class InstallController extends ShaarliVisitorController | |||
53 | $this->assignView('cities', $cities); | 53 | $this->assignView('cities', $cities); |
54 | $this->assignView('languages', Languages::getAvailableLanguages()); | 54 | $this->assignView('languages', Languages::getAvailableLanguages()); |
55 | 55 | ||
56 | $phpEol = new \DateTimeImmutable(ApplicationUtils::getPhpEol(PHP_VERSION)); | ||
57 | |||
58 | $this->assignView('php_version', PHP_VERSION); | ||
59 | $this->assignView('php_eol', format_date($phpEol, false)); | ||
60 | $this->assignView('php_has_reached_eol', $phpEol < new \DateTimeImmutable()); | ||
61 | $this->assignView('php_extensions', ApplicationUtils::getPhpExtensionsRequirement()); | ||
62 | $this->assignView('permissions', ApplicationUtils::checkResourcePermissions($this->container->conf)); | ||
63 | |||
64 | $this->assignView('pagetitle', t('Install Shaarli')); | ||
65 | |||
56 | return $response->write($this->render('install')); | 66 | return $response->write($this->render('install')); |
57 | } | 67 | } |
58 | 68 | ||
@@ -150,7 +160,7 @@ class InstallController extends ShaarliVisitorController | |||
150 | protected function checkPermissions(): bool | 160 | protected function checkPermissions(): bool |
151 | { | 161 | { |
152 | // Ensure Shaarli has proper access to its resources | 162 | // Ensure Shaarli has proper access to its resources |
153 | $errors = ApplicationUtils::checkResourcePermissions($this->container->conf); | 163 | $errors = ApplicationUtils::checkResourcePermissions($this->container->conf, true); |
154 | if (empty($errors)) { | 164 | if (empty($errors)) { |
155 | return true; | 165 | return true; |
156 | } | 166 | } |
diff --git a/assets/default/scss/shaarli.scss b/assets/default/scss/shaarli.scss index 286ac83b..7dc61903 100644 --- a/assets/default/scss/shaarli.scss +++ b/assets/default/scss/shaarli.scss | |||
@@ -1047,7 +1047,7 @@ body, | |||
1047 | } | 1047 | } |
1048 | 1048 | ||
1049 | table { | 1049 | table { |
1050 | margin: auto; | 1050 | margin: 10px auto 25px auto; |
1051 | width: 90%; | 1051 | width: 90%; |
1052 | 1052 | ||
1053 | .order { | 1053 | .order { |
@@ -1696,6 +1696,60 @@ form { | |||
1696 | } | 1696 | } |
1697 | } | 1697 | } |
1698 | 1698 | ||
1699 | // SERVER PAGE | ||
1700 | |||
1701 | .server-tables-page, | ||
1702 | .server-tables { | ||
1703 | .window-subtitle { | ||
1704 | &::before { | ||
1705 | display: block; | ||
1706 | margin: 8px auto; | ||
1707 | background: linear-gradient(to right, var(--background-color), $dark-grey, var(--background-color)); | ||
1708 | width: 50%; | ||
1709 | height: 1px; | ||
1710 | content: ''; | ||
1711 | } | ||
1712 | } | ||
1713 | |||
1714 | .server-row { | ||
1715 | p { | ||
1716 | height: 25px; | ||
1717 | padding: 0 10px; | ||
1718 | } | ||
1719 | } | ||
1720 | |||
1721 | .server-label { | ||
1722 | text-align: right; | ||
1723 | font-weight: bold; | ||
1724 | } | ||
1725 | |||
1726 | i { | ||
1727 | &.fa-color-green { | ||
1728 | color: $main-green; | ||
1729 | } | ||
1730 | |||
1731 | &.fa-color-orange { | ||
1732 | color: $orange; | ||
1733 | } | ||
1734 | |||
1735 | &.fa-color-red { | ||
1736 | color: $red; | ||
1737 | } | ||
1738 | } | ||
1739 | |||
1740 | @media screen and (max-width: 64em) { | ||
1741 | .server-label { | ||
1742 | text-align: center; | ||
1743 | } | ||
1744 | |||
1745 | .server-row { | ||
1746 | p { | ||
1747 | text-align: center; | ||
1748 | } | ||
1749 | } | ||
1750 | } | ||
1751 | } | ||
1752 | |||
1699 | // Print rules | 1753 | // Print rules |
1700 | @media print { | 1754 | @media print { |
1701 | .shaarli-menu { | 1755 | .shaarli-menu { |
diff --git a/inc/languages/fr/LC_MESSAGES/shaarli.po b/inc/languages/fr/LC_MESSAGES/shaarli.po index f7baedfb..db6bfa3e 100644 --- a/inc/languages/fr/LC_MESSAGES/shaarli.po +++ b/inc/languages/fr/LC_MESSAGES/shaarli.po | |||
@@ -1,8 +1,8 @@ | |||
1 | msgid "" | 1 | msgid "" |
2 | msgstr "" | 2 | msgstr "" |
3 | "Project-Id-Version: Shaarli\n" | 3 | "Project-Id-Version: Shaarli\n" |
4 | "POT-Creation-Date: 2020-10-16 20:01+0200\n" | 4 | "POT-Creation-Date: 2020-10-21 15:00+0200\n" |
5 | "PO-Revision-Date: 2020-10-16 20:02+0200\n" | 5 | "PO-Revision-Date: 2020-10-21 15:06+0200\n" |
6 | "Last-Translator: \n" | 6 | "Last-Translator: \n" |
7 | "Language-Team: Shaarli\n" | 7 | "Language-Team: Shaarli\n" |
8 | "Language: fr_FR\n" | 8 | "Language: fr_FR\n" |
@@ -20,7 +20,7 @@ msgstr "" | |||
20 | "X-Poedit-SearchPath-3: init.php\n" | 20 | "X-Poedit-SearchPath-3: init.php\n" |
21 | "X-Poedit-SearchPath-4: plugins\n" | 21 | "X-Poedit-SearchPath-4: plugins\n" |
22 | 22 | ||
23 | #: application/ApplicationUtils.php:161 | 23 | #: application/ApplicationUtils.php:162 |
24 | #, php-format | 24 | #, php-format |
25 | msgid "" | 25 | msgid "" |
26 | "Your PHP version is obsolete! Shaarli requires at least PHP %s, and thus " | 26 | "Your PHP version is obsolete! Shaarli requires at least PHP %s, and thus " |
@@ -31,22 +31,62 @@ msgstr "" | |||
31 | "peut donc pas fonctionner. Votre version de PHP a des failles de sรฉcuritรฉs " | 31 | "peut donc pas fonctionner. Votre version de PHP a des failles de sรฉcuritรฉs " |
32 | "connues et devrait รชtre mise ร jour au plus tรดt." | 32 | "connues et devrait รชtre mise ร jour au plus tรดt." |
33 | 33 | ||
34 | #: application/ApplicationUtils.php:192 application/ApplicationUtils.php:204 | 34 | #: application/ApplicationUtils.php:195 application/ApplicationUtils.php:215 |
35 | msgid "directory is not readable" | 35 | msgid "directory is not readable" |
36 | msgstr "le rรฉpertoire n'est pas accessible en lecture" | 36 | msgstr "le rรฉpertoire n'est pas accessible en lecture" |
37 | 37 | ||
38 | #: application/ApplicationUtils.php:207 | 38 | #: application/ApplicationUtils.php:218 |
39 | msgid "directory is not writable" | 39 | msgid "directory is not writable" |
40 | msgstr "le rรฉpertoire n'est pas accessible en รฉcriture" | 40 | msgstr "le rรฉpertoire n'est pas accessible en รฉcriture" |
41 | 41 | ||
42 | #: application/ApplicationUtils.php:225 | 42 | #: application/ApplicationUtils.php:240 |
43 | msgid "file is not readable" | 43 | msgid "file is not readable" |
44 | msgstr "le fichier n'est pas accessible en lecture" | 44 | msgstr "le fichier n'est pas accessible en lecture" |
45 | 45 | ||
46 | #: application/ApplicationUtils.php:228 | 46 | #: application/ApplicationUtils.php:243 |
47 | msgid "file is not writable" | 47 | msgid "file is not writable" |
48 | msgstr "le fichier n'est pas accessible en รฉcriture" | 48 | msgstr "le fichier n'est pas accessible en รฉcriture" |
49 | 49 | ||
50 | #: application/ApplicationUtils.php:277 | ||
51 | msgid "Configuration parsing" | ||
52 | msgstr "Chargement de la configuration" | ||
53 | |||
54 | #: application/ApplicationUtils.php:278 | ||
55 | msgid "Slim Framework (routing, etc.)" | ||
56 | msgstr "Slim Framwork (routage, etc.)" | ||
57 | |||
58 | #: application/ApplicationUtils.php:279 | ||
59 | msgid "Multibyte (Unicode) string support" | ||
60 | msgstr "Support des chaรฎnes de caractรจre multibytes (Unicode)" | ||
61 | |||
62 | #: application/ApplicationUtils.php:280 | ||
63 | msgid "Required to use thumbnails" | ||
64 | msgstr "Obligatoire pour utiliser les miniatures" | ||
65 | |||
66 | #: application/ApplicationUtils.php:281 | ||
67 | msgid "Localized text sorting (e.g. e->รจ->f)" | ||
68 | msgstr "Tri des textes traduits (ex : e->รจ->f)" | ||
69 | |||
70 | #: application/ApplicationUtils.php:282 | ||
71 | msgid "Better retrieval of bookmark metadata and thumbnail" | ||
72 | msgstr "Meilleure rรฉcupรฉration des meta-donnรฉes des marque-pages et minatures" | ||
73 | |||
74 | #: application/ApplicationUtils.php:283 | ||
75 | msgid "Use the translation system in gettext mode" | ||
76 | msgstr "Utiliser le systรจme de traduction en mode gettext" | ||
77 | |||
78 | #: application/ApplicationUtils.php:284 | ||
79 | msgid "Login using LDAP server" | ||
80 | msgstr "Authentification via un serveur LDAP" | ||
81 | |||
82 | #: application/FileUtils.php:100 | ||
83 | msgid "Provided path is not a directory." | ||
84 | msgstr "Le chemin fourni n'est pas un dossier." | ||
85 | |||
86 | #: application/FileUtils.php:104 | ||
87 | msgid "Trying to delete a folder outside of Shaarli path." | ||
88 | msgstr "Tentative de supprimer un dossier en dehors du chemin de Shaarli." | ||
89 | |||
50 | #: application/History.php:179 | 90 | #: application/History.php:179 |
51 | msgid "History file isn't readable or writable" | 91 | msgid "History file isn't readable or writable" |
52 | msgstr "Le fichier d'historique n'est pas accessible en lecture ou en รฉcriture" | 92 | msgstr "Le fichier d'historique n'est pas accessible en lecture ou en รฉcriture" |
@@ -330,12 +370,13 @@ msgid "You have enabled or changed thumbnails mode." | |||
330 | msgstr "Vous avez activรฉ ou changรฉ le mode de miniatures." | 370 | msgstr "Vous avez activรฉ ou changรฉ le mode de miniatures." |
331 | 371 | ||
332 | #: application/front/controller/admin/ConfigureController.php:103 | 372 | #: application/front/controller/admin/ConfigureController.php:103 |
373 | #: application/front/controller/admin/ServerController.php:68 | ||
333 | #: application/legacy/LegacyUpdater.php:538 | 374 | #: application/legacy/LegacyUpdater.php:538 |
334 | msgid "Please synchronize them." | 375 | msgid "Please synchronize them." |
335 | msgstr "Merci de les synchroniser." | 376 | msgstr "Merci de les synchroniser." |
336 | 377 | ||
337 | #: application/front/controller/admin/ConfigureController.php:113 | 378 | #: application/front/controller/admin/ConfigureController.php:113 |
338 | #: application/front/controller/visitor/InstallController.php:136 | 379 | #: application/front/controller/visitor/InstallController.php:146 |
339 | msgid "Error while writing config file after configuration update." | 380 | msgid "Error while writing config file after configuration update." |
340 | msgstr "" | 381 | msgstr "" |
341 | "Une erreur s'est produite lors de la sauvegarde du fichier de configuration." | 382 | "Une erreur s'est produite lors de la sauvegarde du fichier de configuration." |
@@ -377,33 +418,33 @@ msgstr "" | |||
377 | msgid "Shaare a new link" | 418 | msgid "Shaare a new link" |
378 | msgstr "Partager un nouveau lien" | 419 | msgstr "Partager un nouveau lien" |
379 | 420 | ||
380 | #: application/front/controller/admin/ManageShaareController.php:78 | 421 | #: application/front/controller/admin/ManageShaareController.php:64 |
381 | msgid "Note: " | 422 | msgid "Note: " |
382 | msgstr "Note : " | 423 | msgstr "Note : " |
383 | 424 | ||
384 | #: application/front/controller/admin/ManageShaareController.php:109 | 425 | #: application/front/controller/admin/ManageShaareController.php:95 |
385 | #: application/front/controller/admin/ManageShaareController.php:206 | 426 | #: application/front/controller/admin/ManageShaareController.php:193 |
386 | #: application/front/controller/admin/ManageShaareController.php:275 | 427 | #: application/front/controller/admin/ManageShaareController.php:262 |
387 | #: application/front/controller/admin/ManageShaareController.php:315 | 428 | #: application/front/controller/admin/ManageShaareController.php:302 |
388 | #, php-format | 429 | #, php-format |
389 | msgid "Bookmark with identifier %s could not be found." | 430 | msgid "Bookmark with identifier %s could not be found." |
390 | msgstr "Le lien avec l'identifiant %s n'a pas pu รชtre trouvรฉ." | 431 | msgstr "Le lien avec l'identifiant %s n'a pas pu รชtre trouvรฉ." |
391 | 432 | ||
392 | #: application/front/controller/admin/ManageShaareController.php:194 | 433 | #: application/front/controller/admin/ManageShaareController.php:181 |
393 | #: application/front/controller/admin/ManageShaareController.php:252 | 434 | #: application/front/controller/admin/ManageShaareController.php:239 |
394 | msgid "Invalid bookmark ID provided." | 435 | msgid "Invalid bookmark ID provided." |
395 | msgstr "ID du lien non valide." | 436 | msgstr "ID du lien non valide." |
396 | 437 | ||
397 | #: application/front/controller/admin/ManageShaareController.php:260 | 438 | #: application/front/controller/admin/ManageShaareController.php:247 |
398 | msgid "Invalid visibility provided." | 439 | msgid "Invalid visibility provided." |
399 | msgstr "Visibilitรฉ du lien non valide." | 440 | msgstr "Visibilitรฉ du lien non valide." |
400 | 441 | ||
401 | #: application/front/controller/admin/ManageShaareController.php:363 | 442 | #: application/front/controller/admin/ManageShaareController.php:352 |
402 | #: tmp/linklist.b91ef64efc3688266305ea9b42e5017e.rtpl.php:171 | 443 | #: tmp/linklist.b91ef64efc3688266305ea9b42e5017e.rtpl.php:171 |
403 | msgid "Edit" | 444 | msgid "Edit" |
404 | msgstr "Modifier" | 445 | msgstr "Modifier" |
405 | 446 | ||
406 | #: application/front/controller/admin/ManageShaareController.php:366 | 447 | #: application/front/controller/admin/ManageShaareController.php:355 |
407 | #: tmp/page.header.b91ef64efc3688266305ea9b42e5017e.rtpl.php:28 | 448 | #: tmp/page.header.b91ef64efc3688266305ea9b42e5017e.rtpl.php:28 |
408 | #: tmp/page.header.cedf684561d925457130839629000a81.rtpl.php:28 | 449 | #: tmp/page.header.cedf684561d925457130839629000a81.rtpl.php:28 |
409 | msgid "Shaare" | 450 | msgid "Shaare" |
@@ -411,7 +452,7 @@ msgstr "Shaare" | |||
411 | 452 | ||
412 | #: application/front/controller/admin/ManageTagController.php:29 | 453 | #: application/front/controller/admin/ManageTagController.php:29 |
413 | #: tmp/changetag.b91ef64efc3688266305ea9b42e5017e.rtpl.php:13 | 454 | #: tmp/changetag.b91ef64efc3688266305ea9b42e5017e.rtpl.php:13 |
414 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:36 | 455 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:42 |
415 | msgid "Manage tags" | 456 | msgid "Manage tags" |
416 | msgstr "Gรฉrer les tags" | 457 | msgstr "Gรฉrer les tags" |
417 | 458 | ||
@@ -435,7 +476,7 @@ msgstr[1] "Le tag a รฉtรฉ renommรฉ dans %d liens." | |||
435 | 476 | ||
436 | #: application/front/controller/admin/PasswordController.php:28 | 477 | #: application/front/controller/admin/PasswordController.php:28 |
437 | #: tmp/changepassword.b91ef64efc3688266305ea9b42e5017e.rtpl.php:13 | 478 | #: tmp/changepassword.b91ef64efc3688266305ea9b42e5017e.rtpl.php:13 |
438 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:29 | 479 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:35 |
439 | msgid "Change password" | 480 | msgid "Change password" |
440 | msgstr "Modifier le mot de passe" | 481 | msgstr "Modifier le mot de passe" |
441 | 482 | ||
@@ -467,6 +508,20 @@ msgstr "" | |||
467 | "Une erreur s'est produite lors de la sauvegarde de la configuration des " | 508 | "Une erreur s'est produite lors de la sauvegarde de la configuration des " |
468 | "plugins : " | 509 | "plugins : " |
469 | 510 | ||
511 | #: application/front/controller/admin/ServerController.php:50 | ||
512 | #: tmp/server.b91ef64efc3688266305ea9b42e5017e.rtpl.php:14 | ||
513 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:28 | ||
514 | msgid "Server administration" | ||
515 | msgstr "Administration serveur" | ||
516 | |||
517 | #: application/front/controller/admin/ServerController.php:67 | ||
518 | msgid "Thumbnails cache has been cleared." | ||
519 | msgstr "Le cache des miniatures a รฉtรฉ vidรฉ." | ||
520 | |||
521 | #: application/front/controller/admin/ServerController.php:76 | ||
522 | msgid "Shaarli's cache folder has been cleared!" | ||
523 | msgstr "Le dossier de cache de Shaarli a รฉtรฉ vidรฉ !" | ||
524 | |||
470 | #: application/front/controller/admin/ThumbnailsController.php:37 | 525 | #: application/front/controller/admin/ThumbnailsController.php:37 |
471 | #: tmp/thumbnails.b91ef64efc3688266305ea9b42e5017e.rtpl.php:14 | 526 | #: tmp/thumbnails.b91ef64efc3688266305ea9b42e5017e.rtpl.php:14 |
472 | msgid "Thumbnails update" | 527 | msgid "Thumbnails update" |
@@ -502,9 +557,14 @@ msgstr "Une erreur inattendue s'est produite." | |||
502 | 557 | ||
503 | #: application/front/controller/visitor/ErrorNotFoundController.php:25 | 558 | #: application/front/controller/visitor/ErrorNotFoundController.php:25 |
504 | msgid "Requested page could not be found." | 559 | msgid "Requested page could not be found." |
505 | msgstr "" | 560 | msgstr "La page demandรฉe n'a pas pu รชtre trouvรฉe." |
506 | 561 | ||
507 | #: application/front/controller/visitor/InstallController.php:73 | 562 | #: application/front/controller/visitor/InstallController.php:64 |
563 | #: tmp/install.b91ef64efc3688266305ea9b42e5017e.rtpl.php:22 | ||
564 | msgid "Install Shaarli" | ||
565 | msgstr "Installation de Shaarli" | ||
566 | |||
567 | #: application/front/controller/visitor/InstallController.php:83 | ||
508 | #, php-format | 568 | #, php-format |
509 | msgid "" | 569 | msgid "" |
510 | "<pre>Sessions do not seem to work correctly on your server.<br>Make sure the " | 570 | "<pre>Sessions do not seem to work correctly on your server.<br>Make sure the " |
@@ -523,14 +583,14 @@ msgstr "" | |||
523 | "des cookies. Nous vous recommandons d'accรฉder ร votre serveur depuis son " | 583 | "des cookies. Nous vous recommandons d'accรฉder ร votre serveur depuis son " |
524 | "adresse IP ou un <em>Fully Qualified Domain Name</em>.<br>" | 584 | "adresse IP ou un <em>Fully Qualified Domain Name</em>.<br>" |
525 | 585 | ||
526 | #: application/front/controller/visitor/InstallController.php:144 | 586 | #: application/front/controller/visitor/InstallController.php:154 |
527 | msgid "" | 587 | msgid "" |
528 | "Shaarli is now configured. Please login and start shaaring your bookmarks!" | 588 | "Shaarli is now configured. Please login and start shaaring your bookmarks!" |
529 | msgstr "" | 589 | msgstr "" |
530 | "Shaarli est maintenant configurรฉ. Vous pouvez vous connecter et commencez ร " | 590 | "Shaarli est maintenant configurรฉ. Vous pouvez vous connecter et commencez ร " |
531 | "shaare vos liens !" | 591 | "shaare vos liens !" |
532 | 592 | ||
533 | #: application/front/controller/visitor/InstallController.php:158 | 593 | #: application/front/controller/visitor/InstallController.php:168 |
534 | msgid "Insufficient permissions:" | 594 | msgid "Insufficient permissions:" |
535 | msgstr "Permissions insuffisantes :" | 595 | msgstr "Permissions insuffisantes :" |
536 | 596 | ||
@@ -1016,25 +1076,28 @@ msgstr "" | |||
1016 | "miniatures." | 1076 | "miniatures." |
1017 | 1077 | ||
1018 | #: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:328 | 1078 | #: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:328 |
1019 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:56 | 1079 | #: tmp/server.b91ef64efc3688266305ea9b42e5017e.rtpl.php:122 |
1020 | msgid "Synchronize thumbnails" | 1080 | msgid "Synchronize thumbnails" |
1021 | msgstr "Synchroniser les miniatures" | 1081 | msgstr "Synchroniser les miniatures" |
1022 | 1082 | ||
1023 | #: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:339 | 1083 | #: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:339 |
1024 | #: tmp/export.b91ef64efc3688266305ea9b42e5017e.rtpl.php:30 | 1084 | #: tmp/export.b91ef64efc3688266305ea9b42e5017e.rtpl.php:30 |
1085 | #: tmp/server.b91ef64efc3688266305ea9b42e5017e.rtpl.php:102 | ||
1025 | msgid "All" | 1086 | msgid "All" |
1026 | msgstr "Tous" | 1087 | msgstr "Tous" |
1027 | 1088 | ||
1028 | #: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:343 | 1089 | #: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:343 |
1090 | #: tmp/server.b91ef64efc3688266305ea9b42e5017e.rtpl.php:106 | ||
1029 | msgid "Only common media hosts" | 1091 | msgid "Only common media hosts" |
1030 | msgstr "Seulement les hรฉbergeurs de mรฉdia connus" | 1092 | msgstr "Seulement les hรฉbergeurs de mรฉdia connus" |
1031 | 1093 | ||
1032 | #: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:347 | 1094 | #: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:347 |
1095 | #: tmp/server.b91ef64efc3688266305ea9b42e5017e.rtpl.php:110 | ||
1033 | msgid "None" | 1096 | msgid "None" |
1034 | msgstr "Aucune" | 1097 | msgstr "Aucune" |
1035 | 1098 | ||
1036 | #: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:355 | 1099 | #: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:355 |
1037 | #: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:88 | 1100 | #: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:102 |
1038 | #: tmp/pluginsadmin.b91ef64efc3688266305ea9b42e5017e.rtpl.php:139 | 1101 | #: tmp/pluginsadmin.b91ef64efc3688266305ea9b42e5017e.rtpl.php:139 |
1039 | #: tmp/pluginsadmin.b91ef64efc3688266305ea9b42e5017e.rtpl.php:199 | 1102 | #: tmp/pluginsadmin.b91ef64efc3688266305ea9b42e5017e.rtpl.php:199 |
1040 | msgid "Save" | 1103 | msgid "Save" |
@@ -1060,27 +1123,27 @@ msgstr "Tous les liens d'un jour sur une page." | |||
1060 | msgid "Next day" | 1123 | msgid "Next day" |
1061 | msgstr "Jour suivant" | 1124 | msgstr "Jour suivant" |
1062 | 1125 | ||
1063 | #: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:18 | 1126 | #: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:21 |
1064 | msgid "Edit Shaare" | 1127 | msgid "Edit Shaare" |
1065 | msgstr "Modifier le Shaare" | 1128 | msgstr "Modifier le Shaare" |
1066 | 1129 | ||
1067 | #: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:18 | 1130 | #: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:21 |
1068 | msgid "New Shaare" | 1131 | msgid "New Shaare" |
1069 | msgstr "Nouveau Shaare" | 1132 | msgstr "Nouveau Shaare" |
1070 | 1133 | ||
1071 | #: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:26 | 1134 | #: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:29 |
1072 | msgid "Created:" | 1135 | msgid "Created:" |
1073 | msgstr "Crรฉation :" | 1136 | msgstr "Crรฉation :" |
1074 | 1137 | ||
1075 | #: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:29 | 1138 | #: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:32 |
1076 | msgid "URL" | 1139 | msgid "URL" |
1077 | msgstr "URL" | 1140 | msgstr "URL" |
1078 | 1141 | ||
1079 | #: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:35 | 1142 | #: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:38 |
1080 | msgid "Title" | 1143 | msgid "Title" |
1081 | msgstr "Titre" | 1144 | msgstr "Titre" |
1082 | 1145 | ||
1083 | #: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:41 | 1146 | #: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:49 |
1084 | #: tmp/pluginsadmin.b91ef64efc3688266305ea9b42e5017e.rtpl.php:42 | 1147 | #: tmp/pluginsadmin.b91ef64efc3688266305ea9b42e5017e.rtpl.php:42 |
1085 | #: tmp/pluginsadmin.b91ef64efc3688266305ea9b42e5017e.rtpl.php:75 | 1148 | #: tmp/pluginsadmin.b91ef64efc3688266305ea9b42e5017e.rtpl.php:75 |
1086 | #: tmp/pluginsadmin.b91ef64efc3688266305ea9b42e5017e.rtpl.php:99 | 1149 | #: tmp/pluginsadmin.b91ef64efc3688266305ea9b42e5017e.rtpl.php:99 |
@@ -1088,33 +1151,33 @@ msgstr "Titre" | |||
1088 | msgid "Description" | 1151 | msgid "Description" |
1089 | msgstr "Description" | 1152 | msgstr "Description" |
1090 | 1153 | ||
1091 | #: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:47 | 1154 | #: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:58 |
1092 | msgid "Tags" | 1155 | msgid "Tags" |
1093 | msgstr "Tags" | 1156 | msgstr "Tags" |
1094 | 1157 | ||
1095 | #: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:60 | 1158 | #: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:74 |
1096 | #: tmp/export.b91ef64efc3688266305ea9b42e5017e.rtpl.php:35 | 1159 | #: tmp/export.b91ef64efc3688266305ea9b42e5017e.rtpl.php:35 |
1097 | #: tmp/linklist.b91ef64efc3688266305ea9b42e5017e.rtpl.php:169 | 1160 | #: tmp/linklist.b91ef64efc3688266305ea9b42e5017e.rtpl.php:169 |
1098 | msgid "Private" | 1161 | msgid "Private" |
1099 | msgstr "Privรฉ" | 1162 | msgstr "Privรฉ" |
1100 | 1163 | ||
1101 | #: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:66 | 1164 | #: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:80 |
1102 | msgid "Description will be rendered with" | 1165 | msgid "Description will be rendered with" |
1103 | msgstr "La description sera gรฉnรฉrรฉe avec" | 1166 | msgstr "La description sera gรฉnรฉrรฉe avec" |
1104 | 1167 | ||
1105 | #: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:68 | 1168 | #: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:82 |
1106 | msgid "Markdown syntax documentation" | 1169 | msgid "Markdown syntax documentation" |
1107 | msgstr "Documentation sur la syntaxe Markdown" | 1170 | msgstr "Documentation sur la syntaxe Markdown" |
1108 | 1171 | ||
1109 | #: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:69 | 1172 | #: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:83 |
1110 | msgid "Markdown syntax" | 1173 | msgid "Markdown syntax" |
1111 | msgstr "la syntaxe Markdown" | 1174 | msgstr "la syntaxe Markdown" |
1112 | 1175 | ||
1113 | #: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:88 | 1176 | #: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:102 |
1114 | msgid "Apply Changes" | 1177 | msgid "Apply Changes" |
1115 | msgstr "Appliquer les changements" | 1178 | msgstr "Appliquer les changements" |
1116 | 1179 | ||
1117 | #: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:93 | 1180 | #: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:107 |
1118 | #: tmp/linklist.b91ef64efc3688266305ea9b42e5017e.rtpl.php:173 | 1181 | #: tmp/linklist.b91ef64efc3688266305ea9b42e5017e.rtpl.php:173 |
1119 | #: tmp/page.header.b91ef64efc3688266305ea9b42e5017e.rtpl.php:147 | 1182 | #: tmp/page.header.b91ef64efc3688266305ea9b42e5017e.rtpl.php:147 |
1120 | #: tmp/page.header.cedf684561d925457130839629000a81.rtpl.php:147 | 1183 | #: tmp/page.header.cedf684561d925457130839629000a81.rtpl.php:147 |
@@ -1179,10 +1242,6 @@ msgstr "Les doublons s'appuient sur les URL" | |||
1179 | msgid "Add default tags" | 1242 | msgid "Add default tags" |
1180 | msgstr "Ajouter des tags par dรฉfaut" | 1243 | msgstr "Ajouter des tags par dรฉfaut" |
1181 | 1244 | ||
1182 | #: tmp/install.b91ef64efc3688266305ea9b42e5017e.rtpl.php:22 | ||
1183 | msgid "Install Shaarli" | ||
1184 | msgstr "Installation de Shaarli" | ||
1185 | |||
1186 | #: tmp/install.b91ef64efc3688266305ea9b42e5017e.rtpl.php:25 | 1245 | #: tmp/install.b91ef64efc3688266305ea9b42e5017e.rtpl.php:25 |
1187 | msgid "It looks like it's the first time you run Shaarli. Please configure it." | 1246 | msgid "It looks like it's the first time you run Shaarli. Please configure it." |
1188 | msgstr "" | 1247 | msgstr "" |
@@ -1215,6 +1274,10 @@ msgstr "Mes liens" | |||
1215 | msgid "Install" | 1274 | msgid "Install" |
1216 | msgstr "Installer" | 1275 | msgstr "Installer" |
1217 | 1276 | ||
1277 | #: tmp/install.b91ef64efc3688266305ea9b42e5017e.rtpl.php:190 | ||
1278 | msgid "Server requirements" | ||
1279 | msgstr "Prรฉ-requis serveur" | ||
1280 | |||
1218 | #: tmp/linklist.b91ef64efc3688266305ea9b42e5017e.rtpl.php:14 | 1281 | #: tmp/linklist.b91ef64efc3688266305ea9b42e5017e.rtpl.php:14 |
1219 | #: tmp/linklist.b91ef64efc3688266305ea9b42e5017e.rtpl.php:79 | 1282 | #: tmp/linklist.b91ef64efc3688266305ea9b42e5017e.rtpl.php:79 |
1220 | msgid "shaare" | 1283 | msgid "shaare" |
@@ -1511,6 +1574,100 @@ msgstr "Configuration des extensions" | |||
1511 | msgid "No parameter available." | 1574 | msgid "No parameter available." |
1512 | msgstr "Aucun paramรจtre disponible." | 1575 | msgstr "Aucun paramรจtre disponible." |
1513 | 1576 | ||
1577 | #: tmp/server.b91ef64efc3688266305ea9b42e5017e.rtpl.php:16 | ||
1578 | msgid "General" | ||
1579 | msgstr "Gรฉnรฉral" | ||
1580 | |||
1581 | #: tmp/server.b91ef64efc3688266305ea9b42e5017e.rtpl.php:20 | ||
1582 | msgid "Index URL" | ||
1583 | msgstr "URL de l'index" | ||
1584 | |||
1585 | #: tmp/server.b91ef64efc3688266305ea9b42e5017e.rtpl.php:28 | ||
1586 | msgid "Base path" | ||
1587 | msgstr "Chemin de base" | ||
1588 | |||
1589 | #: tmp/server.b91ef64efc3688266305ea9b42e5017e.rtpl.php:36 | ||
1590 | msgid "Client IP" | ||
1591 | msgstr "IP du client" | ||
1592 | |||
1593 | #: tmp/server.b91ef64efc3688266305ea9b42e5017e.rtpl.php:44 | ||
1594 | msgid "Trusted reverse proxies" | ||
1595 | msgstr "Reverse proxies de confiance" | ||
1596 | |||
1597 | #: tmp/server.b91ef64efc3688266305ea9b42e5017e.rtpl.php:58 | ||
1598 | msgid "N/A" | ||
1599 | msgstr "N/A" | ||
1600 | |||
1601 | #: tmp/server.b91ef64efc3688266305ea9b42e5017e.rtpl.php:84 | ||
1602 | msgid "Visit releases page on Github" | ||
1603 | msgstr "Visiter la page des releases sur Github" | ||
1604 | |||
1605 | #: tmp/server.b91ef64efc3688266305ea9b42e5017e.rtpl.php:121 | ||
1606 | msgid "Synchronize all link thumbnails" | ||
1607 | msgstr "Synchroniser toutes les miniatures" | ||
1608 | |||
1609 | #: tmp/server.requirements.b91ef64efc3688266305ea9b42e5017e.rtpl.php:2 | ||
1610 | #: tmp/server.requirements.cedf684561d925457130839629000a81.rtpl.php:2 | ||
1611 | msgid "Permissions" | ||
1612 | msgstr "Permissions" | ||
1613 | |||
1614 | #: tmp/server.requirements.b91ef64efc3688266305ea9b42e5017e.rtpl.php:8 | ||
1615 | #: tmp/server.requirements.cedf684561d925457130839629000a81.rtpl.php:8 | ||
1616 | msgid "There are permissions that need to be fixed." | ||
1617 | msgstr "Il y a des permissions qui doivent รชtre corrigรฉes." | ||
1618 | |||
1619 | #: tmp/server.requirements.b91ef64efc3688266305ea9b42e5017e.rtpl.php:23 | ||
1620 | #: tmp/server.requirements.cedf684561d925457130839629000a81.rtpl.php:23 | ||
1621 | msgid "All read/write permissions are properly set." | ||
1622 | msgstr "Toutes les permissions de lecture/รฉcriture sont dรฉfinies correctement." | ||
1623 | |||
1624 | #: tmp/server.requirements.b91ef64efc3688266305ea9b42e5017e.rtpl.php:32 | ||
1625 | #: tmp/server.requirements.cedf684561d925457130839629000a81.rtpl.php:32 | ||
1626 | msgid "Running PHP" | ||
1627 | msgstr "Fonctionnant avec PHP" | ||
1628 | |||
1629 | #: tmp/server.requirements.b91ef64efc3688266305ea9b42e5017e.rtpl.php:36 | ||
1630 | #: tmp/server.requirements.cedf684561d925457130839629000a81.rtpl.php:36 | ||
1631 | msgid "End of life: " | ||
1632 | msgstr "Fin de vie : " | ||
1633 | |||
1634 | #: tmp/server.requirements.b91ef64efc3688266305ea9b42e5017e.rtpl.php:48 | ||
1635 | #: tmp/server.requirements.cedf684561d925457130839629000a81.rtpl.php:48 | ||
1636 | msgid "Extension" | ||
1637 | msgstr "Extension" | ||
1638 | |||
1639 | #: tmp/server.requirements.b91ef64efc3688266305ea9b42e5017e.rtpl.php:49 | ||
1640 | #: tmp/server.requirements.cedf684561d925457130839629000a81.rtpl.php:49 | ||
1641 | msgid "Usage" | ||
1642 | msgstr "Utilisation" | ||
1643 | |||
1644 | #: tmp/server.requirements.b91ef64efc3688266305ea9b42e5017e.rtpl.php:50 | ||
1645 | #: tmp/server.requirements.cedf684561d925457130839629000a81.rtpl.php:50 | ||
1646 | msgid "Status" | ||
1647 | msgstr "Statut" | ||
1648 | |||
1649 | #: tmp/server.requirements.b91ef64efc3688266305ea9b42e5017e.rtpl.php:51 | ||
1650 | #: tmp/server.requirements.b91ef64efc3688266305ea9b42e5017e.rtpl.php:66 | ||
1651 | #: tmp/server.requirements.cedf684561d925457130839629000a81.rtpl.php:51 | ||
1652 | #: tmp/server.requirements.cedf684561d925457130839629000a81.rtpl.php:66 | ||
1653 | msgid "Loaded" | ||
1654 | msgstr "Chargรฉ" | ||
1655 | |||
1656 | #: tmp/server.requirements.b91ef64efc3688266305ea9b42e5017e.rtpl.php:60 | ||
1657 | #: tmp/server.requirements.cedf684561d925457130839629000a81.rtpl.php:60 | ||
1658 | msgid "Required" | ||
1659 | msgstr "Obligatoire" | ||
1660 | |||
1661 | #: tmp/server.requirements.b91ef64efc3688266305ea9b42e5017e.rtpl.php:60 | ||
1662 | #: tmp/server.requirements.cedf684561d925457130839629000a81.rtpl.php:60 | ||
1663 | msgid "Optional" | ||
1664 | msgstr "Optionnel" | ||
1665 | |||
1666 | #: tmp/server.requirements.b91ef64efc3688266305ea9b42e5017e.rtpl.php:70 | ||
1667 | #: tmp/server.requirements.cedf684561d925457130839629000a81.rtpl.php:70 | ||
1668 | msgid "Not loaded" | ||
1669 | msgstr "Non chargรฉ" | ||
1670 | |||
1514 | #: tmp/tag.cloud.b91ef64efc3688266305ea9b42e5017e.rtpl.php:19 | 1671 | #: tmp/tag.cloud.b91ef64efc3688266305ea9b42e5017e.rtpl.php:19 |
1515 | #: tmp/tag.list.b91ef64efc3688266305ea9b42e5017e.rtpl.php:19 | 1672 | #: tmp/tag.list.b91ef64efc3688266305ea9b42e5017e.rtpl.php:19 |
1516 | msgid "tags" | 1673 | msgid "tags" |
@@ -1561,15 +1718,19 @@ msgstr "Configurer Shaarli" | |||
1561 | msgid "Enable, disable and configure plugins" | 1718 | msgid "Enable, disable and configure plugins" |
1562 | msgstr "Activer, dรฉsactiver et configurer les extensions" | 1719 | msgstr "Activer, dรฉsactiver et configurer les extensions" |
1563 | 1720 | ||
1564 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:28 | 1721 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:27 |
1722 | msgid "Check instance's server configuration" | ||
1723 | msgstr "Vรฉrifier la configuration serveur de l'instance" | ||
1724 | |||
1725 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:34 | ||
1565 | msgid "Change your password" | 1726 | msgid "Change your password" |
1566 | msgstr "Modifier le mot de passe" | 1727 | msgstr "Modifier le mot de passe" |
1567 | 1728 | ||
1568 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:35 | 1729 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:41 |
1569 | msgid "Rename or delete a tag in all links" | 1730 | msgid "Rename or delete a tag in all links" |
1570 | msgstr "Renommer ou supprimer un tag dans tous les liens" | 1731 | msgstr "Renommer ou supprimer un tag dans tous les liens" |
1571 | 1732 | ||
1572 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:41 | 1733 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:47 |
1573 | msgid "" | 1734 | msgid "" |
1574 | "Import Netscape HTML bookmarks (as exported from Firefox, Chrome, Opera, " | 1735 | "Import Netscape HTML bookmarks (as exported from Firefox, Chrome, Opera, " |
1575 | "delicious...)" | 1736 | "delicious...)" |
@@ -1577,11 +1738,11 @@ msgstr "" | |||
1577 | "Importer des marques pages au format Netscape HTML (comme exportรฉs depuis " | 1738 | "Importer des marques pages au format Netscape HTML (comme exportรฉs depuis " |
1578 | "Firefox, Chrome, Opera, delicious...)" | 1739 | "Firefox, Chrome, Opera, delicious...)" |
1579 | 1740 | ||
1580 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:42 | 1741 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:48 |
1581 | msgid "Import links" | 1742 | msgid "Import links" |
1582 | msgstr "Importer des liens" | 1743 | msgstr "Importer des liens" |
1583 | 1744 | ||
1584 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:47 | 1745 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:53 |
1585 | msgid "" | 1746 | msgid "" |
1586 | "Export Netscape HTML bookmarks (which can be imported in Firefox, Chrome, " | 1747 | "Export Netscape HTML bookmarks (which can be imported in Firefox, Chrome, " |
1587 | "Opera, delicious...)" | 1748 | "Opera, delicious...)" |
@@ -1589,15 +1750,11 @@ msgstr "" | |||
1589 | "Exporter les marques pages au format Netscape HTML (comme exportรฉs depuis " | 1750 | "Exporter les marques pages au format Netscape HTML (comme exportรฉs depuis " |
1590 | "Firefox, Chrome, Opera, delicious...)" | 1751 | "Firefox, Chrome, Opera, delicious...)" |
1591 | 1752 | ||
1592 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:48 | 1753 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:54 |
1593 | msgid "Export database" | 1754 | msgid "Export database" |
1594 | msgstr "Exporter les donnรฉes" | 1755 | msgstr "Exporter les donnรฉes" |
1595 | 1756 | ||
1596 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:55 | 1757 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:77 |
1597 | msgid "Synchronize all link thumbnails" | ||
1598 | msgstr "Synchroniser toutes les miniatures" | ||
1599 | |||
1600 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:81 | ||
1601 | msgid "" | 1758 | msgid "" |
1602 | "Drag one of these button to your bookmarks toolbar or right-click it and " | 1759 | "Drag one of these button to your bookmarks toolbar or right-click it and " |
1603 | "\"Bookmark This Link\"" | 1760 | "\"Bookmark This Link\"" |
@@ -1605,13 +1762,13 @@ msgstr "" | |||
1605 | "Glisser un de ces boutons dans votre barre de favoris ou cliquer droit " | 1762 | "Glisser un de ces boutons dans votre barre de favoris ou cliquer droit " |
1606 | "dessus et ยซ Ajouter aux favoris ยป" | 1763 | "dessus et ยซ Ajouter aux favoris ยป" |
1607 | 1764 | ||
1608 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:82 | 1765 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:78 |
1609 | msgid "then click on the bookmarklet in any page you want to share." | 1766 | msgid "then click on the bookmarklet in any page you want to share." |
1610 | msgstr "" | 1767 | msgstr "" |
1611 | "puis cliquer sur le marque-page depuis un site que vous souhaitez partager." | 1768 | "puis cliquer sur le marque-page depuis un site que vous souhaitez partager." |
1612 | 1769 | ||
1613 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:86 | 1770 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:82 |
1614 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:110 | 1771 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:106 |
1615 | msgid "" | 1772 | msgid "" |
1616 | "Drag this link to your bookmarks toolbar or right-click it and Bookmark This " | 1773 | "Drag this link to your bookmarks toolbar or right-click it and Bookmark This " |
1617 | "Link" | 1774 | "Link" |
@@ -1619,40 +1776,40 @@ msgstr "" | |||
1619 | "Glisser ce lien dans votre barre de favoris ou cliquer droit dessus et ยซ " | 1776 | "Glisser ce lien dans votre barre de favoris ou cliquer droit dessus et ยซ " |
1620 | "Ajouter aux favoris ยป" | 1777 | "Ajouter aux favoris ยป" |
1621 | 1778 | ||
1622 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:87 | 1779 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:83 |
1623 | msgid "then click โShaare link button in any page you want to share" | 1780 | msgid "then click โShaare link button in any page you want to share" |
1624 | msgstr "puis cliquer sur โShaare depuis un site que vous souhaitez partager" | 1781 | msgstr "puis cliquer sur โShaare depuis un site que vous souhaitez partager" |
1625 | 1782 | ||
1626 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:96 | 1783 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:92 |
1627 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:118 | 1784 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:114 |
1628 | msgid "The selected text is too long, it will be truncated." | 1785 | msgid "The selected text is too long, it will be truncated." |
1629 | msgstr "Le texte sรฉlectionnรฉ est trop long, il sera tronquรฉ." | 1786 | msgstr "Le texte sรฉlectionnรฉ est trop long, il sera tronquรฉ." |
1630 | 1787 | ||
1631 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:106 | 1788 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:102 |
1632 | msgid "Shaare link" | 1789 | msgid "Shaare link" |
1633 | msgstr "Shaare" | 1790 | msgstr "Shaare" |
1634 | 1791 | ||
1635 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:111 | 1792 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:107 |
1636 | msgid "" | 1793 | msgid "" |
1637 | "Then click โAdd Note button anytime to start composing a private Note (text " | 1794 | "Then click โAdd Note button anytime to start composing a private Note (text " |
1638 | "post) to your Shaarli" | 1795 | "post) to your Shaarli" |
1639 | msgstr "" | 1796 | msgstr "" |
1640 | "Puis cliquer sur โAdd Note pour commencer ร rรฉdiger une Note sur Shaarli" | 1797 | "Puis cliquer sur โAdd Note pour commencer ร rรฉdiger une Note sur Shaarli" |
1641 | 1798 | ||
1642 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:127 | 1799 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:123 |
1643 | msgid "Add Note" | 1800 | msgid "Add Note" |
1644 | msgstr "Ajouter une Note" | 1801 | msgstr "Ajouter une Note" |
1645 | 1802 | ||
1646 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:136 | 1803 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:132 |
1647 | msgid "3rd party" | 1804 | msgid "3rd party" |
1648 | msgstr "Applications tierces" | 1805 | msgstr "Applications tierces" |
1649 | 1806 | ||
1650 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:139 | 1807 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:135 |
1651 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:144 | 1808 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:140 |
1652 | msgid "plugin" | 1809 | msgid "plugin" |
1653 | msgstr "extension" | 1810 | msgstr "extension" |
1654 | 1811 | ||
1655 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:169 | 1812 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:165 |
1656 | msgid "" | 1813 | msgid "" |
1657 | "Drag this link to your bookmarks toolbar, or right-click it and choose " | 1814 | "Drag this link to your bookmarks toolbar, or right-click it and choose " |
1658 | "Bookmark This Link" | 1815 | "Bookmark This Link" |
@@ -1660,9 +1817,6 @@ msgstr "" | |||
1660 | "Glisser ce lien dans votre barre de favoris ou cliquer droit dessus et ยซ " | 1817 | "Glisser ce lien dans votre barre de favoris ou cliquer droit dessus et ยซ " |
1661 | "Ajouter aux favoris ยป" | 1818 | "Ajouter aux favoris ยป" |
1662 | 1819 | ||
1663 | #~ msgid "Provided data is invalid" | ||
1664 | #~ msgstr "Les informations fournies ne sont pas valides" | ||
1665 | |||
1666 | #~ msgid "Rename" | 1820 | #~ msgid "Rename" |
1667 | #~ msgstr "Renommer" | 1821 | #~ msgstr "Renommer" |
1668 | 1822 | ||
@@ -128,6 +128,8 @@ $app->group('/admin', function () { | |||
128 | $this->get('/plugins', '\Shaarli\Front\Controller\Admin\PluginsController:index'); | 128 | $this->get('/plugins', '\Shaarli\Front\Controller\Admin\PluginsController:index'); |
129 | $this->post('/plugins', '\Shaarli\Front\Controller\Admin\PluginsController:save'); | 129 | $this->post('/plugins', '\Shaarli\Front\Controller\Admin\PluginsController:save'); |
130 | $this->get('/token', '\Shaarli\Front\Controller\Admin\TokenController:getToken'); | 130 | $this->get('/token', '\Shaarli\Front\Controller\Admin\TokenController:getToken'); |
131 | $this->get('/server', '\Shaarli\Front\Controller\Admin\ServerController:index'); | ||
132 | $this->get('/clear-cache', '\Shaarli\Front\Controller\Admin\ServerController:clearCache'); | ||
131 | $this->get('/thumbnails', '\Shaarli\Front\Controller\Admin\ThumbnailsController:index'); | 133 | $this->get('/thumbnails', '\Shaarli\Front\Controller\Admin\ThumbnailsController:index'); |
132 | $this->get('/metadata', '\Shaarli\Front\Controller\Admin\MetadataController:ajaxRetrieveTitle'); | 134 | $this->get('/metadata', '\Shaarli\Front\Controller\Admin\MetadataController:ajaxRetrieveTitle'); |
133 | $this->get('/visibility/{visibility}', '\Shaarli\Front\Controller\Admin\SessionFilterController:visibility'); | 135 | $this->get('/visibility/{visibility}', '\Shaarli\Front\Controller\Admin\SessionFilterController:visibility'); |
diff --git a/tests/ApplicationUtilsTest.php b/tests/ApplicationUtilsTest.php index a232b351..ac46cbf1 100644 --- a/tests/ApplicationUtilsTest.php +++ b/tests/ApplicationUtilsTest.php | |||
@@ -340,6 +340,35 @@ class ApplicationUtilsTest extends \Shaarli\TestCase | |||
340 | } | 340 | } |
341 | 341 | ||
342 | /** | 342 | /** |
343 | * Checks resource permissions in minimal mode. | ||
344 | */ | ||
345 | public function testCheckCurrentResourcePermissionsErrorsMinimalMode(): void | ||
346 | { | ||
347 | $conf = new ConfigManager(''); | ||
348 | $conf->set('resource.thumbnails_cache', 'null/cache'); | ||
349 | $conf->set('resource.config', 'null/data/config.php'); | ||
350 | $conf->set('resource.data_dir', 'null/data'); | ||
351 | $conf->set('resource.datastore', 'null/data/store.php'); | ||
352 | $conf->set('resource.ban_file', 'null/data/ipbans.php'); | ||
353 | $conf->set('resource.log', 'null/data/log.txt'); | ||
354 | $conf->set('resource.page_cache', 'null/pagecache'); | ||
355 | $conf->set('resource.raintpl_tmp', 'null/tmp'); | ||
356 | $conf->set('resource.raintpl_tpl', 'null/tpl'); | ||
357 | $conf->set('resource.raintpl_theme', 'null/tpl/default'); | ||
358 | $conf->set('resource.update_check', 'null/data/lastupdatecheck.txt'); | ||
359 | |||
360 | static::assertSame( | ||
361 | [ | ||
362 | '"null/tpl" directory is not readable', | ||
363 | '"null/tpl/default" directory is not readable', | ||
364 | '"null/tmp" directory is not readable', | ||
365 | '"null/tmp" directory is not writable' | ||
366 | ], | ||
367 | ApplicationUtils::checkResourcePermissions($conf, true) | ||
368 | ); | ||
369 | } | ||
370 | |||
371 | /** | ||
343 | * Check update with 'dev' as curent version (master branch). | 372 | * Check update with 'dev' as curent version (master branch). |
344 | * It should always return false. | 373 | * It should always return false. |
345 | */ | 374 | */ |
@@ -349,4 +378,37 @@ class ApplicationUtilsTest extends \Shaarli\TestCase | |||
349 | ApplicationUtils::checkUpdate('dev', self::$testUpdateFile, 100, true, true) | 378 | ApplicationUtils::checkUpdate('dev', self::$testUpdateFile, 100, true, true) |
350 | ); | 379 | ); |
351 | } | 380 | } |
381 | |||
382 | /** | ||
383 | * Basic test of getPhpExtensionsRequirement() | ||
384 | */ | ||
385 | public function testGetPhpExtensionsRequirementSimple(): void | ||
386 | { | ||
387 | static::assertCount(8, ApplicationUtils::getPhpExtensionsRequirement()); | ||
388 | static::assertSame([ | ||
389 | 'name' => 'json', | ||
390 | 'required' => true, | ||
391 | 'desc' => 'Configuration parsing', | ||
392 | 'loaded' => true, | ||
393 | ], ApplicationUtils::getPhpExtensionsRequirement()[0]); | ||
394 | } | ||
395 | |||
396 | /** | ||
397 | * Test getPhpEol with a known version: 7.4 -> 2022 | ||
398 | */ | ||
399 | public function testGetKnownPhpEol(): void | ||
400 | { | ||
401 | static::assertSame('2022-11-28', ApplicationUtils::getPhpEol('7.4.7')); | ||
402 | } | ||
403 | |||
404 | /** | ||
405 | * Test getPhpEol with an unknown version: 7.4 -> 2022 | ||
406 | */ | ||
407 | public function testGetUnknownPhpEol(): void | ||
408 | { | ||
409 | static::assertSame( | ||
410 | (((int) (new \DateTime())->format('Y')) + 2) . (new \DateTime())->format('-m-d'), | ||
411 | ApplicationUtils::getPhpEol('7.51.34') | ||
412 | ); | ||
413 | } | ||
352 | } | 414 | } |
diff --git a/tests/FileUtilsTest.php b/tests/FileUtilsTest.php index 9163bdf1..3384504a 100644 --- a/tests/FileUtilsTest.php +++ b/tests/FileUtilsTest.php | |||
@@ -3,25 +3,48 @@ | |||
3 | namespace Shaarli; | 3 | namespace Shaarli; |
4 | 4 | ||
5 | use Exception; | 5 | use Exception; |
6 | use Shaarli\Exceptions\IOException; | ||
6 | 7 | ||
7 | /** | 8 | /** |
8 | * Class FileUtilsTest | 9 | * Class FileUtilsTest |
9 | * | 10 | * |
10 | * Test file utility class. | 11 | * Test file utility class. |
11 | */ | 12 | */ |
12 | class FileUtilsTest extends \Shaarli\TestCase | 13 | class FileUtilsTest extends TestCase |
13 | { | 14 | { |
14 | /** | 15 | /** |
15 | * @var string Test file path. | 16 | * @var string Test file path. |
16 | */ | 17 | */ |
17 | protected static $file = 'sandbox/flat.db'; | 18 | protected static $file = 'sandbox/flat.db'; |
18 | 19 | ||
20 | protected function setUp(): void | ||
21 | { | ||
22 | @mkdir('sandbox'); | ||
23 | mkdir('sandbox/folder2'); | ||
24 | touch('sandbox/file1'); | ||
25 | touch('sandbox/file2'); | ||
26 | mkdir('sandbox/folder1'); | ||
27 | touch('sandbox/folder1/file1'); | ||
28 | touch('sandbox/folder1/file2'); | ||
29 | mkdir('sandbox/folder3'); | ||
30 | mkdir('/tmp/shaarli-to-delete'); | ||
31 | } | ||
32 | |||
19 | /** | 33 | /** |
20 | * Delete test file after every test. | 34 | * Delete test file after every test. |
21 | */ | 35 | */ |
22 | protected function tearDown(): void | 36 | protected function tearDown(): void |
23 | { | 37 | { |
24 | @unlink(self::$file); | 38 | @unlink(self::$file); |
39 | |||
40 | @unlink('sandbox/folder1/file1'); | ||
41 | @unlink('sandbox/folder1/file2'); | ||
42 | @rmdir('sandbox/folder1'); | ||
43 | @unlink('sandbox/file1'); | ||
44 | @unlink('sandbox/file2'); | ||
45 | @rmdir('sandbox/folder2'); | ||
46 | @rmdir('sandbox/folder3'); | ||
47 | @rmdir('/tmp/shaarli-to-delete'); | ||
25 | } | 48 | } |
26 | 49 | ||
27 | /** | 50 | /** |
@@ -107,4 +130,67 @@ class FileUtilsTest extends \Shaarli\TestCase | |||
107 | $this->assertEquals(null, FileUtils::readFlatDB(self::$file)); | 130 | $this->assertEquals(null, FileUtils::readFlatDB(self::$file)); |
108 | $this->assertEquals(['test'], FileUtils::readFlatDB(self::$file, ['test'])); | 131 | $this->assertEquals(['test'], FileUtils::readFlatDB(self::$file, ['test'])); |
109 | } | 132 | } |
133 | |||
134 | /** | ||
135 | * Test clearFolder with self delete and excluded files | ||
136 | */ | ||
137 | public function testClearFolderSelfDeleteWithExclusion(): void | ||
138 | { | ||
139 | FileUtils::clearFolder('sandbox', true, ['file2']); | ||
140 | |||
141 | static::assertFileExists('sandbox/folder1/file2'); | ||
142 | static::assertFileExists('sandbox/folder1'); | ||
143 | static::assertFileExists('sandbox/file2'); | ||
144 | static::assertFileExists('sandbox'); | ||
145 | |||
146 | static::assertFileNotExists('sandbox/folder1/file1'); | ||
147 | static::assertFileNotExists('sandbox/file1'); | ||
148 | static::assertFileNotExists('sandbox/folder3'); | ||
149 | } | ||
150 | |||
151 | /** | ||
152 | * Test clearFolder with self delete and excluded files | ||
153 | */ | ||
154 | public function testClearFolderSelfDeleteWithoutExclusion(): void | ||
155 | { | ||
156 | FileUtils::clearFolder('sandbox', true); | ||
157 | |||
158 | static::assertFileNotExists('sandbox'); | ||
159 | } | ||
160 | |||
161 | /** | ||
162 | * Test clearFolder with self delete and excluded files | ||
163 | */ | ||
164 | public function testClearFolderNoSelfDeleteWithoutExclusion(): void | ||
165 | { | ||
166 | FileUtils::clearFolder('sandbox', false); | ||
167 | |||
168 | static::assertFileExists('sandbox'); | ||
169 | |||
170 | // 2 because '.' and '..' | ||
171 | static::assertCount(2, new \DirectoryIterator('sandbox')); | ||
172 | } | ||
173 | |||
174 | /** | ||
175 | * Test clearFolder on a file instead of a folder | ||
176 | */ | ||
177 | public function testClearFolderOnANonDirectory(): void | ||
178 | { | ||
179 | $this->expectException(IOException::class); | ||
180 | $this->expectExceptionMessage('Provided path is not a directory.'); | ||
181 | |||
182 | FileUtils::clearFolder('sandbox/file1', false); | ||
183 | } | ||
184 | |||
185 | /** | ||
186 | * Test clearFolder on a file instead of a folder | ||
187 | */ | ||
188 | public function testClearFolderOutsideOfShaarliDirectory(): void | ||
189 | { | ||
190 | $this->expectException(IOException::class); | ||
191 | $this->expectExceptionMessage('Trying to delete a folder outside of Shaarli path.'); | ||
192 | |||
193 | |||
194 | FileUtils::clearFolder('/tmp/shaarli-to-delete', true); | ||
195 | } | ||
110 | } | 196 | } |
diff --git a/tests/front/controller/admin/ServerControllerTest.php b/tests/front/controller/admin/ServerControllerTest.php new file mode 100644 index 00000000..355cce7d --- /dev/null +++ b/tests/front/controller/admin/ServerControllerTest.php | |||
@@ -0,0 +1,184 @@ | |||
1 | <?php | ||
2 | |||
3 | declare(strict_types=1); | ||
4 | |||
5 | namespace Shaarli\Front\Controller\Admin; | ||
6 | |||
7 | use Shaarli\Config\ConfigManager; | ||
8 | use Shaarli\Security\SessionManager; | ||
9 | use Shaarli\TestCase; | ||
10 | use Slim\Http\Request; | ||
11 | use Slim\Http\Response; | ||
12 | |||
13 | /** | ||
14 | * Test Server administration controller. | ||
15 | */ | ||
16 | class ServerControllerTest extends TestCase | ||
17 | { | ||
18 | use FrontAdminControllerMockHelper; | ||
19 | |||
20 | /** @var ServerController */ | ||
21 | protected $controller; | ||
22 | |||
23 | public function setUp(): void | ||
24 | { | ||
25 | $this->createContainer(); | ||
26 | |||
27 | $this->controller = new ServerController($this->container); | ||
28 | |||
29 | // initialize dummy cache | ||
30 | @mkdir('sandbox/'); | ||
31 | foreach (['pagecache', 'tmp', 'cache'] as $folder) { | ||
32 | @mkdir('sandbox/' . $folder); | ||
33 | @touch('sandbox/' . $folder . '/.htaccess'); | ||
34 | @touch('sandbox/' . $folder . '/1'); | ||
35 | @touch('sandbox/' . $folder . '/2'); | ||
36 | } | ||
37 | } | ||
38 | |||
39 | public function tearDown(): void | ||
40 | { | ||
41 | foreach (['pagecache', 'tmp', 'cache'] as $folder) { | ||
42 | @unlink('sandbox/' . $folder . '/.htaccess'); | ||
43 | @unlink('sandbox/' . $folder . '/1'); | ||
44 | @unlink('sandbox/' . $folder . '/2'); | ||
45 | @rmdir('sandbox/' . $folder); | ||
46 | } | ||
47 | } | ||
48 | |||
49 | /** | ||
50 | * Test default display of server administration page. | ||
51 | */ | ||
52 | public function testIndex(): void | ||
53 | { | ||
54 | $request = $this->createMock(Request::class); | ||
55 | $response = new Response(); | ||
56 | |||
57 | // Save RainTPL assigned variables | ||
58 | $assignedVariables = []; | ||
59 | $this->assignTemplateVars($assignedVariables); | ||
60 | |||
61 | $result = $this->controller->index($request, $response); | ||
62 | |||
63 | static::assertSame(200, $result->getStatusCode()); | ||
64 | static::assertSame('server', (string) $result->getBody()); | ||
65 | |||
66 | static::assertSame(PHP_VERSION, $assignedVariables['php_version']); | ||
67 | static::assertArrayHasKey('php_has_reached_eol', $assignedVariables); | ||
68 | static::assertArrayHasKey('php_eol', $assignedVariables); | ||
69 | static::assertArrayHasKey('php_extensions', $assignedVariables); | ||
70 | static::assertArrayHasKey('permissions', $assignedVariables); | ||
71 | static::assertEmpty($assignedVariables['permissions']); | ||
72 | |||
73 | static::assertRegExp( | ||
74 | '#https://github\.com/shaarli/Shaarli/releases/tag/v\d+\.\d+\.\d+#', | ||
75 | $assignedVariables['release_url'] | ||
76 | ); | ||
77 | static::assertRegExp('#v\d+\.\d+\.\d+#', $assignedVariables['latest_version']); | ||
78 | static::assertRegExp('#(v\d+\.\d+\.\d+|dev)#', $assignedVariables['current_version']); | ||
79 | static::assertArrayHasKey('index_url', $assignedVariables); | ||
80 | static::assertArrayHasKey('client_ip', $assignedVariables); | ||
81 | static::assertArrayHasKey('trusted_proxies', $assignedVariables); | ||
82 | |||
83 | static::assertSame('Server administration - Shaarli', $assignedVariables['pagetitle']); | ||
84 | } | ||
85 | |||
86 | /** | ||
87 | * Test clearing the main cache | ||
88 | */ | ||
89 | public function testClearMainCache(): void | ||
90 | { | ||
91 | $this->container->conf = $this->createMock(ConfigManager::class); | ||
92 | $this->container->conf->method('get')->willReturnCallback(function (string $key, $default) { | ||
93 | if ($key === 'resource.page_cache') { | ||
94 | return 'sandbox/pagecache'; | ||
95 | } elseif ($key === 'resource.raintpl_tmp') { | ||
96 | return 'sandbox/tmp'; | ||
97 | } elseif ($key === 'resource.thumbnails_cache') { | ||
98 | return 'sandbox/cache'; | ||
99 | } else { | ||
100 | return $default; | ||
101 | } | ||
102 | }); | ||
103 | |||
104 | $this->container->sessionManager | ||
105 | ->expects(static::once()) | ||
106 | ->method('setSessionParameter') | ||
107 | ->with(SessionManager::KEY_SUCCESS_MESSAGES, ['Shaarli\'s cache folder has been cleared!']) | ||
108 | ; | ||
109 | |||
110 | $request = $this->createMock(Request::class); | ||
111 | $request->method('getQueryParam')->with('type')->willReturn('main'); | ||
112 | $response = new Response(); | ||
113 | |||
114 | $result = $this->controller->clearCache($request, $response); | ||
115 | |||
116 | static::assertSame(302, $result->getStatusCode()); | ||
117 | static::assertSame('/subfolder/admin/server', (string) $result->getHeaderLine('Location')); | ||
118 | |||
119 | static::assertFileNotExists('sandbox/pagecache/1'); | ||
120 | static::assertFileNotExists('sandbox/pagecache/2'); | ||
121 | static::assertFileNotExists('sandbox/tmp/1'); | ||
122 | static::assertFileNotExists('sandbox/tmp/2'); | ||
123 | |||
124 | static::assertFileExists('sandbox/pagecache/.htaccess'); | ||
125 | static::assertFileExists('sandbox/tmp/.htaccess'); | ||
126 | static::assertFileExists('sandbox/cache'); | ||
127 | static::assertFileExists('sandbox/cache/.htaccess'); | ||
128 | static::assertFileExists('sandbox/cache/1'); | ||
129 | static::assertFileExists('sandbox/cache/2'); | ||
130 | } | ||
131 | |||
132 | /** | ||
133 | * Test clearing thumbnails cache | ||
134 | */ | ||
135 | public function testClearThumbnailsCache(): void | ||
136 | { | ||
137 | $this->container->conf = $this->createMock(ConfigManager::class); | ||
138 | $this->container->conf->method('get')->willReturnCallback(function (string $key, $default) { | ||
139 | if ($key === 'resource.page_cache') { | ||
140 | return 'sandbox/pagecache'; | ||
141 | } elseif ($key === 'resource.raintpl_tmp') { | ||
142 | return 'sandbox/tmp'; | ||
143 | } elseif ($key === 'resource.thumbnails_cache') { | ||
144 | return 'sandbox/cache'; | ||
145 | } else { | ||
146 | return $default; | ||
147 | } | ||
148 | }); | ||
149 | |||
150 | $this->container->sessionManager | ||
151 | ->expects(static::once()) | ||
152 | ->method('setSessionParameter') | ||
153 | ->willReturnCallback(function (string $key, array $value): SessionManager { | ||
154 | static::assertSame(SessionManager::KEY_WARNING_MESSAGES, $key); | ||
155 | static::assertCount(1, $value); | ||
156 | static::assertStringStartsWith('Thumbnails cache has been cleared.', $value[0]); | ||
157 | |||
158 | return $this->container->sessionManager; | ||
159 | }); | ||
160 | ; | ||
161 | |||
162 | $request = $this->createMock(Request::class); | ||
163 | $request->method('getQueryParam')->with('type')->willReturn('thumbnails'); | ||
164 | $response = new Response(); | ||
165 | |||
166 | $result = $this->controller->clearCache($request, $response); | ||
167 | |||
168 | static::assertSame(302, $result->getStatusCode()); | ||
169 | static::assertSame('/subfolder/admin/server', (string) $result->getHeaderLine('Location')); | ||
170 | |||
171 | static::assertFileNotExists('sandbox/cache/1'); | ||
172 | static::assertFileNotExists('sandbox/cache/2'); | ||
173 | |||
174 | static::assertFileExists('sandbox/cache/.htaccess'); | ||
175 | static::assertFileExists('sandbox/pagecache'); | ||
176 | static::assertFileExists('sandbox/pagecache/.htaccess'); | ||
177 | static::assertFileExists('sandbox/pagecache/1'); | ||
178 | static::assertFileExists('sandbox/pagecache/2'); | ||
179 | static::assertFileExists('sandbox/tmp'); | ||
180 | static::assertFileExists('sandbox/tmp/.htaccess'); | ||
181 | static::assertFileExists('sandbox/tmp/1'); | ||
182 | static::assertFileExists('sandbox/tmp/2'); | ||
183 | } | ||
184 | } | ||
diff --git a/tests/front/controller/visitor/InstallControllerTest.php b/tests/front/controller/visitor/InstallControllerTest.php index 345ad544..2105ed77 100644 --- a/tests/front/controller/visitor/InstallControllerTest.php +++ b/tests/front/controller/visitor/InstallControllerTest.php | |||
@@ -79,6 +79,15 @@ class InstallControllerTest extends TestCase | |||
79 | static::assertIsArray($assignedVariables['languages']); | 79 | static::assertIsArray($assignedVariables['languages']); |
80 | static::assertSame('Automatic', $assignedVariables['languages']['auto']); | 80 | static::assertSame('Automatic', $assignedVariables['languages']['auto']); |
81 | static::assertSame('French', $assignedVariables['languages']['fr']); | 81 | static::assertSame('French', $assignedVariables['languages']['fr']); |
82 | |||
83 | static::assertSame(PHP_VERSION, $assignedVariables['php_version']); | ||
84 | static::assertArrayHasKey('php_has_reached_eol', $assignedVariables); | ||
85 | static::assertArrayHasKey('php_eol', $assignedVariables); | ||
86 | static::assertArrayHasKey('php_extensions', $assignedVariables); | ||
87 | static::assertArrayHasKey('permissions', $assignedVariables); | ||
88 | static::assertEmpty($assignedVariables['permissions']); | ||
89 | |||
90 | static::assertSame('Install Shaarli', $assignedVariables['pagetitle']); | ||
82 | } | 91 | } |
83 | 92 | ||
84 | /** | 93 | /** |
diff --git a/tpl/default/install.html b/tpl/default/install.html index a506a2eb..4f98d49d 100644 --- a/tpl/default/install.html +++ b/tpl/default/install.html | |||
@@ -163,6 +163,16 @@ | |||
163 | </div> | 163 | </div> |
164 | </div> | 164 | </div> |
165 | </form> | 165 | </form> |
166 | |||
167 | <div class="pure-g"> | ||
168 | <div class="pure-u-lg-1-6 pure-u-1-24"></div> | ||
169 | <div class="pure-u-lg-2-3 pure-u-22-24 page-form page-form-complete"> | ||
170 | <h2 class="window-title">{'Server requirements'|t}</h2> | ||
171 | |||
172 | {include="server.requirements"} | ||
173 | </div> | ||
174 | </div> | ||
175 | |||
166 | {include="page.footer"} | 176 | {include="page.footer"} |
167 | </body> | 177 | </body> |
168 | </html> | 178 | </html> |
diff --git a/tpl/default/server.html b/tpl/default/server.html new file mode 100644 index 00000000..de1c8b53 --- /dev/null +++ b/tpl/default/server.html | |||
@@ -0,0 +1,129 @@ | |||
1 | <!DOCTYPE html> | ||
2 | <html{if="$language !== 'auto'"} lang="{$language}"{/if}> | ||
3 | <head> | ||
4 | {include="includes"} | ||
5 | </head> | ||
6 | <body> | ||
7 | {include="page.header"} | ||
8 | |||
9 | <div class="pure-g"> | ||
10 | <div class="pure-u-lg-1-4 pure-u-1-24"></div> | ||
11 | <div class="pure-u-lg-1-2 pure-u-22-24 page-form server-tables-page"> | ||
12 | <h2 class="window-title">{'Server administration'|t}</h2> | ||
13 | |||
14 | <h3 class="window-subtitle">{'General'|t}</h3> | ||
15 | |||
16 | <div class="pure-g server-row"> | ||
17 | <div class="pure-u-lg-1-2 pure-u-1 server-label"> | ||
18 | <p>{'Index URL'|t}</p> | ||
19 | </div> | ||
20 | <div class="pure-u-lg-1-2 pure-u-1"> | ||
21 | <p><a href="{$index_url}" title="{$pagetitle}">{$index_url}</a></p> | ||
22 | </div> | ||
23 | </div> | ||
24 | <div class="pure-g server-row"> | ||
25 | <div class="pure-u-lg-1-2 pure-u-1 server-label"> | ||
26 | <p>{'Base path'|t}</p> | ||
27 | </div> | ||
28 | <div class="pure-u-lg-1-2 pure-u-1"> | ||
29 | <p>{$base_path}</p> | ||
30 | </div> | ||
31 | </div> | ||
32 | <div class="pure-g server-row"> | ||
33 | <div class="pure-u-lg-1-2 pure-u-1 server-label"> | ||
34 | <p>{'Client IP'|t}</p> | ||
35 | </div> | ||
36 | <div class="pure-u-lg-1-2 pure-u-1"> | ||
37 | <p>{$client_ip}</p> | ||
38 | </div> | ||
39 | </div> | ||
40 | <div class="pure-g server-row"> | ||
41 | <div class="pure-u-lg-1-2 pure-u-1 server-label"> | ||
42 | <p>{'Trusted reverse proxies'|t}</p> | ||
43 | </div> | ||
44 | <div class="pure-u-lg-1-2 pure-u-1"> | ||
45 | {if="count($trusted_proxies) > 0"} | ||
46 | <p> | ||
47 | {loop="$trusted_proxies"} | ||
48 | {$value}<br> | ||
49 | {/loop} | ||
50 | </p> | ||
51 | {else} | ||
52 | <p>{'N/A'|t}</p> | ||
53 | {/if} | ||
54 | </div> | ||
55 | </div> | ||
56 | |||
57 | {include="server.requirements"} | ||
58 | |||
59 | <h3 class="window-subtitle">Version</h3> | ||
60 | |||
61 | <div class="pure-g server-row"> | ||
62 | <div class="pure-u-lg-1-2 pure-u-1 server-label"> | ||
63 | <p>Current version</p> | ||
64 | </div> | ||
65 | <div class="pure-u-lg-1-2 pure-u-1"> | ||
66 | <p>{$current_version}</p> | ||
67 | </div> | ||
68 | </div> | ||
69 | |||
70 | <div class="pure-g server-row"> | ||
71 | <div class="pure-u-lg-1-2 pure-u-1 server-label"> | ||
72 | <p>Latest release</p> | ||
73 | </div> | ||
74 | <div class="pure-u-lg-1-2 pure-u-1"> | ||
75 | <p> | ||
76 | <a href="{$release_url}" title="{'Visit releases page on Github'|t}"> | ||
77 | {$latest_version} | ||
78 | </a> | ||
79 | </p> | ||
80 | </div> | ||
81 | </div> | ||
82 | |||
83 | <h3 class="window-subtitle">Thumbnails</h3> | ||
84 | |||
85 | <div class="pure-g server-row"> | ||
86 | <div class="pure-u-lg-1-2 pure-u-1 server-label"> | ||
87 | <p>Thumbnails status</p> | ||
88 | </div> | ||
89 | <div class="pure-u-lg-1-2 pure-u-1"> | ||
90 | <p> | ||
91 | {if="$thumbnails_mode==='all'"} | ||
92 | {'All'|t} | ||
93 | {elseif="$thumbnails_mode==='common'"} | ||
94 | {'Only common media hosts'|t} | ||
95 | {else} | ||
96 | {'None'|t} | ||
97 | {/if} | ||
98 | </p> | ||
99 | </div> | ||
100 | </div> | ||
101 | |||
102 | {if="$thumbnails_mode!=='none'"} | ||
103 | <div class="center tools-item"> | ||
104 | <a href="{$base_path}/admin/thumbnails" title="{'Synchronize all link thumbnails'|t}"> | ||
105 | <span class="pure-button pure-u-lg-2-3 pure-u-3-4">{'Synchronize thumbnails'|t}</span> | ||
106 | </a> | ||
107 | </div> | ||
108 | {/if} | ||
109 | |||
110 | <h3 class="window-subtitle">Cache</h3> | ||
111 | |||
112 | <div class="center tools-item"> | ||
113 | <a href="{$base_path}/admin/clear-cache?type=main"> | ||
114 | <span class="pure-button pure-u-lg-2-3 pure-u-3-4">Clear main cache</span> | ||
115 | </a> | ||
116 | </div> | ||
117 | |||
118 | <div class="center tools-item"> | ||
119 | <a href="{$base_path}/admin/clear-cache?type=thumbnails"> | ||
120 | <span class="pure-button pure-u-lg-2-3 pure-u-3-4">Clear thumbnails cache</span> | ||
121 | </a> | ||
122 | </div> | ||
123 | </div> | ||
124 | </div> | ||
125 | |||
126 | {include="page.footer"} | ||
127 | |||
128 | </body> | ||
129 | </html> | ||
diff --git a/tpl/default/server.requirements.html b/tpl/default/server.requirements.html new file mode 100644 index 00000000..85def9b7 --- /dev/null +++ b/tpl/default/server.requirements.html | |||
@@ -0,0 +1,68 @@ | |||
1 | <div class="server-tables"> | ||
2 | <h3 class="window-subtitle">{'Permissions'|t}</h3> | ||
3 | |||
4 | {if="count($permissions) > 0"} | ||
5 | <p class="center"> | ||
6 | <i class="fa fa-close fa-color-red" aria-hidden="true"></i> | ||
7 | {'There are permissions that need to be fixed.'|t} | ||
8 | </p> | ||
9 | |||
10 | <p> | ||
11 | {loop="$permissions"} | ||
12 | <div class="center">{$value}</div> | ||
13 | {/loop} | ||
14 | </p> | ||
15 | {else} | ||
16 | <p class="center"> | ||
17 | <i class="fa fa-check fa-color-green" aria-hidden="true"></i> | ||
18 | {'All read/write permissions are properly set.'|t} | ||
19 | </p> | ||
20 | {/if} | ||
21 | |||
22 | <h3 class="window-subtitle">PHP</h3> | ||
23 | |||
24 | <p class="center"> | ||
25 | <strong>{'Running PHP'|t} {$php_version}</strong> | ||
26 | {if="$php_has_reached_eol"} | ||
27 | <i class="fa fa-circle fa-color-orange" aria-label="hidden"></i><br> | ||
28 | {'End of life: '|t} {$php_eol} | ||
29 | {else} | ||
30 | <i class="fa fa-circle fa-color-green" aria-label="hidden"></i><br> | ||
31 | {/if} | ||
32 | </p> | ||
33 | |||
34 | <table class="center"> | ||
35 | <thead> | ||
36 | <tr> | ||
37 | <th>{'Extension'|t}</th> | ||
38 | <th>{'Usage'|t}</th> | ||
39 | <th>{'Status'|t}</th> | ||
40 | <th>{'Loaded'|t}</th> | ||
41 | </tr> | ||
42 | </thead> | ||
43 | <tbody> | ||
44 | {loop="$php_extensions"} | ||
45 | <tr> | ||
46 | <td>{$value.name}</td> | ||
47 | <td>{$value.desc}</td> | ||
48 | <td>{$value.required ? t('Required') : t('Optional')}</td> | ||
49 | <td> | ||
50 | {if="$value.loaded"} | ||
51 | {$classLoaded="fa-color-green"} | ||
52 | {$strLoaded=t('Loaded')} | ||
53 | {else} | ||
54 | {$strLoaded=t('Not loaded')} | ||
55 | {if="$value.required"} | ||
56 | {$classLoaded="fa-color-red"} | ||
57 | {else} | ||
58 | {$classLoaded="fa-color-orange"} | ||
59 | {/if} | ||
60 | {/if} | ||
61 | |||
62 | <i class="fa fa-circle {$classLoaded}" aria-label="{$strLoaded}" title="{$strLoaded}"></i> | ||
63 | </td> | ||
64 | </tr> | ||
65 | {/loop} | ||
66 | </tbody> | ||
67 | </table> | ||
68 | </div> | ||
diff --git a/tpl/default/tools.html b/tpl/default/tools.html index 2cb08e38..2df73598 100644 --- a/tpl/default/tools.html +++ b/tpl/default/tools.html | |||
@@ -20,6 +20,12 @@ | |||
20 | <span class="pure-button pure-u-lg-2-3 pure-u-3-4">{'Plugin administration'|t}</span> | 20 | <span class="pure-button pure-u-lg-2-3 pure-u-3-4">{'Plugin administration'|t}</span> |
21 | </a> | 21 | </a> |
22 | </div> | 22 | </div> |
23 | <div class="tools-item"> | ||
24 | <a href="{$base_path}/admin/server" | ||
25 | title="{'Check instance\'s server configuration'|t}"> | ||
26 | <span class="pure-button pure-u-lg-2-3 pure-u-3-4">{'Server administration'|t}</span> | ||
27 | </a> | ||
28 | </div> | ||
23 | {if="!$openshaarli"} | 29 | {if="!$openshaarli"} |
24 | <div class="tools-item"> | 30 | <div class="tools-item"> |
25 | <a href="{$base_path}/admin/password" title="{'Change your password'|t}"> | 31 | <a href="{$base_path}/admin/password" title="{'Change your password'|t}"> |
@@ -45,14 +51,6 @@ | |||
45 | </a> | 51 | </a> |
46 | </div> | 52 | </div> |
47 | 53 | ||
48 | {if="$thumbnails_enabled"} | ||
49 | <div class="tools-item"> | ||
50 | <a href="{$base_path}/admin/thumbnails" title="{'Synchronize all link thumbnails'|t}"> | ||
51 | <span class="pure-button pure-u-lg-2-3 pure-u-3-4">{'Synchronize thumbnails'|t}</span> | ||
52 | </a> | ||
53 | </div> | ||
54 | {/if} | ||
55 | |||
56 | {loop="$tools_plugin"} | 54 | {loop="$tools_plugin"} |
57 | <div class="tools-item"> | 55 | <div class="tools-item"> |
58 | {$value} | 56 | {$value} |