diff options
author | ArthurHoaro <arthur@hoa.ro> | 2020-10-21 13:12:15 +0200 |
---|---|---|
committer | ArthurHoaro <arthur@hoa.ro> | 2020-10-21 15:06:47 +0200 |
commit | 0cf76ccb4736473a958d9fd36ed914e2d25d594a (patch) | |
tree | 0bb11821bc45ad2a7c2b965137a901ae5546455a | |
parent | d8030c8155ee4c20573848b2444f6df0b65d1662 (diff) | |
download | Shaarli-0cf76ccb4736473a958d9fd36ed914e2d25d594a.tar.gz Shaarli-0cf76ccb4736473a958d9fd36ed914e2d25d594a.tar.zst Shaarli-0cf76ccb4736473a958d9fd36ed914e2d25d594a.zip |
Feature: add a Server administration page
It contains mostly read only information about the current Shaarli instance,
PHP version, extensions, file and folder permissions, etc.
Also action buttons to clear the cache or sync thumbnails.
Part of the content of this page is also displayed on the install page,
to check server requirement before installing Shaarli config file.
Fixes #40
Fixes #185
-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} |