Merge pull request #1604 from ArthurHoaro/feature/server-admin-page
Feature: add a Server administration page
This commit is contained in:
commit
e6215a2ad9
16 changed files with 1086 additions and 104 deletions
|
@ -14,8 +14,9 @@ class ApplicationUtils
|
|||
*/
|
||||
public static $VERSION_FILE = 'shaarli_version.php';
|
||||
|
||||
private static $GIT_URL = 'https://raw.githubusercontent.com/shaarli/Shaarli';
|
||||
private static $GIT_BRANCHES = array('latest', 'stable');
|
||||
public static $GITHUB_URL = 'https://github.com/shaarli/Shaarli';
|
||||
public static $GIT_RAW_URL = 'https://raw.githubusercontent.com/shaarli/Shaarli';
|
||||
public static $GIT_BRANCHES = array('latest', 'stable');
|
||||
private static $VERSION_START_TAG = '<?php /* ';
|
||||
private static $VERSION_END_TAG = ' */ ?>';
|
||||
|
||||
|
@ -125,7 +126,7 @@ class ApplicationUtils
|
|||
// Late Static Binding allows overriding within tests
|
||||
// See http://php.net/manual/en/language.oop5.late-static-bindings.php
|
||||
$latestVersion = static::getVersion(
|
||||
self::$GIT_URL . '/' . $branch . '/' . self::$VERSION_FILE
|
||||
self::$GIT_RAW_URL . '/' . $branch . '/' . self::$VERSION_FILE
|
||||
);
|
||||
|
||||
if (!$latestVersion) {
|
||||
|
@ -171,35 +172,45 @@ class ApplicationUtils
|
|||
/**
|
||||
* Checks Shaarli has the proper access permissions to its resources
|
||||
*
|
||||
* @param ConfigManager $conf Configuration Manager instance.
|
||||
* @param ConfigManager $conf Configuration Manager instance.
|
||||
* @param bool $minimalMode In minimal mode we only check permissions to be able to display a template.
|
||||
* Currently we only need to be able to read the theme and write in raintpl cache.
|
||||
*
|
||||
* @return array A list of the detected configuration issues
|
||||
*/
|
||||
public static function checkResourcePermissions($conf)
|
||||
public static function checkResourcePermissions(ConfigManager $conf, bool $minimalMode = false): array
|
||||
{
|
||||
$errors = array();
|
||||
$errors = [];
|
||||
$rainTplDir = rtrim($conf->get('resource.raintpl_tpl'), '/');
|
||||
|
||||
// Check script and template directories are readable
|
||||
foreach (array(
|
||||
foreach ([
|
||||
'application',
|
||||
'inc',
|
||||
'plugins',
|
||||
$rainTplDir,
|
||||
$rainTplDir . '/' . $conf->get('resource.theme'),
|
||||
) as $path) {
|
||||
] as $path) {
|
||||
if (!is_readable(realpath($path))) {
|
||||
$errors[] = '"' . $path . '" ' . t('directory is not readable');
|
||||
}
|
||||
}
|
||||
|
||||
// Check cache and data directories are readable and writable
|
||||
foreach (array(
|
||||
$conf->get('resource.thumbnails_cache'),
|
||||
$conf->get('resource.data_dir'),
|
||||
$conf->get('resource.page_cache'),
|
||||
$conf->get('resource.raintpl_tmp'),
|
||||
) as $path) {
|
||||
if ($minimalMode) {
|
||||
$folders = [
|
||||
$conf->get('resource.raintpl_tmp'),
|
||||
];
|
||||
} else {
|
||||
$folders = [
|
||||
$conf->get('resource.thumbnails_cache'),
|
||||
$conf->get('resource.data_dir'),
|
||||
$conf->get('resource.page_cache'),
|
||||
$conf->get('resource.raintpl_tmp'),
|
||||
];
|
||||
}
|
||||
|
||||
foreach ($folders as $path) {
|
||||
if (!is_readable(realpath($path))) {
|
||||
$errors[] = '"' . $path . '" ' . t('directory is not readable');
|
||||
}
|
||||
|
@ -208,6 +219,10 @@ class ApplicationUtils
|
|||
}
|
||||
}
|
||||
|
||||
if ($minimalMode) {
|
||||
return $errors;
|
||||
}
|
||||
|
||||
// Check configuration files are readable and writable
|
||||
foreach (array(
|
||||
$conf->getConfigFileExt(),
|
||||
|
@ -246,4 +261,54 @@ class ApplicationUtils
|
|||
{
|
||||
return hash_hmac('sha256', $currentVersion, $salt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of PHP extensions used by Shaarli.
|
||||
*
|
||||
* @return array[] List of extension with following keys:
|
||||
* - name: extension name
|
||||
* - required: whether the extension is required to use Shaarli
|
||||
* - desc: short description of extension usage in Shaarli
|
||||
* - loaded: whether the extension is properly loaded or not
|
||||
*/
|
||||
public static function getPhpExtensionsRequirement(): array
|
||||
{
|
||||
$extensions = [
|
||||
['name' => 'json', 'required' => true, 'desc' => t('Configuration parsing')],
|
||||
['name' => 'simplexml', 'required' => true, 'desc' => t('Slim Framework (routing, etc.)')],
|
||||
['name' => 'mbstring', 'required' => true, 'desc' => t('Multibyte (Unicode) string support')],
|
||||
['name' => 'gd', 'required' => false, 'desc' => t('Required to use thumbnails')],
|
||||
['name' => 'intl', 'required' => false, 'desc' => t('Localized text sorting (e.g. e->è->f)')],
|
||||
['name' => 'curl', 'required' => false, 'desc' => t('Better retrieval of bookmark metadata and thumbnail')],
|
||||
['name' => 'gettext', 'required' => false, 'desc' => t('Use the translation system in gettext mode')],
|
||||
['name' => 'ldap', 'required' => false, 'desc' => t('Login using LDAP server')],
|
||||
];
|
||||
|
||||
foreach ($extensions as &$extension) {
|
||||
$extension['loaded'] = extension_loaded($extension['name']);
|
||||
}
|
||||
|
||||
return $extensions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the EOL date of given PHP version. If the version is unknown,
|
||||
* we return today + 2 years.
|
||||
*
|
||||
* @param string $fullVersion PHP version, e.g. 7.4.7
|
||||
*
|
||||
* @return string Date format: YYYY-MM-DD
|
||||
*/
|
||||
public static function getPhpEol(string $fullVersion): string
|
||||
{
|
||||
preg_match('/(\d+\.\d+)\.\d+/', $fullVersion, $matches);
|
||||
|
||||
return [
|
||||
'7.1' => '2019-12-01',
|
||||
'7.2' => '2020-11-30',
|
||||
'7.3' => '2021-12-06',
|
||||
'7.4' => '2022-11-28',
|
||||
'8.0' => '2023-12-01',
|
||||
][$matches[1]] ?? (new \DateTime('+2 year'))->format('Y-m-d');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -81,4 +81,60 @@ class FileUtils
|
|||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively deletes a folder content, and deletes itself optionally.
|
||||
* If an excluded file is found, folders won't be deleted.
|
||||
*
|
||||
* Additional security: raise an exception if it tries to delete a folder outside of Shaarli directory.
|
||||
*
|
||||
* @param string $path
|
||||
* @param bool $selfDelete Delete the provided folder if true, only its content if false.
|
||||
* @param array $exclude
|
||||
*/
|
||||
public static function clearFolder(string $path, bool $selfDelete, array $exclude = []): bool
|
||||
{
|
||||
$skipped = false;
|
||||
|
||||
if (!is_dir($path)) {
|
||||
throw new IOException(t('Provided path is not a directory.'));
|
||||
}
|
||||
|
||||
if (!static::isPathInShaarliFolder($path)) {
|
||||
throw new IOException(t('Trying to delete a folder outside of Shaarli path.'));
|
||||
}
|
||||
|
||||
foreach (new \DirectoryIterator($path) as $file) {
|
||||
if($file->isDot()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (in_array($file->getBasename(), $exclude, true)) {
|
||||
$skipped = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($file->isFile()) {
|
||||
unlink($file->getPathname());
|
||||
} elseif($file->isDir()) {
|
||||
$skipped = static::clearFolder($file->getRealPath(), true, $exclude) || $skipped;
|
||||
}
|
||||
}
|
||||
|
||||
if ($selfDelete && !$skipped) {
|
||||
rmdir($path);
|
||||
}
|
||||
|
||||
return $skipped;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that the given path is inside Shaarli directory.
|
||||
*/
|
||||
public static function isPathInShaarliFolder(string $path): bool
|
||||
{
|
||||
$rootDirectory = dirname(dirname(__FILE__));
|
||||
|
||||
return strpos(realpath($path), $rootDirectory) !== false;
|
||||
}
|
||||
}
|
||||
|
|
87
application/front/controller/admin/ServerController.php
Normal file
87
application/front/controller/admin/ServerController.php
Normal file
|
@ -0,0 +1,87 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Shaarli\Front\Controller\Admin;
|
||||
|
||||
use Shaarli\ApplicationUtils;
|
||||
use Shaarli\FileUtils;
|
||||
use Slim\Http\Request;
|
||||
use Slim\Http\Response;
|
||||
|
||||
/**
|
||||
* Slim controller used to handle Server administration page, and actions.
|
||||
*/
|
||||
class ServerController extends ShaarliAdminController
|
||||
{
|
||||
/** @var string Cache type - main - by default pagecache/ and tmp/ */
|
||||
protected const CACHE_MAIN = 'main';
|
||||
|
||||
/** @var string Cache type - thumbnails - by default cache/ */
|
||||
protected const CACHE_THUMB = 'thumbnails';
|
||||
|
||||
/**
|
||||
* GET /admin/server - Display page Server administration
|
||||
*/
|
||||
public function index(Request $request, Response $response): Response
|
||||
{
|
||||
$latestVersion = 'v' . ApplicationUtils::getVersion(
|
||||
ApplicationUtils::$GIT_RAW_URL . '/latest/' . ApplicationUtils::$VERSION_FILE
|
||||
);
|
||||
$currentVersion = ApplicationUtils::getVersion('./shaarli_version.php');
|
||||
$currentVersion = $currentVersion === 'dev' ? $currentVersion : 'v' . $currentVersion;
|
||||
$phpEol = new \DateTimeImmutable(ApplicationUtils::getPhpEol(PHP_VERSION));
|
||||
|
||||
$this->assignView('php_version', PHP_VERSION);
|
||||
$this->assignView('php_eol', format_date($phpEol, false));
|
||||
$this->assignView('php_has_reached_eol', $phpEol < new \DateTimeImmutable());
|
||||
$this->assignView('php_extensions', ApplicationUtils::getPhpExtensionsRequirement());
|
||||
$this->assignView('permissions', ApplicationUtils::checkResourcePermissions($this->container->conf));
|
||||
$this->assignView('release_url', ApplicationUtils::$GITHUB_URL . '/releases/tag/' . $latestVersion);
|
||||
$this->assignView('latest_version', $latestVersion);
|
||||
$this->assignView('current_version', $currentVersion);
|
||||
$this->assignView('thumbnails_mode', $this->container->conf->get('thumbnails.mode'));
|
||||
$this->assignView('index_url', index_url($this->container->environment));
|
||||
$this->assignView('client_ip', client_ip_id($this->container->environment));
|
||||
$this->assignView('trusted_proxies', $this->container->conf->get('security.trusted_proxies', []));
|
||||
|
||||
$this->assignView(
|
||||
'pagetitle',
|
||||
t('Server administration') . ' - ' . $this->container->conf->get('general.title', 'Shaarli')
|
||||
);
|
||||
|
||||
return $response->write($this->render('server'));
|
||||
}
|
||||
|
||||
/**
|
||||
* GET /admin/clear-cache?type={$type} - Action to trigger cache folder clearing (either main or thumbnails).
|
||||
*/
|
||||
public function clearCache(Request $request, Response $response): Response
|
||||
{
|
||||
$exclude = ['.htaccess'];
|
||||
|
||||
if ($request->getQueryParam('type') === static::CACHE_THUMB) {
|
||||
$folders = [$this->container->conf->get('resource.thumbnails_cache')];
|
||||
|
||||
$this->saveWarningMessage(
|
||||
t('Thumbnails cache has been cleared.') . ' ' .
|
||||
'<a href="'. $this->container->basePath .'/admin/thumbnails">' . t('Please synchronize them.') .'</a>'
|
||||
);
|
||||
} else {
|
||||
$folders = [
|
||||
$this->container->conf->get('resource.page_cache'),
|
||||
$this->container->conf->get('resource.raintpl_tmp'),
|
||||
];
|
||||
|
||||
$this->saveSuccessMessage(t('Shaarli\'s cache folder has been cleared!'));
|
||||
}
|
||||
|
||||
// Make sure that we don't delete root cache folder
|
||||
$folders = array_map('realpath', array_values(array_filter(array_map('trim', $folders))));
|
||||
foreach ($folders as $folder) {
|
||||
FileUtils::clearFolder($folder, false, $exclude);
|
||||
}
|
||||
|
||||
return $this->redirect($response, '/admin/server');
|
||||
}
|
||||
}
|
|
@ -169,16 +169,24 @@ class BookmarkListController extends ShaarliVisitorController
|
|||
*/
|
||||
protected function updateThumbnail(Bookmark $bookmark, bool $writeDatastore = true): bool
|
||||
{
|
||||
// Logged in, not async retrieval, thumbnails enabled, and thumbnail should be updated
|
||||
if ($this->container->loginManager->isLoggedIn()
|
||||
&& true !== $this->container->conf->get('general.enable_async_metadata', true)
|
||||
&& $this->container->conf->get('thumbnails.mode', Thumbnailer::MODE_NONE) !== Thumbnailer::MODE_NONE
|
||||
&& $bookmark->shouldUpdateThumbnail()
|
||||
) {
|
||||
$bookmark->setThumbnail($this->container->thumbnailer->get($bookmark->getUrl()));
|
||||
$this->container->bookmarkService->set($bookmark, $writeDatastore);
|
||||
if (false === $this->container->loginManager->isLoggedIn()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
// If thumbnail should be updated, we reset it to null
|
||||
if ($bookmark->shouldUpdateThumbnail()) {
|
||||
$bookmark->setThumbnail(null);
|
||||
|
||||
// Requires an update, not async retrieval, thumbnails enabled
|
||||
if ($bookmark->shouldUpdateThumbnail()
|
||||
&& true !== $this->container->conf->get('general.enable_async_metadata', true)
|
||||
&& $this->container->conf->get('thumbnails.mode', Thumbnailer::MODE_NONE) !== Thumbnailer::MODE_NONE
|
||||
) {
|
||||
$bookmark->setThumbnail($this->container->thumbnailer->get($bookmark->getUrl()));
|
||||
$this->container->bookmarkService->set($bookmark, $writeDatastore);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
|
@ -53,6 +53,16 @@ class InstallController extends ShaarliVisitorController
|
|||
$this->assignView('cities', $cities);
|
||||
$this->assignView('languages', Languages::getAvailableLanguages());
|
||||
|
||||
$phpEol = new \DateTimeImmutable(ApplicationUtils::getPhpEol(PHP_VERSION));
|
||||
|
||||
$this->assignView('php_version', PHP_VERSION);
|
||||
$this->assignView('php_eol', format_date($phpEol, false));
|
||||
$this->assignView('php_has_reached_eol', $phpEol < new \DateTimeImmutable());
|
||||
$this->assignView('php_extensions', ApplicationUtils::getPhpExtensionsRequirement());
|
||||
$this->assignView('permissions', ApplicationUtils::checkResourcePermissions($this->container->conf));
|
||||
|
||||
$this->assignView('pagetitle', t('Install Shaarli'));
|
||||
|
||||
return $response->write($this->render('install'));
|
||||
}
|
||||
|
||||
|
@ -150,7 +160,7 @@ class InstallController extends ShaarliVisitorController
|
|||
protected function checkPermissions(): bool
|
||||
{
|
||||
// Ensure Shaarli has proper access to its resources
|
||||
$errors = ApplicationUtils::checkResourcePermissions($this->container->conf);
|
||||
$errors = ApplicationUtils::checkResourcePermissions($this->container->conf, true);
|
||||
if (empty($errors)) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1047,7 +1047,7 @@ body,
|
|||
}
|
||||
|
||||
table {
|
||||
margin: auto;
|
||||
margin: 10px auto 25px auto;
|
||||
width: 90%;
|
||||
|
||||
.order {
|
||||
|
@ -1696,6 +1696,60 @@ form {
|
|||
}
|
||||
}
|
||||
|
||||
// SERVER PAGE
|
||||
|
||||
.server-tables-page,
|
||||
.server-tables {
|
||||
.window-subtitle {
|
||||
&::before {
|
||||
display: block;
|
||||
margin: 8px auto;
|
||||
background: linear-gradient(to right, var(--background-color), $dark-grey, var(--background-color));
|
||||
width: 50%;
|
||||
height: 1px;
|
||||
content: '';
|
||||
}
|
||||
}
|
||||
|
||||
.server-row {
|
||||
p {
|
||||
height: 25px;
|
||||
padding: 0 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.server-label {
|
||||
text-align: right;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
i {
|
||||
&.fa-color-green {
|
||||
color: $main-green;
|
||||
}
|
||||
|
||||
&.fa-color-orange {
|
||||
color: $orange;
|
||||
}
|
||||
|
||||
&.fa-color-red {
|
||||
color: $red;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 64em) {
|
||||
.server-label {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.server-row {
|
||||
p {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Print rules
|
||||
@media print {
|
||||
.shaarli-menu {
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Shaarli\n"
|
||||
"POT-Creation-Date: 2020-10-16 20:01+0200\n"
|
||||
"PO-Revision-Date: 2020-10-16 20:02+0200\n"
|
||||
"POT-Creation-Date: 2020-10-21 15:00+0200\n"
|
||||
"PO-Revision-Date: 2020-10-21 15:06+0200\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Shaarli\n"
|
||||
"Language: fr_FR\n"
|
||||
|
@ -20,7 +20,7 @@ msgstr ""
|
|||
"X-Poedit-SearchPath-3: init.php\n"
|
||||
"X-Poedit-SearchPath-4: plugins\n"
|
||||
|
||||
#: application/ApplicationUtils.php:161
|
||||
#: application/ApplicationUtils.php:162
|
||||
#, php-format
|
||||
msgid ""
|
||||
"Your PHP version is obsolete! Shaarli requires at least PHP %s, and thus "
|
||||
|
@ -31,22 +31,62 @@ msgstr ""
|
|||
"peut donc pas fonctionner. Votre version de PHP a des failles de sécurités "
|
||||
"connues et devrait être mise à jour au plus tôt."
|
||||
|
||||
#: application/ApplicationUtils.php:192 application/ApplicationUtils.php:204
|
||||
#: application/ApplicationUtils.php:195 application/ApplicationUtils.php:215
|
||||
msgid "directory is not readable"
|
||||
msgstr "le répertoire n'est pas accessible en lecture"
|
||||
|
||||
#: application/ApplicationUtils.php:207
|
||||
#: application/ApplicationUtils.php:218
|
||||
msgid "directory is not writable"
|
||||
msgstr "le répertoire n'est pas accessible en écriture"
|
||||
|
||||
#: application/ApplicationUtils.php:225
|
||||
#: application/ApplicationUtils.php:240
|
||||
msgid "file is not readable"
|
||||
msgstr "le fichier n'est pas accessible en lecture"
|
||||
|
||||
#: application/ApplicationUtils.php:228
|
||||
#: application/ApplicationUtils.php:243
|
||||
msgid "file is not writable"
|
||||
msgstr "le fichier n'est pas accessible en écriture"
|
||||
|
||||
#: application/ApplicationUtils.php:277
|
||||
msgid "Configuration parsing"
|
||||
msgstr "Chargement de la configuration"
|
||||
|
||||
#: application/ApplicationUtils.php:278
|
||||
msgid "Slim Framework (routing, etc.)"
|
||||
msgstr "Slim Framwork (routage, etc.)"
|
||||
|
||||
#: application/ApplicationUtils.php:279
|
||||
msgid "Multibyte (Unicode) string support"
|
||||
msgstr "Support des chaînes de caractère multibytes (Unicode)"
|
||||
|
||||
#: application/ApplicationUtils.php:280
|
||||
msgid "Required to use thumbnails"
|
||||
msgstr "Obligatoire pour utiliser les miniatures"
|
||||
|
||||
#: application/ApplicationUtils.php:281
|
||||
msgid "Localized text sorting (e.g. e->è->f)"
|
||||
msgstr "Tri des textes traduits (ex : e->è->f)"
|
||||
|
||||
#: application/ApplicationUtils.php:282
|
||||
msgid "Better retrieval of bookmark metadata and thumbnail"
|
||||
msgstr "Meilleure récupération des meta-données des marque-pages et minatures"
|
||||
|
||||
#: application/ApplicationUtils.php:283
|
||||
msgid "Use the translation system in gettext mode"
|
||||
msgstr "Utiliser le système de traduction en mode gettext"
|
||||
|
||||
#: application/ApplicationUtils.php:284
|
||||
msgid "Login using LDAP server"
|
||||
msgstr "Authentification via un serveur LDAP"
|
||||
|
||||
#: application/FileUtils.php:100
|
||||
msgid "Provided path is not a directory."
|
||||
msgstr "Le chemin fourni n'est pas un dossier."
|
||||
|
||||
#: application/FileUtils.php:104
|
||||
msgid "Trying to delete a folder outside of Shaarli path."
|
||||
msgstr "Tentative de supprimer un dossier en dehors du chemin de Shaarli."
|
||||
|
||||
#: application/History.php:179
|
||||
msgid "History file isn't readable or writable"
|
||||
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."
|
|||
msgstr "Vous avez activé ou changé le mode de miniatures."
|
||||
|
||||
#: application/front/controller/admin/ConfigureController.php:103
|
||||
#: application/front/controller/admin/ServerController.php:68
|
||||
#: application/legacy/LegacyUpdater.php:538
|
||||
msgid "Please synchronize them."
|
||||
msgstr "Merci de les synchroniser."
|
||||
|
||||
#: application/front/controller/admin/ConfigureController.php:113
|
||||
#: application/front/controller/visitor/InstallController.php:136
|
||||
#: application/front/controller/visitor/InstallController.php:146
|
||||
msgid "Error while writing config file after configuration update."
|
||||
msgstr ""
|
||||
"Une erreur s'est produite lors de la sauvegarde du fichier de configuration."
|
||||
|
@ -377,33 +418,33 @@ msgstr ""
|
|||
msgid "Shaare a new link"
|
||||
msgstr "Partager un nouveau lien"
|
||||
|
||||
#: application/front/controller/admin/ManageShaareController.php:78
|
||||
#: application/front/controller/admin/ManageShaareController.php:64
|
||||
msgid "Note: "
|
||||
msgstr "Note : "
|
||||
|
||||
#: application/front/controller/admin/ManageShaareController.php:109
|
||||
#: application/front/controller/admin/ManageShaareController.php:206
|
||||
#: application/front/controller/admin/ManageShaareController.php:275
|
||||
#: application/front/controller/admin/ManageShaareController.php:315
|
||||
#: application/front/controller/admin/ManageShaareController.php:95
|
||||
#: application/front/controller/admin/ManageShaareController.php:193
|
||||
#: application/front/controller/admin/ManageShaareController.php:262
|
||||
#: application/front/controller/admin/ManageShaareController.php:302
|
||||
#, php-format
|
||||
msgid "Bookmark with identifier %s could not be found."
|
||||
msgstr "Le lien avec l'identifiant %s n'a pas pu être trouvé."
|
||||
|
||||
#: application/front/controller/admin/ManageShaareController.php:194
|
||||
#: application/front/controller/admin/ManageShaareController.php:252
|
||||
#: application/front/controller/admin/ManageShaareController.php:181
|
||||
#: application/front/controller/admin/ManageShaareController.php:239
|
||||
msgid "Invalid bookmark ID provided."
|
||||
msgstr "ID du lien non valide."
|
||||
|
||||
#: application/front/controller/admin/ManageShaareController.php:260
|
||||
#: application/front/controller/admin/ManageShaareController.php:247
|
||||
msgid "Invalid visibility provided."
|
||||
msgstr "Visibilité du lien non valide."
|
||||
|
||||
#: application/front/controller/admin/ManageShaareController.php:363
|
||||
#: application/front/controller/admin/ManageShaareController.php:352
|
||||
#: tmp/linklist.b91ef64efc3688266305ea9b42e5017e.rtpl.php:171
|
||||
msgid "Edit"
|
||||
msgstr "Modifier"
|
||||
|
||||
#: application/front/controller/admin/ManageShaareController.php:366
|
||||
#: application/front/controller/admin/ManageShaareController.php:355
|
||||
#: tmp/page.header.b91ef64efc3688266305ea9b42e5017e.rtpl.php:28
|
||||
#: tmp/page.header.cedf684561d925457130839629000a81.rtpl.php:28
|
||||
msgid "Shaare"
|
||||
|
@ -411,7 +452,7 @@ msgstr "Shaare"
|
|||
|
||||
#: application/front/controller/admin/ManageTagController.php:29
|
||||
#: tmp/changetag.b91ef64efc3688266305ea9b42e5017e.rtpl.php:13
|
||||
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:36
|
||||
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:42
|
||||
msgid "Manage tags"
|
||||
msgstr "Gérer les tags"
|
||||
|
||||
|
@ -435,7 +476,7 @@ msgstr[1] "Le tag a été renommé dans %d liens."
|
|||
|
||||
#: application/front/controller/admin/PasswordController.php:28
|
||||
#: tmp/changepassword.b91ef64efc3688266305ea9b42e5017e.rtpl.php:13
|
||||
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:29
|
||||
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:35
|
||||
msgid "Change password"
|
||||
msgstr "Modifier le mot de passe"
|
||||
|
||||
|
@ -467,6 +508,20 @@ msgstr ""
|
|||
"Une erreur s'est produite lors de la sauvegarde de la configuration des "
|
||||
"plugins : "
|
||||
|
||||
#: application/front/controller/admin/ServerController.php:50
|
||||
#: tmp/server.b91ef64efc3688266305ea9b42e5017e.rtpl.php:14
|
||||
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:28
|
||||
msgid "Server administration"
|
||||
msgstr "Administration serveur"
|
||||
|
||||
#: application/front/controller/admin/ServerController.php:67
|
||||
msgid "Thumbnails cache has been cleared."
|
||||
msgstr "Le cache des miniatures a été vidé."
|
||||
|
||||
#: application/front/controller/admin/ServerController.php:76
|
||||
msgid "Shaarli's cache folder has been cleared!"
|
||||
msgstr "Le dossier de cache de Shaarli a été vidé !"
|
||||
|
||||
#: application/front/controller/admin/ThumbnailsController.php:37
|
||||
#: tmp/thumbnails.b91ef64efc3688266305ea9b42e5017e.rtpl.php:14
|
||||
msgid "Thumbnails update"
|
||||
|
@ -502,9 +557,14 @@ msgstr "Une erreur inattendue s'est produite."
|
|||
|
||||
#: application/front/controller/visitor/ErrorNotFoundController.php:25
|
||||
msgid "Requested page could not be found."
|
||||
msgstr ""
|
||||
msgstr "La page demandée n'a pas pu être trouvée."
|
||||
|
||||
#: application/front/controller/visitor/InstallController.php:73
|
||||
#: application/front/controller/visitor/InstallController.php:64
|
||||
#: tmp/install.b91ef64efc3688266305ea9b42e5017e.rtpl.php:22
|
||||
msgid "Install Shaarli"
|
||||
msgstr "Installation de Shaarli"
|
||||
|
||||
#: application/front/controller/visitor/InstallController.php:83
|
||||
#, php-format
|
||||
msgid ""
|
||||
"<pre>Sessions do not seem to work correctly on your server.<br>Make sure the "
|
||||
|
@ -523,14 +583,14 @@ msgstr ""
|
|||
"des cookies. Nous vous recommandons d'accéder à votre serveur depuis son "
|
||||
"adresse IP ou un <em>Fully Qualified Domain Name</em>.<br>"
|
||||
|
||||
#: application/front/controller/visitor/InstallController.php:144
|
||||
#: application/front/controller/visitor/InstallController.php:154
|
||||
msgid ""
|
||||
"Shaarli is now configured. Please login and start shaaring your bookmarks!"
|
||||
msgstr ""
|
||||
"Shaarli est maintenant configuré. Vous pouvez vous connecter et commencez à "
|
||||
"shaare vos liens !"
|
||||
|
||||
#: application/front/controller/visitor/InstallController.php:158
|
||||
#: application/front/controller/visitor/InstallController.php:168
|
||||
msgid "Insufficient permissions:"
|
||||
msgstr "Permissions insuffisantes :"
|
||||
|
||||
|
@ -1016,25 +1076,28 @@ msgstr ""
|
|||
"miniatures."
|
||||
|
||||
#: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:328
|
||||
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:56
|
||||
#: tmp/server.b91ef64efc3688266305ea9b42e5017e.rtpl.php:122
|
||||
msgid "Synchronize thumbnails"
|
||||
msgstr "Synchroniser les miniatures"
|
||||
|
||||
#: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:339
|
||||
#: tmp/export.b91ef64efc3688266305ea9b42e5017e.rtpl.php:30
|
||||
#: tmp/server.b91ef64efc3688266305ea9b42e5017e.rtpl.php:102
|
||||
msgid "All"
|
||||
msgstr "Tous"
|
||||
|
||||
#: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:343
|
||||
#: tmp/server.b91ef64efc3688266305ea9b42e5017e.rtpl.php:106
|
||||
msgid "Only common media hosts"
|
||||
msgstr "Seulement les hébergeurs de média connus"
|
||||
|
||||
#: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:347
|
||||
#: tmp/server.b91ef64efc3688266305ea9b42e5017e.rtpl.php:110
|
||||
msgid "None"
|
||||
msgstr "Aucune"
|
||||
|
||||
#: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:355
|
||||
#: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:88
|
||||
#: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:102
|
||||
#: tmp/pluginsadmin.b91ef64efc3688266305ea9b42e5017e.rtpl.php:139
|
||||
#: tmp/pluginsadmin.b91ef64efc3688266305ea9b42e5017e.rtpl.php:199
|
||||
msgid "Save"
|
||||
|
@ -1060,27 +1123,27 @@ msgstr "Tous les liens d'un jour sur une page."
|
|||
msgid "Next day"
|
||||
msgstr "Jour suivant"
|
||||
|
||||
#: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:18
|
||||
#: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:21
|
||||
msgid "Edit Shaare"
|
||||
msgstr "Modifier le Shaare"
|
||||
|
||||
#: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:18
|
||||
#: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:21
|
||||
msgid "New Shaare"
|
||||
msgstr "Nouveau Shaare"
|
||||
|
||||
#: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:26
|
||||
#: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:29
|
||||
msgid "Created:"
|
||||
msgstr "Création :"
|
||||
|
||||
#: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:29
|
||||
#: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:32
|
||||
msgid "URL"
|
||||
msgstr "URL"
|
||||
|
||||
#: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:35
|
||||
#: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:38
|
||||
msgid "Title"
|
||||
msgstr "Titre"
|
||||
|
||||
#: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:41
|
||||
#: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:49
|
||||
#: tmp/pluginsadmin.b91ef64efc3688266305ea9b42e5017e.rtpl.php:42
|
||||
#: tmp/pluginsadmin.b91ef64efc3688266305ea9b42e5017e.rtpl.php:75
|
||||
#: tmp/pluginsadmin.b91ef64efc3688266305ea9b42e5017e.rtpl.php:99
|
||||
|
@ -1088,33 +1151,33 @@ msgstr "Titre"
|
|||
msgid "Description"
|
||||
msgstr "Description"
|
||||
|
||||
#: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:47
|
||||
#: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:58
|
||||
msgid "Tags"
|
||||
msgstr "Tags"
|
||||
|
||||
#: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:60
|
||||
#: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:74
|
||||
#: tmp/export.b91ef64efc3688266305ea9b42e5017e.rtpl.php:35
|
||||
#: tmp/linklist.b91ef64efc3688266305ea9b42e5017e.rtpl.php:169
|
||||
msgid "Private"
|
||||
msgstr "Privé"
|
||||
|
||||
#: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:66
|
||||
#: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:80
|
||||
msgid "Description will be rendered with"
|
||||
msgstr "La description sera générée avec"
|
||||
|
||||
#: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:68
|
||||
#: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:82
|
||||
msgid "Markdown syntax documentation"
|
||||
msgstr "Documentation sur la syntaxe Markdown"
|
||||
|
||||
#: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:69
|
||||
#: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:83
|
||||
msgid "Markdown syntax"
|
||||
msgstr "la syntaxe Markdown"
|
||||
|
||||
#: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:88
|
||||
#: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:102
|
||||
msgid "Apply Changes"
|
||||
msgstr "Appliquer les changements"
|
||||
|
||||
#: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:93
|
||||
#: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:107
|
||||
#: tmp/linklist.b91ef64efc3688266305ea9b42e5017e.rtpl.php:173
|
||||
#: tmp/page.header.b91ef64efc3688266305ea9b42e5017e.rtpl.php:147
|
||||
#: tmp/page.header.cedf684561d925457130839629000a81.rtpl.php:147
|
||||
|
@ -1179,10 +1242,6 @@ msgstr "Les doublons s'appuient sur les URL"
|
|||
msgid "Add default tags"
|
||||
msgstr "Ajouter des tags par défaut"
|
||||
|
||||
#: tmp/install.b91ef64efc3688266305ea9b42e5017e.rtpl.php:22
|
||||
msgid "Install Shaarli"
|
||||
msgstr "Installation de Shaarli"
|
||||
|
||||
#: tmp/install.b91ef64efc3688266305ea9b42e5017e.rtpl.php:25
|
||||
msgid "It looks like it's the first time you run Shaarli. Please configure it."
|
||||
msgstr ""
|
||||
|
@ -1215,6 +1274,10 @@ msgstr "Mes liens"
|
|||
msgid "Install"
|
||||
msgstr "Installer"
|
||||
|
||||
#: tmp/install.b91ef64efc3688266305ea9b42e5017e.rtpl.php:190
|
||||
msgid "Server requirements"
|
||||
msgstr "Pré-requis serveur"
|
||||
|
||||
#: tmp/linklist.b91ef64efc3688266305ea9b42e5017e.rtpl.php:14
|
||||
#: tmp/linklist.b91ef64efc3688266305ea9b42e5017e.rtpl.php:79
|
||||
msgid "shaare"
|
||||
|
@ -1511,6 +1574,100 @@ msgstr "Configuration des extensions"
|
|||
msgid "No parameter available."
|
||||
msgstr "Aucun paramètre disponible."
|
||||
|
||||
#: tmp/server.b91ef64efc3688266305ea9b42e5017e.rtpl.php:16
|
||||
msgid "General"
|
||||
msgstr "Général"
|
||||
|
||||
#: tmp/server.b91ef64efc3688266305ea9b42e5017e.rtpl.php:20
|
||||
msgid "Index URL"
|
||||
msgstr "URL de l'index"
|
||||
|
||||
#: tmp/server.b91ef64efc3688266305ea9b42e5017e.rtpl.php:28
|
||||
msgid "Base path"
|
||||
msgstr "Chemin de base"
|
||||
|
||||
#: tmp/server.b91ef64efc3688266305ea9b42e5017e.rtpl.php:36
|
||||
msgid "Client IP"
|
||||
msgstr "IP du client"
|
||||
|
||||
#: tmp/server.b91ef64efc3688266305ea9b42e5017e.rtpl.php:44
|
||||
msgid "Trusted reverse proxies"
|
||||
msgstr "Reverse proxies de confiance"
|
||||
|
||||
#: tmp/server.b91ef64efc3688266305ea9b42e5017e.rtpl.php:58
|
||||
msgid "N/A"
|
||||
msgstr "N/A"
|
||||
|
||||
#: tmp/server.b91ef64efc3688266305ea9b42e5017e.rtpl.php:84
|
||||
msgid "Visit releases page on Github"
|
||||
msgstr "Visiter la page des releases sur Github"
|
||||
|
||||
#: tmp/server.b91ef64efc3688266305ea9b42e5017e.rtpl.php:121
|
||||
msgid "Synchronize all link thumbnails"
|
||||
msgstr "Synchroniser toutes les miniatures"
|
||||
|
||||
#: tmp/server.requirements.b91ef64efc3688266305ea9b42e5017e.rtpl.php:2
|
||||
#: tmp/server.requirements.cedf684561d925457130839629000a81.rtpl.php:2
|
||||
msgid "Permissions"
|
||||
msgstr "Permissions"
|
||||
|
||||
#: tmp/server.requirements.b91ef64efc3688266305ea9b42e5017e.rtpl.php:8
|
||||
#: tmp/server.requirements.cedf684561d925457130839629000a81.rtpl.php:8
|
||||
msgid "There are permissions that need to be fixed."
|
||||
msgstr "Il y a des permissions qui doivent être corrigées."
|
||||
|
||||
#: tmp/server.requirements.b91ef64efc3688266305ea9b42e5017e.rtpl.php:23
|
||||
#: tmp/server.requirements.cedf684561d925457130839629000a81.rtpl.php:23
|
||||
msgid "All read/write permissions are properly set."
|
||||
msgstr "Toutes les permissions de lecture/écriture sont définies correctement."
|
||||
|
||||
#: tmp/server.requirements.b91ef64efc3688266305ea9b42e5017e.rtpl.php:32
|
||||
#: tmp/server.requirements.cedf684561d925457130839629000a81.rtpl.php:32
|
||||
msgid "Running PHP"
|
||||
msgstr "Fonctionnant avec PHP"
|
||||
|
||||
#: tmp/server.requirements.b91ef64efc3688266305ea9b42e5017e.rtpl.php:36
|
||||
#: tmp/server.requirements.cedf684561d925457130839629000a81.rtpl.php:36
|
||||
msgid "End of life: "
|
||||
msgstr "Fin de vie : "
|
||||
|
||||
#: tmp/server.requirements.b91ef64efc3688266305ea9b42e5017e.rtpl.php:48
|
||||
#: tmp/server.requirements.cedf684561d925457130839629000a81.rtpl.php:48
|
||||
msgid "Extension"
|
||||
msgstr "Extension"
|
||||
|
||||
#: tmp/server.requirements.b91ef64efc3688266305ea9b42e5017e.rtpl.php:49
|
||||
#: tmp/server.requirements.cedf684561d925457130839629000a81.rtpl.php:49
|
||||
msgid "Usage"
|
||||
msgstr "Utilisation"
|
||||
|
||||
#: tmp/server.requirements.b91ef64efc3688266305ea9b42e5017e.rtpl.php:50
|
||||
#: tmp/server.requirements.cedf684561d925457130839629000a81.rtpl.php:50
|
||||
msgid "Status"
|
||||
msgstr "Statut"
|
||||
|
||||
#: tmp/server.requirements.b91ef64efc3688266305ea9b42e5017e.rtpl.php:51
|
||||
#: tmp/server.requirements.b91ef64efc3688266305ea9b42e5017e.rtpl.php:66
|
||||
#: tmp/server.requirements.cedf684561d925457130839629000a81.rtpl.php:51
|
||||
#: tmp/server.requirements.cedf684561d925457130839629000a81.rtpl.php:66
|
||||
msgid "Loaded"
|
||||
msgstr "Chargé"
|
||||
|
||||
#: tmp/server.requirements.b91ef64efc3688266305ea9b42e5017e.rtpl.php:60
|
||||
#: tmp/server.requirements.cedf684561d925457130839629000a81.rtpl.php:60
|
||||
msgid "Required"
|
||||
msgstr "Obligatoire"
|
||||
|
||||
#: tmp/server.requirements.b91ef64efc3688266305ea9b42e5017e.rtpl.php:60
|
||||
#: tmp/server.requirements.cedf684561d925457130839629000a81.rtpl.php:60
|
||||
msgid "Optional"
|
||||
msgstr "Optionnel"
|
||||
|
||||
#: tmp/server.requirements.b91ef64efc3688266305ea9b42e5017e.rtpl.php:70
|
||||
#: tmp/server.requirements.cedf684561d925457130839629000a81.rtpl.php:70
|
||||
msgid "Not loaded"
|
||||
msgstr "Non chargé"
|
||||
|
||||
#: tmp/tag.cloud.b91ef64efc3688266305ea9b42e5017e.rtpl.php:19
|
||||
#: tmp/tag.list.b91ef64efc3688266305ea9b42e5017e.rtpl.php:19
|
||||
msgid "tags"
|
||||
|
@ -1561,15 +1718,19 @@ msgstr "Configurer Shaarli"
|
|||
msgid "Enable, disable and configure plugins"
|
||||
msgstr "Activer, désactiver et configurer les extensions"
|
||||
|
||||
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:28
|
||||
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:27
|
||||
msgid "Check instance's server configuration"
|
||||
msgstr "Vérifier la configuration serveur de l'instance"
|
||||
|
||||
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:34
|
||||
msgid "Change your password"
|
||||
msgstr "Modifier le mot de passe"
|
||||
|
||||
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:35
|
||||
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:41
|
||||
msgid "Rename or delete a tag in all links"
|
||||
msgstr "Renommer ou supprimer un tag dans tous les liens"
|
||||
|
||||
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:41
|
||||
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:47
|
||||
msgid ""
|
||||
"Import Netscape HTML bookmarks (as exported from Firefox, Chrome, Opera, "
|
||||
"delicious...)"
|
||||
|
@ -1577,11 +1738,11 @@ msgstr ""
|
|||
"Importer des marques pages au format Netscape HTML (comme exportés depuis "
|
||||
"Firefox, Chrome, Opera, delicious...)"
|
||||
|
||||
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:42
|
||||
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:48
|
||||
msgid "Import links"
|
||||
msgstr "Importer des liens"
|
||||
|
||||
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:47
|
||||
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:53
|
||||
msgid ""
|
||||
"Export Netscape HTML bookmarks (which can be imported in Firefox, Chrome, "
|
||||
"Opera, delicious...)"
|
||||
|
@ -1589,15 +1750,11 @@ msgstr ""
|
|||
"Exporter les marques pages au format Netscape HTML (comme exportés depuis "
|
||||
"Firefox, Chrome, Opera, delicious...)"
|
||||
|
||||
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:48
|
||||
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:54
|
||||
msgid "Export database"
|
||||
msgstr "Exporter les données"
|
||||
|
||||
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:55
|
||||
msgid "Synchronize all link thumbnails"
|
||||
msgstr "Synchroniser toutes les miniatures"
|
||||
|
||||
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:81
|
||||
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:77
|
||||
msgid ""
|
||||
"Drag one of these button to your bookmarks toolbar or right-click it and "
|
||||
"\"Bookmark This Link\""
|
||||
|
@ -1605,13 +1762,13 @@ msgstr ""
|
|||
"Glisser un de ces boutons dans votre barre de favoris ou cliquer droit "
|
||||
"dessus et « Ajouter aux favoris »"
|
||||
|
||||
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:82
|
||||
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:78
|
||||
msgid "then click on the bookmarklet in any page you want to share."
|
||||
msgstr ""
|
||||
"puis cliquer sur le marque-page depuis un site que vous souhaitez partager."
|
||||
|
||||
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:86
|
||||
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:110
|
||||
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:82
|
||||
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:106
|
||||
msgid ""
|
||||
"Drag this link to your bookmarks toolbar or right-click it and Bookmark This "
|
||||
"Link"
|
||||
|
@ -1619,40 +1776,40 @@ msgstr ""
|
|||
"Glisser ce lien dans votre barre de favoris ou cliquer droit dessus et « "
|
||||
"Ajouter aux favoris »"
|
||||
|
||||
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:87
|
||||
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:83
|
||||
msgid "then click ✚Shaare link button in any page you want to share"
|
||||
msgstr "puis cliquer sur ✚Shaare depuis un site que vous souhaitez partager"
|
||||
|
||||
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:96
|
||||
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:118
|
||||
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:92
|
||||
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:114
|
||||
msgid "The selected text is too long, it will be truncated."
|
||||
msgstr "Le texte sélectionné est trop long, il sera tronqué."
|
||||
|
||||
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:106
|
||||
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:102
|
||||
msgid "Shaare link"
|
||||
msgstr "Shaare"
|
||||
|
||||
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:111
|
||||
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:107
|
||||
msgid ""
|
||||
"Then click ✚Add Note button anytime to start composing a private Note (text "
|
||||
"post) to your Shaarli"
|
||||
msgstr ""
|
||||
"Puis cliquer sur ✚Add Note pour commencer à rédiger une Note sur Shaarli"
|
||||
|
||||
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:127
|
||||
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:123
|
||||
msgid "Add Note"
|
||||
msgstr "Ajouter une Note"
|
||||
|
||||
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:136
|
||||
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:132
|
||||
msgid "3rd party"
|
||||
msgstr "Applications tierces"
|
||||
|
||||
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:139
|
||||
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:144
|
||||
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:135
|
||||
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:140
|
||||
msgid "plugin"
|
||||
msgstr "extension"
|
||||
|
||||
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:169
|
||||
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:165
|
||||
msgid ""
|
||||
"Drag this link to your bookmarks toolbar, or right-click it and choose "
|
||||
"Bookmark This Link"
|
||||
|
@ -1660,9 +1817,6 @@ msgstr ""
|
|||
"Glisser ce lien dans votre barre de favoris ou cliquer droit dessus et « "
|
||||
"Ajouter aux favoris »"
|
||||
|
||||
#~ msgid "Provided data is invalid"
|
||||
#~ msgstr "Les informations fournies ne sont pas valides"
|
||||
|
||||
#~ msgid "Rename"
|
||||
#~ msgstr "Renommer"
|
||||
|
||||
|
|
|
@ -143,6 +143,8 @@ $app->group('/admin', function () {
|
|||
$this->get('/plugins', '\Shaarli\Front\Controller\Admin\PluginsController:index');
|
||||
$this->post('/plugins', '\Shaarli\Front\Controller\Admin\PluginsController:save');
|
||||
$this->get('/token', '\Shaarli\Front\Controller\Admin\TokenController:getToken');
|
||||
$this->get('/server', '\Shaarli\Front\Controller\Admin\ServerController:index');
|
||||
$this->get('/clear-cache', '\Shaarli\Front\Controller\Admin\ServerController:clearCache');
|
||||
$this->get('/thumbnails', '\Shaarli\Front\Controller\Admin\ThumbnailsController:index');
|
||||
$this->get('/metadata', '\Shaarli\Front\Controller\Admin\MetadataController:ajaxRetrieveTitle');
|
||||
$this->get('/visibility/{visibility}', '\Shaarli\Front\Controller\Admin\SessionFilterController:visibility');
|
||||
|
|
|
@ -339,6 +339,35 @@ class ApplicationUtilsTest extends \Shaarli\TestCase
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks resource permissions in minimal mode.
|
||||
*/
|
||||
public function testCheckCurrentResourcePermissionsErrorsMinimalMode(): void
|
||||
{
|
||||
$conf = new ConfigManager('');
|
||||
$conf->set('resource.thumbnails_cache', 'null/cache');
|
||||
$conf->set('resource.config', 'null/data/config.php');
|
||||
$conf->set('resource.data_dir', 'null/data');
|
||||
$conf->set('resource.datastore', 'null/data/store.php');
|
||||
$conf->set('resource.ban_file', 'null/data/ipbans.php');
|
||||
$conf->set('resource.log', 'null/data/log.txt');
|
||||
$conf->set('resource.page_cache', 'null/pagecache');
|
||||
$conf->set('resource.raintpl_tmp', 'null/tmp');
|
||||
$conf->set('resource.raintpl_tpl', 'null/tpl');
|
||||
$conf->set('resource.raintpl_theme', 'null/tpl/default');
|
||||
$conf->set('resource.update_check', 'null/data/lastupdatecheck.txt');
|
||||
|
||||
static::assertSame(
|
||||
[
|
||||
'"null/tpl" directory is not readable',
|
||||
'"null/tpl/default" directory is not readable',
|
||||
'"null/tmp" directory is not readable',
|
||||
'"null/tmp" directory is not writable'
|
||||
],
|
||||
ApplicationUtils::checkResourcePermissions($conf, true)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check update with 'dev' as curent version (master branch).
|
||||
* It should always return false.
|
||||
|
@ -349,4 +378,37 @@ class ApplicationUtilsTest extends \Shaarli\TestCase
|
|||
ApplicationUtils::checkUpdate('dev', self::$testUpdateFile, 100, true, true)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Basic test of getPhpExtensionsRequirement()
|
||||
*/
|
||||
public function testGetPhpExtensionsRequirementSimple(): void
|
||||
{
|
||||
static::assertCount(8, ApplicationUtils::getPhpExtensionsRequirement());
|
||||
static::assertSame([
|
||||
'name' => 'json',
|
||||
'required' => true,
|
||||
'desc' => 'Configuration parsing',
|
||||
'loaded' => true,
|
||||
], ApplicationUtils::getPhpExtensionsRequirement()[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test getPhpEol with a known version: 7.4 -> 2022
|
||||
*/
|
||||
public function testGetKnownPhpEol(): void
|
||||
{
|
||||
static::assertSame('2022-11-28', ApplicationUtils::getPhpEol('7.4.7'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test getPhpEol with an unknown version: 7.4 -> 2022
|
||||
*/
|
||||
public function testGetUnknownPhpEol(): void
|
||||
{
|
||||
static::assertSame(
|
||||
(((int) (new \DateTime())->format('Y')) + 2) . (new \DateTime())->format('-m-d'),
|
||||
ApplicationUtils::getPhpEol('7.51.34')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,25 +3,48 @@
|
|||
namespace Shaarli;
|
||||
|
||||
use Exception;
|
||||
use Shaarli\Exceptions\IOException;
|
||||
|
||||
/**
|
||||
* Class FileUtilsTest
|
||||
*
|
||||
* Test file utility class.
|
||||
*/
|
||||
class FileUtilsTest extends \Shaarli\TestCase
|
||||
class FileUtilsTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @var string Test file path.
|
||||
*/
|
||||
protected static $file = 'sandbox/flat.db';
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
@mkdir('sandbox');
|
||||
mkdir('sandbox/folder2');
|
||||
touch('sandbox/file1');
|
||||
touch('sandbox/file2');
|
||||
mkdir('sandbox/folder1');
|
||||
touch('sandbox/folder1/file1');
|
||||
touch('sandbox/folder1/file2');
|
||||
mkdir('sandbox/folder3');
|
||||
mkdir('/tmp/shaarli-to-delete');
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete test file after every test.
|
||||
*/
|
||||
protected function tearDown(): void
|
||||
{
|
||||
@unlink(self::$file);
|
||||
|
||||
@unlink('sandbox/folder1/file1');
|
||||
@unlink('sandbox/folder1/file2');
|
||||
@rmdir('sandbox/folder1');
|
||||
@unlink('sandbox/file1');
|
||||
@unlink('sandbox/file2');
|
||||
@rmdir('sandbox/folder2');
|
||||
@rmdir('sandbox/folder3');
|
||||
@rmdir('/tmp/shaarli-to-delete');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -107,4 +130,67 @@ class FileUtilsTest extends \Shaarli\TestCase
|
|||
$this->assertEquals(null, FileUtils::readFlatDB(self::$file));
|
||||
$this->assertEquals(['test'], FileUtils::readFlatDB(self::$file, ['test']));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test clearFolder with self delete and excluded files
|
||||
*/
|
||||
public function testClearFolderSelfDeleteWithExclusion(): void
|
||||
{
|
||||
FileUtils::clearFolder('sandbox', true, ['file2']);
|
||||
|
||||
static::assertFileExists('sandbox/folder1/file2');
|
||||
static::assertFileExists('sandbox/folder1');
|
||||
static::assertFileExists('sandbox/file2');
|
||||
static::assertFileExists('sandbox');
|
||||
|
||||
static::assertFileNotExists('sandbox/folder1/file1');
|
||||
static::assertFileNotExists('sandbox/file1');
|
||||
static::assertFileNotExists('sandbox/folder3');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test clearFolder with self delete and excluded files
|
||||
*/
|
||||
public function testClearFolderSelfDeleteWithoutExclusion(): void
|
||||
{
|
||||
FileUtils::clearFolder('sandbox', true);
|
||||
|
||||
static::assertFileNotExists('sandbox');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test clearFolder with self delete and excluded files
|
||||
*/
|
||||
public function testClearFolderNoSelfDeleteWithoutExclusion(): void
|
||||
{
|
||||
FileUtils::clearFolder('sandbox', false);
|
||||
|
||||
static::assertFileExists('sandbox');
|
||||
|
||||
// 2 because '.' and '..'
|
||||
static::assertCount(2, new \DirectoryIterator('sandbox'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test clearFolder on a file instead of a folder
|
||||
*/
|
||||
public function testClearFolderOnANonDirectory(): void
|
||||
{
|
||||
$this->expectException(IOException::class);
|
||||
$this->expectExceptionMessage('Provided path is not a directory.');
|
||||
|
||||
FileUtils::clearFolder('sandbox/file1', false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test clearFolder on a file instead of a folder
|
||||
*/
|
||||
public function testClearFolderOutsideOfShaarliDirectory(): void
|
||||
{
|
||||
$this->expectException(IOException::class);
|
||||
$this->expectExceptionMessage('Trying to delete a folder outside of Shaarli path.');
|
||||
|
||||
|
||||
FileUtils::clearFolder('/tmp/shaarli-to-delete', true);
|
||||
}
|
||||
}
|
||||
|
|
184
tests/front/controller/admin/ServerControllerTest.php
Normal file
184
tests/front/controller/admin/ServerControllerTest.php
Normal file
|
@ -0,0 +1,184 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Shaarli\Front\Controller\Admin;
|
||||
|
||||
use Shaarli\Config\ConfigManager;
|
||||
use Shaarli\Security\SessionManager;
|
||||
use Shaarli\TestCase;
|
||||
use Slim\Http\Request;
|
||||
use Slim\Http\Response;
|
||||
|
||||
/**
|
||||
* Test Server administration controller.
|
||||
*/
|
||||
class ServerControllerTest extends TestCase
|
||||
{
|
||||
use FrontAdminControllerMockHelper;
|
||||
|
||||
/** @var ServerController */
|
||||
protected $controller;
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
$this->createContainer();
|
||||
|
||||
$this->controller = new ServerController($this->container);
|
||||
|
||||
// initialize dummy cache
|
||||
@mkdir('sandbox/');
|
||||
foreach (['pagecache', 'tmp', 'cache'] as $folder) {
|
||||
@mkdir('sandbox/' . $folder);
|
||||
@touch('sandbox/' . $folder . '/.htaccess');
|
||||
@touch('sandbox/' . $folder . '/1');
|
||||
@touch('sandbox/' . $folder . '/2');
|
||||
}
|
||||
}
|
||||
|
||||
public function tearDown(): void
|
||||
{
|
||||
foreach (['pagecache', 'tmp', 'cache'] as $folder) {
|
||||
@unlink('sandbox/' . $folder . '/.htaccess');
|
||||
@unlink('sandbox/' . $folder . '/1');
|
||||
@unlink('sandbox/' . $folder . '/2');
|
||||
@rmdir('sandbox/' . $folder);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test default display of server administration page.
|
||||
*/
|
||||
public function testIndex(): void
|
||||
{
|
||||
$request = $this->createMock(Request::class);
|
||||
$response = new Response();
|
||||
|
||||
// Save RainTPL assigned variables
|
||||
$assignedVariables = [];
|
||||
$this->assignTemplateVars($assignedVariables);
|
||||
|
||||
$result = $this->controller->index($request, $response);
|
||||
|
||||
static::assertSame(200, $result->getStatusCode());
|
||||
static::assertSame('server', (string) $result->getBody());
|
||||
|
||||
static::assertSame(PHP_VERSION, $assignedVariables['php_version']);
|
||||
static::assertArrayHasKey('php_has_reached_eol', $assignedVariables);
|
||||
static::assertArrayHasKey('php_eol', $assignedVariables);
|
||||
static::assertArrayHasKey('php_extensions', $assignedVariables);
|
||||
static::assertArrayHasKey('permissions', $assignedVariables);
|
||||
static::assertEmpty($assignedVariables['permissions']);
|
||||
|
||||
static::assertRegExp(
|
||||
'#https://github\.com/shaarli/Shaarli/releases/tag/v\d+\.\d+\.\d+#',
|
||||
$assignedVariables['release_url']
|
||||
);
|
||||
static::assertRegExp('#v\d+\.\d+\.\d+#', $assignedVariables['latest_version']);
|
||||
static::assertRegExp('#(v\d+\.\d+\.\d+|dev)#', $assignedVariables['current_version']);
|
||||
static::assertArrayHasKey('index_url', $assignedVariables);
|
||||
static::assertArrayHasKey('client_ip', $assignedVariables);
|
||||
static::assertArrayHasKey('trusted_proxies', $assignedVariables);
|
||||
|
||||
static::assertSame('Server administration - Shaarli', $assignedVariables['pagetitle']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test clearing the main cache
|
||||
*/
|
||||
public function testClearMainCache(): void
|
||||
{
|
||||
$this->container->conf = $this->createMock(ConfigManager::class);
|
||||
$this->container->conf->method('get')->willReturnCallback(function (string $key, $default) {
|
||||
if ($key === 'resource.page_cache') {
|
||||
return 'sandbox/pagecache';
|
||||
} elseif ($key === 'resource.raintpl_tmp') {
|
||||
return 'sandbox/tmp';
|
||||
} elseif ($key === 'resource.thumbnails_cache') {
|
||||
return 'sandbox/cache';
|
||||
} else {
|
||||
return $default;
|
||||
}
|
||||
});
|
||||
|
||||
$this->container->sessionManager
|
||||
->expects(static::once())
|
||||
->method('setSessionParameter')
|
||||
->with(SessionManager::KEY_SUCCESS_MESSAGES, ['Shaarli\'s cache folder has been cleared!'])
|
||||
;
|
||||
|
||||
$request = $this->createMock(Request::class);
|
||||
$request->method('getQueryParam')->with('type')->willReturn('main');
|
||||
$response = new Response();
|
||||
|
||||
$result = $this->controller->clearCache($request, $response);
|
||||
|
||||
static::assertSame(302, $result->getStatusCode());
|
||||
static::assertSame('/subfolder/admin/server', (string) $result->getHeaderLine('Location'));
|
||||
|
||||
static::assertFileNotExists('sandbox/pagecache/1');
|
||||
static::assertFileNotExists('sandbox/pagecache/2');
|
||||
static::assertFileNotExists('sandbox/tmp/1');
|
||||
static::assertFileNotExists('sandbox/tmp/2');
|
||||
|
||||
static::assertFileExists('sandbox/pagecache/.htaccess');
|
||||
static::assertFileExists('sandbox/tmp/.htaccess');
|
||||
static::assertFileExists('sandbox/cache');
|
||||
static::assertFileExists('sandbox/cache/.htaccess');
|
||||
static::assertFileExists('sandbox/cache/1');
|
||||
static::assertFileExists('sandbox/cache/2');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test clearing thumbnails cache
|
||||
*/
|
||||
public function testClearThumbnailsCache(): void
|
||||
{
|
||||
$this->container->conf = $this->createMock(ConfigManager::class);
|
||||
$this->container->conf->method('get')->willReturnCallback(function (string $key, $default) {
|
||||
if ($key === 'resource.page_cache') {
|
||||
return 'sandbox/pagecache';
|
||||
} elseif ($key === 'resource.raintpl_tmp') {
|
||||
return 'sandbox/tmp';
|
||||
} elseif ($key === 'resource.thumbnails_cache') {
|
||||
return 'sandbox/cache';
|
||||
} else {
|
||||
return $default;
|
||||
}
|
||||
});
|
||||
|
||||
$this->container->sessionManager
|
||||
->expects(static::once())
|
||||
->method('setSessionParameter')
|
||||
->willReturnCallback(function (string $key, array $value): SessionManager {
|
||||
static::assertSame(SessionManager::KEY_WARNING_MESSAGES, $key);
|
||||
static::assertCount(1, $value);
|
||||
static::assertStringStartsWith('Thumbnails cache has been cleared.', $value[0]);
|
||||
|
||||
return $this->container->sessionManager;
|
||||
});
|
||||
;
|
||||
|
||||
$request = $this->createMock(Request::class);
|
||||
$request->method('getQueryParam')->with('type')->willReturn('thumbnails');
|
||||
$response = new Response();
|
||||
|
||||
$result = $this->controller->clearCache($request, $response);
|
||||
|
||||
static::assertSame(302, $result->getStatusCode());
|
||||
static::assertSame('/subfolder/admin/server', (string) $result->getHeaderLine('Location'));
|
||||
|
||||
static::assertFileNotExists('sandbox/cache/1');
|
||||
static::assertFileNotExists('sandbox/cache/2');
|
||||
|
||||
static::assertFileExists('sandbox/cache/.htaccess');
|
||||
static::assertFileExists('sandbox/pagecache');
|
||||
static::assertFileExists('sandbox/pagecache/.htaccess');
|
||||
static::assertFileExists('sandbox/pagecache/1');
|
||||
static::assertFileExists('sandbox/pagecache/2');
|
||||
static::assertFileExists('sandbox/tmp');
|
||||
static::assertFileExists('sandbox/tmp/.htaccess');
|
||||
static::assertFileExists('sandbox/tmp/1');
|
||||
static::assertFileExists('sandbox/tmp/2');
|
||||
}
|
||||
}
|
|
@ -79,6 +79,15 @@ class InstallControllerTest extends TestCase
|
|||
static::assertIsArray($assignedVariables['languages']);
|
||||
static::assertSame('Automatic', $assignedVariables['languages']['auto']);
|
||||
static::assertSame('French', $assignedVariables['languages']['fr']);
|
||||
|
||||
static::assertSame(PHP_VERSION, $assignedVariables['php_version']);
|
||||
static::assertArrayHasKey('php_has_reached_eol', $assignedVariables);
|
||||
static::assertArrayHasKey('php_eol', $assignedVariables);
|
||||
static::assertArrayHasKey('php_extensions', $assignedVariables);
|
||||
static::assertArrayHasKey('permissions', $assignedVariables);
|
||||
static::assertEmpty($assignedVariables['permissions']);
|
||||
|
||||
static::assertSame('Install Shaarli', $assignedVariables['pagetitle']);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -163,6 +163,16 @@
|
|||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="pure-g">
|
||||
<div class="pure-u-lg-1-6 pure-u-1-24"></div>
|
||||
<div class="pure-u-lg-2-3 pure-u-22-24 page-form page-form-complete">
|
||||
<h2 class="window-title">{'Server requirements'|t}</h2>
|
||||
|
||||
{include="server.requirements"}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{include="page.footer"}
|
||||
</body>
|
||||
</html>
|
||||
|
|
129
tpl/default/server.html
Normal file
129
tpl/default/server.html
Normal file
|
@ -0,0 +1,129 @@
|
|||
<!DOCTYPE html>
|
||||
<html{if="$language !== 'auto'"} lang="{$language}"{/if}>
|
||||
<head>
|
||||
{include="includes"}
|
||||
</head>
|
||||
<body>
|
||||
{include="page.header"}
|
||||
|
||||
<div class="pure-g">
|
||||
<div class="pure-u-lg-1-4 pure-u-1-24"></div>
|
||||
<div class="pure-u-lg-1-2 pure-u-22-24 page-form server-tables-page">
|
||||
<h2 class="window-title">{'Server administration'|t}</h2>
|
||||
|
||||
<h3 class="window-subtitle">{'General'|t}</h3>
|
||||
|
||||
<div class="pure-g server-row">
|
||||
<div class="pure-u-lg-1-2 pure-u-1 server-label">
|
||||
<p>{'Index URL'|t}</p>
|
||||
</div>
|
||||
<div class="pure-u-lg-1-2 pure-u-1">
|
||||
<p><a href="{$index_url}" title="{$pagetitle}">{$index_url}</a></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pure-g server-row">
|
||||
<div class="pure-u-lg-1-2 pure-u-1 server-label">
|
||||
<p>{'Base path'|t}</p>
|
||||
</div>
|
||||
<div class="pure-u-lg-1-2 pure-u-1">
|
||||
<p>{$base_path}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pure-g server-row">
|
||||
<div class="pure-u-lg-1-2 pure-u-1 server-label">
|
||||
<p>{'Client IP'|t}</p>
|
||||
</div>
|
||||
<div class="pure-u-lg-1-2 pure-u-1">
|
||||
<p>{$client_ip}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pure-g server-row">
|
||||
<div class="pure-u-lg-1-2 pure-u-1 server-label">
|
||||
<p>{'Trusted reverse proxies'|t}</p>
|
||||
</div>
|
||||
<div class="pure-u-lg-1-2 pure-u-1">
|
||||
{if="count($trusted_proxies) > 0"}
|
||||
<p>
|
||||
{loop="$trusted_proxies"}
|
||||
{$value}<br>
|
||||
{/loop}
|
||||
</p>
|
||||
{else}
|
||||
<p>{'N/A'|t}</p>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{include="server.requirements"}
|
||||
|
||||
<h3 class="window-subtitle">Version</h3>
|
||||
|
||||
<div class="pure-g server-row">
|
||||
<div class="pure-u-lg-1-2 pure-u-1 server-label">
|
||||
<p>Current version</p>
|
||||
</div>
|
||||
<div class="pure-u-lg-1-2 pure-u-1">
|
||||
<p>{$current_version}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="pure-g server-row">
|
||||
<div class="pure-u-lg-1-2 pure-u-1 server-label">
|
||||
<p>Latest release</p>
|
||||
</div>
|
||||
<div class="pure-u-lg-1-2 pure-u-1">
|
||||
<p>
|
||||
<a href="{$release_url}" title="{'Visit releases page on Github'|t}">
|
||||
{$latest_version}
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3 class="window-subtitle">Thumbnails</h3>
|
||||
|
||||
<div class="pure-g server-row">
|
||||
<div class="pure-u-lg-1-2 pure-u-1 server-label">
|
||||
<p>Thumbnails status</p>
|
||||
</div>
|
||||
<div class="pure-u-lg-1-2 pure-u-1">
|
||||
<p>
|
||||
{if="$thumbnails_mode==='all'"}
|
||||
{'All'|t}
|
||||
{elseif="$thumbnails_mode==='common'"}
|
||||
{'Only common media hosts'|t}
|
||||
{else}
|
||||
{'None'|t}
|
||||
{/if}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{if="$thumbnails_mode!=='none'"}
|
||||
<div class="center tools-item">
|
||||
<a href="{$base_path}/admin/thumbnails" title="{'Synchronize all link thumbnails'|t}">
|
||||
<span class="pure-button pure-u-lg-2-3 pure-u-3-4">{'Synchronize thumbnails'|t}</span>
|
||||
</a>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<h3 class="window-subtitle">Cache</h3>
|
||||
|
||||
<div class="center tools-item">
|
||||
<a href="{$base_path}/admin/clear-cache?type=main">
|
||||
<span class="pure-button pure-u-lg-2-3 pure-u-3-4">Clear main cache</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="center tools-item">
|
||||
<a href="{$base_path}/admin/clear-cache?type=thumbnails">
|
||||
<span class="pure-button pure-u-lg-2-3 pure-u-3-4">Clear thumbnails cache</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{include="page.footer"}
|
||||
|
||||
</body>
|
||||
</html>
|
68
tpl/default/server.requirements.html
Normal file
68
tpl/default/server.requirements.html
Normal file
|
@ -0,0 +1,68 @@
|
|||
<div class="server-tables">
|
||||
<h3 class="window-subtitle">{'Permissions'|t}</h3>
|
||||
|
||||
{if="count($permissions) > 0"}
|
||||
<p class="center">
|
||||
<i class="fa fa-close fa-color-red" aria-hidden="true"></i>
|
||||
{'There are permissions that need to be fixed.'|t}
|
||||
</p>
|
||||
|
||||
<p>
|
||||
{loop="$permissions"}
|
||||
<div class="center">{$value}</div>
|
||||
{/loop}
|
||||
</p>
|
||||
{else}
|
||||
<p class="center">
|
||||
<i class="fa fa-check fa-color-green" aria-hidden="true"></i>
|
||||
{'All read/write permissions are properly set.'|t}
|
||||
</p>
|
||||
{/if}
|
||||
|
||||
<h3 class="window-subtitle">PHP</h3>
|
||||
|
||||
<p class="center">
|
||||
<strong>{'Running PHP'|t} {$php_version}</strong>
|
||||
{if="$php_has_reached_eol"}
|
||||
<i class="fa fa-circle fa-color-orange" aria-label="hidden"></i><br>
|
||||
{'End of life: '|t} {$php_eol}
|
||||
{else}
|
||||
<i class="fa fa-circle fa-color-green" aria-label="hidden"></i><br>
|
||||
{/if}
|
||||
</p>
|
||||
|
||||
<table class="center">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{'Extension'|t}</th>
|
||||
<th>{'Usage'|t}</th>
|
||||
<th>{'Status'|t}</th>
|
||||
<th>{'Loaded'|t}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{loop="$php_extensions"}
|
||||
<tr>
|
||||
<td>{$value.name}</td>
|
||||
<td>{$value.desc}</td>
|
||||
<td>{$value.required ? t('Required') : t('Optional')}</td>
|
||||
<td>
|
||||
{if="$value.loaded"}
|
||||
{$classLoaded="fa-color-green"}
|
||||
{$strLoaded=t('Loaded')}
|
||||
{else}
|
||||
{$strLoaded=t('Not loaded')}
|
||||
{if="$value.required"}
|
||||
{$classLoaded="fa-color-red"}
|
||||
{else}
|
||||
{$classLoaded="fa-color-orange"}
|
||||
{/if}
|
||||
{/if}
|
||||
|
||||
<i class="fa fa-circle {$classLoaded}" aria-label="{$strLoaded}" title="{$strLoaded}"></i>
|
||||
</td>
|
||||
</tr>
|
||||
{/loop}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
|
@ -20,6 +20,12 @@
|
|||
<span class="pure-button pure-u-lg-2-3 pure-u-3-4">{'Plugin administration'|t}</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="tools-item">
|
||||
<a href="{$base_path}/admin/server"
|
||||
title="{'Check instance\'s server configuration'|t}">
|
||||
<span class="pure-button pure-u-lg-2-3 pure-u-3-4">{'Server administration'|t}</span>
|
||||
</a>
|
||||
</div>
|
||||
{if="!$openshaarli"}
|
||||
<div class="tools-item">
|
||||
<a href="{$base_path}/admin/password" title="{'Change your password'|t}">
|
||||
|
@ -45,14 +51,6 @@
|
|||
</a>
|
||||
</div>
|
||||
|
||||
{if="$thumbnails_enabled"}
|
||||
<div class="tools-item">
|
||||
<a href="{$base_path}/admin/thumbnails" title="{'Synchronize all link thumbnails'|t}">
|
||||
<span class="pure-button pure-u-lg-2-3 pure-u-3-4">{'Synchronize thumbnails'|t}</span>
|
||||
</a>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{loop="$tools_plugin"}
|
||||
<div class="tools-item">
|
||||
{$value}
|
||||
|
|
Loading…
Reference in a new issue