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
This commit is contained in:
parent
d8030c8155
commit
0cf76ccb47
16 changed files with 1086 additions and 104 deletions
|
@ -14,8 +14,9 @@ class ApplicationUtils
|
||||||
*/
|
*/
|
||||||
public static $VERSION_FILE = 'shaarli_version.php';
|
public static $VERSION_FILE = 'shaarli_version.php';
|
||||||
|
|
||||||
private static $GIT_URL = 'https://raw.githubusercontent.com/shaarli/Shaarli';
|
public static $GITHUB_URL = 'https://github.com/shaarli/Shaarli';
|
||||||
private static $GIT_BRANCHES = array('latest', 'stable');
|
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_START_TAG = '<?php /* ';
|
||||||
private static $VERSION_END_TAG = ' */ ?>';
|
private static $VERSION_END_TAG = ' */ ?>';
|
||||||
|
|
||||||
|
@ -125,7 +126,7 @@ public static function checkUpdate(
|
||||||
// Late Static Binding allows overriding within tests
|
// Late Static Binding allows overriding within tests
|
||||||
// See http://php.net/manual/en/language.oop5.late-static-bindings.php
|
// See http://php.net/manual/en/language.oop5.late-static-bindings.php
|
||||||
$latestVersion = static::getVersion(
|
$latestVersion = static::getVersion(
|
||||||
self::$GIT_URL . '/' . $branch . '/' . self::$VERSION_FILE
|
self::$GIT_RAW_URL . '/' . $branch . '/' . self::$VERSION_FILE
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!$latestVersion) {
|
if (!$latestVersion) {
|
||||||
|
@ -171,35 +172,45 @@ public static function checkPHPVersion($minVersion, $curVersion)
|
||||||
/**
|
/**
|
||||||
* Checks Shaarli has the proper access permissions to its resources
|
* 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
|
* @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'), '/');
|
$rainTplDir = rtrim($conf->get('resource.raintpl_tpl'), '/');
|
||||||
|
|
||||||
// Check script and template directories are readable
|
// Check script and template directories are readable
|
||||||
foreach (array(
|
foreach ([
|
||||||
'application',
|
'application',
|
||||||
'inc',
|
'inc',
|
||||||
'plugins',
|
'plugins',
|
||||||
$rainTplDir,
|
$rainTplDir,
|
||||||
$rainTplDir . '/' . $conf->get('resource.theme'),
|
$rainTplDir . '/' . $conf->get('resource.theme'),
|
||||||
) as $path) {
|
] as $path) {
|
||||||
if (!is_readable(realpath($path))) {
|
if (!is_readable(realpath($path))) {
|
||||||
$errors[] = '"' . $path . '" ' . t('directory is not readable');
|
$errors[] = '"' . $path . '" ' . t('directory is not readable');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check cache and data directories are readable and writable
|
// Check cache and data directories are readable and writable
|
||||||
foreach (array(
|
if ($minimalMode) {
|
||||||
$conf->get('resource.thumbnails_cache'),
|
$folders = [
|
||||||
$conf->get('resource.data_dir'),
|
$conf->get('resource.raintpl_tmp'),
|
||||||
$conf->get('resource.page_cache'),
|
];
|
||||||
$conf->get('resource.raintpl_tmp'),
|
} else {
|
||||||
) as $path) {
|
$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))) {
|
if (!is_readable(realpath($path))) {
|
||||||
$errors[] = '"' . $path . '" ' . t('directory is not readable');
|
$errors[] = '"' . $path . '" ' . t('directory is not readable');
|
||||||
}
|
}
|
||||||
|
@ -208,6 +219,10 @@ public static function checkResourcePermissions($conf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($minimalMode) {
|
||||||
|
return $errors;
|
||||||
|
}
|
||||||
|
|
||||||
// Check configuration files are readable and writable
|
// Check configuration files are readable and writable
|
||||||
foreach (array(
|
foreach (array(
|
||||||
$conf->getConfigFileExt(),
|
$conf->getConfigFileExt(),
|
||||||
|
@ -246,4 +261,54 @@ public static function getVersionHash($currentVersion, $salt)
|
||||||
{
|
{
|
||||||
return hash_hmac('sha256', $currentVersion, $salt);
|
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 @@ public static function readFlatDB($file, $default = null)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 @@ public function permalink(Request $request, Response $response, array $args): Re
|
||||||
*/
|
*/
|
||||||
protected function updateThumbnail(Bookmark $bookmark, bool $writeDatastore = true): bool
|
protected function updateThumbnail(Bookmark $bookmark, bool $writeDatastore = true): bool
|
||||||
{
|
{
|
||||||
// Logged in, not async retrieval, thumbnails enabled, and thumbnail should be updated
|
if (false === $this->container->loginManager->isLoggedIn()) {
|
||||||
if ($this->container->loginManager->isLoggedIn()
|
return false;
|
||||||
&& 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);
|
|
||||||
|
|
||||||
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;
|
return false;
|
||||||
|
|
|
@ -53,6 +53,16 @@ public function index(Request $request, Response $response): Response
|
||||||
$this->assignView('cities', $cities);
|
$this->assignView('cities', $cities);
|
||||||
$this->assignView('languages', Languages::getAvailableLanguages());
|
$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'));
|
return $response->write($this->render('install'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,7 +160,7 @@ public function save(Request $request, Response $response): Response
|
||||||
protected function checkPermissions(): bool
|
protected function checkPermissions(): bool
|
||||||
{
|
{
|
||||||
// Ensure Shaarli has proper access to its resources
|
// Ensure Shaarli has proper access to its resources
|
||||||
$errors = ApplicationUtils::checkResourcePermissions($this->container->conf);
|
$errors = ApplicationUtils::checkResourcePermissions($this->container->conf, true);
|
||||||
if (empty($errors)) {
|
if (empty($errors)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1047,7 +1047,7 @@ body,
|
||||||
}
|
}
|
||||||
|
|
||||||
table {
|
table {
|
||||||
margin: auto;
|
margin: 10px auto 25px auto;
|
||||||
width: 90%;
|
width: 90%;
|
||||||
|
|
||||||
.order {
|
.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
|
// Print rules
|
||||||
@media print {
|
@media print {
|
||||||
.shaarli-menu {
|
.shaarli-menu {
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: Shaarli\n"
|
"Project-Id-Version: Shaarli\n"
|
||||||
"POT-Creation-Date: 2020-10-16 20:01+0200\n"
|
"POT-Creation-Date: 2020-10-21 15:00+0200\n"
|
||||||
"PO-Revision-Date: 2020-10-16 20:02+0200\n"
|
"PO-Revision-Date: 2020-10-21 15:06+0200\n"
|
||||||
"Last-Translator: \n"
|
"Last-Translator: \n"
|
||||||
"Language-Team: Shaarli\n"
|
"Language-Team: Shaarli\n"
|
||||||
"Language: fr_FR\n"
|
"Language: fr_FR\n"
|
||||||
|
@ -20,7 +20,7 @@ msgstr ""
|
||||||
"X-Poedit-SearchPath-3: init.php\n"
|
"X-Poedit-SearchPath-3: init.php\n"
|
||||||
"X-Poedit-SearchPath-4: plugins\n"
|
"X-Poedit-SearchPath-4: plugins\n"
|
||||||
|
|
||||||
#: application/ApplicationUtils.php:161
|
#: application/ApplicationUtils.php:162
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Your PHP version is obsolete! Shaarli requires at least PHP %s, and thus "
|
"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 "
|
"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."
|
"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"
|
msgid "directory is not readable"
|
||||||
msgstr "le répertoire n'est pas accessible en lecture"
|
msgstr "le répertoire n'est pas accessible en lecture"
|
||||||
|
|
||||||
#: application/ApplicationUtils.php:207
|
#: application/ApplicationUtils.php:218
|
||||||
msgid "directory is not writable"
|
msgid "directory is not writable"
|
||||||
msgstr "le répertoire n'est pas accessible en écriture"
|
msgstr "le répertoire n'est pas accessible en écriture"
|
||||||
|
|
||||||
#: application/ApplicationUtils.php:225
|
#: application/ApplicationUtils.php:240
|
||||||
msgid "file is not readable"
|
msgid "file is not readable"
|
||||||
msgstr "le fichier n'est pas accessible en lecture"
|
msgstr "le fichier n'est pas accessible en lecture"
|
||||||
|
|
||||||
#: application/ApplicationUtils.php:228
|
#: application/ApplicationUtils.php:243
|
||||||
msgid "file is not writable"
|
msgid "file is not writable"
|
||||||
msgstr "le fichier n'est pas accessible en écriture"
|
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
|
#: application/History.php:179
|
||||||
msgid "History file isn't readable or writable"
|
msgid "History file isn't readable or writable"
|
||||||
msgstr "Le fichier d'historique n'est pas accessible en lecture ou en écriture"
|
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."
|
msgstr "Vous avez activé ou changé le mode de miniatures."
|
||||||
|
|
||||||
#: application/front/controller/admin/ConfigureController.php:103
|
#: application/front/controller/admin/ConfigureController.php:103
|
||||||
|
#: application/front/controller/admin/ServerController.php:68
|
||||||
#: application/legacy/LegacyUpdater.php:538
|
#: application/legacy/LegacyUpdater.php:538
|
||||||
msgid "Please synchronize them."
|
msgid "Please synchronize them."
|
||||||
msgstr "Merci de les synchroniser."
|
msgstr "Merci de les synchroniser."
|
||||||
|
|
||||||
#: application/front/controller/admin/ConfigureController.php:113
|
#: 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."
|
msgid "Error while writing config file after configuration update."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Une erreur s'est produite lors de la sauvegarde du fichier de configuration."
|
"Une erreur s'est produite lors de la sauvegarde du fichier de configuration."
|
||||||
|
@ -377,33 +418,33 @@ msgstr ""
|
||||||
msgid "Shaare a new link"
|
msgid "Shaare a new link"
|
||||||
msgstr "Partager un nouveau lien"
|
msgstr "Partager un nouveau lien"
|
||||||
|
|
||||||
#: application/front/controller/admin/ManageShaareController.php:78
|
#: application/front/controller/admin/ManageShaareController.php:64
|
||||||
msgid "Note: "
|
msgid "Note: "
|
||||||
msgstr "Note : "
|
msgstr "Note : "
|
||||||
|
|
||||||
#: application/front/controller/admin/ManageShaareController.php:109
|
#: application/front/controller/admin/ManageShaareController.php:95
|
||||||
#: application/front/controller/admin/ManageShaareController.php:206
|
#: application/front/controller/admin/ManageShaareController.php:193
|
||||||
#: application/front/controller/admin/ManageShaareController.php:275
|
#: application/front/controller/admin/ManageShaareController.php:262
|
||||||
#: application/front/controller/admin/ManageShaareController.php:315
|
#: application/front/controller/admin/ManageShaareController.php:302
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid "Bookmark with identifier %s could not be found."
|
msgid "Bookmark with identifier %s could not be found."
|
||||||
msgstr "Le lien avec l'identifiant %s n'a pas pu être trouvé."
|
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:181
|
||||||
#: application/front/controller/admin/ManageShaareController.php:252
|
#: application/front/controller/admin/ManageShaareController.php:239
|
||||||
msgid "Invalid bookmark ID provided."
|
msgid "Invalid bookmark ID provided."
|
||||||
msgstr "ID du lien non valide."
|
msgstr "ID du lien non valide."
|
||||||
|
|
||||||
#: application/front/controller/admin/ManageShaareController.php:260
|
#: application/front/controller/admin/ManageShaareController.php:247
|
||||||
msgid "Invalid visibility provided."
|
msgid "Invalid visibility provided."
|
||||||
msgstr "Visibilité du lien non valide."
|
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
|
#: tmp/linklist.b91ef64efc3688266305ea9b42e5017e.rtpl.php:171
|
||||||
msgid "Edit"
|
msgid "Edit"
|
||||||
msgstr "Modifier"
|
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.b91ef64efc3688266305ea9b42e5017e.rtpl.php:28
|
||||||
#: tmp/page.header.cedf684561d925457130839629000a81.rtpl.php:28
|
#: tmp/page.header.cedf684561d925457130839629000a81.rtpl.php:28
|
||||||
msgid "Shaare"
|
msgid "Shaare"
|
||||||
|
@ -411,7 +452,7 @@ msgstr "Shaare"
|
||||||
|
|
||||||
#: application/front/controller/admin/ManageTagController.php:29
|
#: application/front/controller/admin/ManageTagController.php:29
|
||||||
#: tmp/changetag.b91ef64efc3688266305ea9b42e5017e.rtpl.php:13
|
#: tmp/changetag.b91ef64efc3688266305ea9b42e5017e.rtpl.php:13
|
||||||
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:36
|
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:42
|
||||||
msgid "Manage tags"
|
msgid "Manage tags"
|
||||||
msgstr "Gérer les 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
|
#: application/front/controller/admin/PasswordController.php:28
|
||||||
#: tmp/changepassword.b91ef64efc3688266305ea9b42e5017e.rtpl.php:13
|
#: tmp/changepassword.b91ef64efc3688266305ea9b42e5017e.rtpl.php:13
|
||||||
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:29
|
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:35
|
||||||
msgid "Change password"
|
msgid "Change password"
|
||||||
msgstr "Modifier le mot de passe"
|
msgstr "Modifier le mot de passe"
|
||||||
|
|
||||||
|
@ -467,6 +508,20 @@ msgstr ""
|
||||||
"Une erreur s'est produite lors de la sauvegarde de la configuration des "
|
"Une erreur s'est produite lors de la sauvegarde de la configuration des "
|
||||||
"plugins : "
|
"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
|
#: application/front/controller/admin/ThumbnailsController.php:37
|
||||||
#: tmp/thumbnails.b91ef64efc3688266305ea9b42e5017e.rtpl.php:14
|
#: tmp/thumbnails.b91ef64efc3688266305ea9b42e5017e.rtpl.php:14
|
||||||
msgid "Thumbnails update"
|
msgid "Thumbnails update"
|
||||||
|
@ -502,9 +557,14 @@ msgstr "Une erreur inattendue s'est produite."
|
||||||
|
|
||||||
#: application/front/controller/visitor/ErrorNotFoundController.php:25
|
#: application/front/controller/visitor/ErrorNotFoundController.php:25
|
||||||
msgid "Requested page could not be found."
|
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
|
#, php-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"<pre>Sessions do not seem to work correctly on your server.<br>Make sure the "
|
"<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 "
|
"des cookies. Nous vous recommandons d'accéder à votre serveur depuis son "
|
||||||
"adresse IP ou un <em>Fully Qualified Domain Name</em>.<br>"
|
"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 ""
|
msgid ""
|
||||||
"Shaarli is now configured. Please login and start shaaring your bookmarks!"
|
"Shaarli is now configured. Please login and start shaaring your bookmarks!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Shaarli est maintenant configuré. Vous pouvez vous connecter et commencez à "
|
"Shaarli est maintenant configuré. Vous pouvez vous connecter et commencez à "
|
||||||
"shaare vos liens !"
|
"shaare vos liens !"
|
||||||
|
|
||||||
#: application/front/controller/visitor/InstallController.php:158
|
#: application/front/controller/visitor/InstallController.php:168
|
||||||
msgid "Insufficient permissions:"
|
msgid "Insufficient permissions:"
|
||||||
msgstr "Permissions insuffisantes :"
|
msgstr "Permissions insuffisantes :"
|
||||||
|
|
||||||
|
@ -1016,25 +1076,28 @@ msgstr ""
|
||||||
"miniatures."
|
"miniatures."
|
||||||
|
|
||||||
#: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:328
|
#: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:328
|
||||||
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:56
|
#: tmp/server.b91ef64efc3688266305ea9b42e5017e.rtpl.php:122
|
||||||
msgid "Synchronize thumbnails"
|
msgid "Synchronize thumbnails"
|
||||||
msgstr "Synchroniser les miniatures"
|
msgstr "Synchroniser les miniatures"
|
||||||
|
|
||||||
#: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:339
|
#: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:339
|
||||||
#: tmp/export.b91ef64efc3688266305ea9b42e5017e.rtpl.php:30
|
#: tmp/export.b91ef64efc3688266305ea9b42e5017e.rtpl.php:30
|
||||||
|
#: tmp/server.b91ef64efc3688266305ea9b42e5017e.rtpl.php:102
|
||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "Tous"
|
msgstr "Tous"
|
||||||
|
|
||||||
#: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:343
|
#: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:343
|
||||||
|
#: tmp/server.b91ef64efc3688266305ea9b42e5017e.rtpl.php:106
|
||||||
msgid "Only common media hosts"
|
msgid "Only common media hosts"
|
||||||
msgstr "Seulement les hébergeurs de média connus"
|
msgstr "Seulement les hébergeurs de média connus"
|
||||||
|
|
||||||
#: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:347
|
#: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:347
|
||||||
|
#: tmp/server.b91ef64efc3688266305ea9b42e5017e.rtpl.php:110
|
||||||
msgid "None"
|
msgid "None"
|
||||||
msgstr "Aucune"
|
msgstr "Aucune"
|
||||||
|
|
||||||
#: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:355
|
#: 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:139
|
||||||
#: tmp/pluginsadmin.b91ef64efc3688266305ea9b42e5017e.rtpl.php:199
|
#: tmp/pluginsadmin.b91ef64efc3688266305ea9b42e5017e.rtpl.php:199
|
||||||
msgid "Save"
|
msgid "Save"
|
||||||
|
@ -1060,27 +1123,27 @@ msgstr "Tous les liens d'un jour sur une page."
|
||||||
msgid "Next day"
|
msgid "Next day"
|
||||||
msgstr "Jour suivant"
|
msgstr "Jour suivant"
|
||||||
|
|
||||||
#: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:18
|
#: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:21
|
||||||
msgid "Edit Shaare"
|
msgid "Edit Shaare"
|
||||||
msgstr "Modifier le Shaare"
|
msgstr "Modifier le Shaare"
|
||||||
|
|
||||||
#: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:18
|
#: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:21
|
||||||
msgid "New Shaare"
|
msgid "New Shaare"
|
||||||
msgstr "Nouveau Shaare"
|
msgstr "Nouveau Shaare"
|
||||||
|
|
||||||
#: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:26
|
#: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:29
|
||||||
msgid "Created:"
|
msgid "Created:"
|
||||||
msgstr "Création :"
|
msgstr "Création :"
|
||||||
|
|
||||||
#: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:29
|
#: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:32
|
||||||
msgid "URL"
|
msgid "URL"
|
||||||
msgstr "URL"
|
msgstr "URL"
|
||||||
|
|
||||||
#: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:35
|
#: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:38
|
||||||
msgid "Title"
|
msgid "Title"
|
||||||
msgstr "Titre"
|
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:42
|
||||||
#: tmp/pluginsadmin.b91ef64efc3688266305ea9b42e5017e.rtpl.php:75
|
#: tmp/pluginsadmin.b91ef64efc3688266305ea9b42e5017e.rtpl.php:75
|
||||||
#: tmp/pluginsadmin.b91ef64efc3688266305ea9b42e5017e.rtpl.php:99
|
#: tmp/pluginsadmin.b91ef64efc3688266305ea9b42e5017e.rtpl.php:99
|
||||||
|
@ -1088,33 +1151,33 @@ msgstr "Titre"
|
||||||
msgid "Description"
|
msgid "Description"
|
||||||
msgstr "Description"
|
msgstr "Description"
|
||||||
|
|
||||||
#: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:47
|
#: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:58
|
||||||
msgid "Tags"
|
msgid "Tags"
|
||||||
msgstr "Tags"
|
msgstr "Tags"
|
||||||
|
|
||||||
#: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:60
|
#: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:74
|
||||||
#: tmp/export.b91ef64efc3688266305ea9b42e5017e.rtpl.php:35
|
#: tmp/export.b91ef64efc3688266305ea9b42e5017e.rtpl.php:35
|
||||||
#: tmp/linklist.b91ef64efc3688266305ea9b42e5017e.rtpl.php:169
|
#: tmp/linklist.b91ef64efc3688266305ea9b42e5017e.rtpl.php:169
|
||||||
msgid "Private"
|
msgid "Private"
|
||||||
msgstr "Privé"
|
msgstr "Privé"
|
||||||
|
|
||||||
#: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:66
|
#: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:80
|
||||||
msgid "Description will be rendered with"
|
msgid "Description will be rendered with"
|
||||||
msgstr "La description sera générée avec"
|
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"
|
msgid "Markdown syntax documentation"
|
||||||
msgstr "Documentation sur la syntaxe Markdown"
|
msgstr "Documentation sur la syntaxe Markdown"
|
||||||
|
|
||||||
#: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:69
|
#: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:83
|
||||||
msgid "Markdown syntax"
|
msgid "Markdown syntax"
|
||||||
msgstr "la syntaxe Markdown"
|
msgstr "la syntaxe Markdown"
|
||||||
|
|
||||||
#: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:88
|
#: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:102
|
||||||
msgid "Apply Changes"
|
msgid "Apply Changes"
|
||||||
msgstr "Appliquer les changements"
|
msgstr "Appliquer les changements"
|
||||||
|
|
||||||
#: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:93
|
#: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:107
|
||||||
#: tmp/linklist.b91ef64efc3688266305ea9b42e5017e.rtpl.php:173
|
#: tmp/linklist.b91ef64efc3688266305ea9b42e5017e.rtpl.php:173
|
||||||
#: tmp/page.header.b91ef64efc3688266305ea9b42e5017e.rtpl.php:147
|
#: tmp/page.header.b91ef64efc3688266305ea9b42e5017e.rtpl.php:147
|
||||||
#: tmp/page.header.cedf684561d925457130839629000a81.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"
|
msgid "Add default tags"
|
||||||
msgstr "Ajouter des tags par défaut"
|
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
|
#: tmp/install.b91ef64efc3688266305ea9b42e5017e.rtpl.php:25
|
||||||
msgid "It looks like it's the first time you run Shaarli. Please configure it."
|
msgid "It looks like it's the first time you run Shaarli. Please configure it."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
@ -1215,6 +1274,10 @@ msgstr "Mes liens"
|
||||||
msgid "Install"
|
msgid "Install"
|
||||||
msgstr "Installer"
|
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:14
|
||||||
#: tmp/linklist.b91ef64efc3688266305ea9b42e5017e.rtpl.php:79
|
#: tmp/linklist.b91ef64efc3688266305ea9b42e5017e.rtpl.php:79
|
||||||
msgid "shaare"
|
msgid "shaare"
|
||||||
|
@ -1511,6 +1574,100 @@ msgstr "Configuration des extensions"
|
||||||
msgid "No parameter available."
|
msgid "No parameter available."
|
||||||
msgstr "Aucun paramètre disponible."
|
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.cloud.b91ef64efc3688266305ea9b42e5017e.rtpl.php:19
|
||||||
#: tmp/tag.list.b91ef64efc3688266305ea9b42e5017e.rtpl.php:19
|
#: tmp/tag.list.b91ef64efc3688266305ea9b42e5017e.rtpl.php:19
|
||||||
msgid "tags"
|
msgid "tags"
|
||||||
|
@ -1561,15 +1718,19 @@ msgstr "Configurer Shaarli"
|
||||||
msgid "Enable, disable and configure plugins"
|
msgid "Enable, disable and configure plugins"
|
||||||
msgstr "Activer, désactiver et configurer les extensions"
|
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"
|
msgid "Change your password"
|
||||||
msgstr "Modifier le mot de passe"
|
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"
|
msgid "Rename or delete a tag in all links"
|
||||||
msgstr "Renommer ou supprimer un tag dans tous les liens"
|
msgstr "Renommer ou supprimer un tag dans tous les liens"
|
||||||
|
|
||||||
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:41
|
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:47
|
||||||
msgid ""
|
msgid ""
|
||||||
"Import Netscape HTML bookmarks (as exported from Firefox, Chrome, Opera, "
|
"Import Netscape HTML bookmarks (as exported from Firefox, Chrome, Opera, "
|
||||||
"delicious...)"
|
"delicious...)"
|
||||||
|
@ -1577,11 +1738,11 @@ msgstr ""
|
||||||
"Importer des marques pages au format Netscape HTML (comme exportés depuis "
|
"Importer des marques pages au format Netscape HTML (comme exportés depuis "
|
||||||
"Firefox, Chrome, Opera, delicious...)"
|
"Firefox, Chrome, Opera, delicious...)"
|
||||||
|
|
||||||
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:42
|
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:48
|
||||||
msgid "Import links"
|
msgid "Import links"
|
||||||
msgstr "Importer des liens"
|
msgstr "Importer des liens"
|
||||||
|
|
||||||
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:47
|
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:53
|
||||||
msgid ""
|
msgid ""
|
||||||
"Export Netscape HTML bookmarks (which can be imported in Firefox, Chrome, "
|
"Export Netscape HTML bookmarks (which can be imported in Firefox, Chrome, "
|
||||||
"Opera, delicious...)"
|
"Opera, delicious...)"
|
||||||
|
@ -1589,15 +1750,11 @@ msgstr ""
|
||||||
"Exporter les marques pages au format Netscape HTML (comme exportés depuis "
|
"Exporter les marques pages au format Netscape HTML (comme exportés depuis "
|
||||||
"Firefox, Chrome, Opera, delicious...)"
|
"Firefox, Chrome, Opera, delicious...)"
|
||||||
|
|
||||||
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:48
|
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:54
|
||||||
msgid "Export database"
|
msgid "Export database"
|
||||||
msgstr "Exporter les données"
|
msgstr "Exporter les données"
|
||||||
|
|
||||||
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:55
|
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:77
|
||||||
msgid "Synchronize all link thumbnails"
|
|
||||||
msgstr "Synchroniser toutes les miniatures"
|
|
||||||
|
|
||||||
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:81
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Drag one of these button to your bookmarks toolbar or right-click it and "
|
"Drag one of these button to your bookmarks toolbar or right-click it and "
|
||||||
"\"Bookmark This Link\""
|
"\"Bookmark This Link\""
|
||||||
|
@ -1605,13 +1762,13 @@ msgstr ""
|
||||||
"Glisser un de ces boutons dans votre barre de favoris ou cliquer droit "
|
"Glisser un de ces boutons dans votre barre de favoris ou cliquer droit "
|
||||||
"dessus et « Ajouter aux favoris »"
|
"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."
|
msgid "then click on the bookmarklet in any page you want to share."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"puis cliquer sur le marque-page depuis un site que vous souhaitez partager."
|
"puis cliquer sur le marque-page depuis un site que vous souhaitez partager."
|
||||||
|
|
||||||
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:86
|
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:82
|
||||||
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:110
|
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:106
|
||||||
msgid ""
|
msgid ""
|
||||||
"Drag this link to your bookmarks toolbar or right-click it and Bookmark This "
|
"Drag this link to your bookmarks toolbar or right-click it and Bookmark This "
|
||||||
"Link"
|
"Link"
|
||||||
|
@ -1619,40 +1776,40 @@ msgstr ""
|
||||||
"Glisser ce lien dans votre barre de favoris ou cliquer droit dessus et « "
|
"Glisser ce lien dans votre barre de favoris ou cliquer droit dessus et « "
|
||||||
"Ajouter aux favoris »"
|
"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"
|
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"
|
msgstr "puis cliquer sur ✚Shaare depuis un site que vous souhaitez partager"
|
||||||
|
|
||||||
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:96
|
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:92
|
||||||
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:118
|
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:114
|
||||||
msgid "The selected text is too long, it will be truncated."
|
msgid "The selected text is too long, it will be truncated."
|
||||||
msgstr "Le texte sélectionné est trop long, il sera tronqué."
|
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"
|
msgid "Shaare link"
|
||||||
msgstr "Shaare"
|
msgstr "Shaare"
|
||||||
|
|
||||||
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:111
|
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:107
|
||||||
msgid ""
|
msgid ""
|
||||||
"Then click ✚Add Note button anytime to start composing a private Note (text "
|
"Then click ✚Add Note button anytime to start composing a private Note (text "
|
||||||
"post) to your Shaarli"
|
"post) to your Shaarli"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Puis cliquer sur ✚Add Note pour commencer à rédiger une Note sur Shaarli"
|
"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"
|
msgid "Add Note"
|
||||||
msgstr "Ajouter une Note"
|
msgstr "Ajouter une Note"
|
||||||
|
|
||||||
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:136
|
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:132
|
||||||
msgid "3rd party"
|
msgid "3rd party"
|
||||||
msgstr "Applications tierces"
|
msgstr "Applications tierces"
|
||||||
|
|
||||||
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:139
|
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:135
|
||||||
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:144
|
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:140
|
||||||
msgid "plugin"
|
msgid "plugin"
|
||||||
msgstr "extension"
|
msgstr "extension"
|
||||||
|
|
||||||
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:169
|
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:165
|
||||||
msgid ""
|
msgid ""
|
||||||
"Drag this link to your bookmarks toolbar, or right-click it and choose "
|
"Drag this link to your bookmarks toolbar, or right-click it and choose "
|
||||||
"Bookmark This Link"
|
"Bookmark This Link"
|
||||||
|
@ -1660,9 +1817,6 @@ msgstr ""
|
||||||
"Glisser ce lien dans votre barre de favoris ou cliquer droit dessus et « "
|
"Glisser ce lien dans votre barre de favoris ou cliquer droit dessus et « "
|
||||||
"Ajouter aux favoris »"
|
"Ajouter aux favoris »"
|
||||||
|
|
||||||
#~ msgid "Provided data is invalid"
|
|
||||||
#~ msgstr "Les informations fournies ne sont pas valides"
|
|
||||||
|
|
||||||
#~ msgid "Rename"
|
#~ msgid "Rename"
|
||||||
#~ msgstr "Renommer"
|
#~ msgstr "Renommer"
|
||||||
|
|
||||||
|
|
|
@ -128,6 +128,8 @@
|
||||||
$this->get('/plugins', '\Shaarli\Front\Controller\Admin\PluginsController:index');
|
$this->get('/plugins', '\Shaarli\Front\Controller\Admin\PluginsController:index');
|
||||||
$this->post('/plugins', '\Shaarli\Front\Controller\Admin\PluginsController:save');
|
$this->post('/plugins', '\Shaarli\Front\Controller\Admin\PluginsController:save');
|
||||||
$this->get('/token', '\Shaarli\Front\Controller\Admin\TokenController:getToken');
|
$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('/thumbnails', '\Shaarli\Front\Controller\Admin\ThumbnailsController:index');
|
||||||
$this->get('/metadata', '\Shaarli\Front\Controller\Admin\MetadataController:ajaxRetrieveTitle');
|
$this->get('/metadata', '\Shaarli\Front\Controller\Admin\MetadataController:ajaxRetrieveTitle');
|
||||||
$this->get('/visibility/{visibility}', '\Shaarli\Front\Controller\Admin\SessionFilterController:visibility');
|
$this->get('/visibility/{visibility}', '\Shaarli\Front\Controller\Admin\SessionFilterController:visibility');
|
||||||
|
|
|
@ -339,6 +339,35 @@ public function testCheckCurrentResourcePermissionsErrors()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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).
|
* Check update with 'dev' as curent version (master branch).
|
||||||
* It should always return false.
|
* It should always return false.
|
||||||
|
@ -349,4 +378,37 @@ public function testCheckUpdateDev()
|
||||||
ApplicationUtils::checkUpdate('dev', self::$testUpdateFile, 100, true, true)
|
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;
|
namespace Shaarli;
|
||||||
|
|
||||||
use Exception;
|
use Exception;
|
||||||
|
use Shaarli\Exceptions\IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class FileUtilsTest
|
* Class FileUtilsTest
|
||||||
*
|
*
|
||||||
* Test file utility class.
|
* Test file utility class.
|
||||||
*/
|
*/
|
||||||
class FileUtilsTest extends \Shaarli\TestCase
|
class FileUtilsTest extends TestCase
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var string Test file path.
|
* @var string Test file path.
|
||||||
*/
|
*/
|
||||||
protected static $file = 'sandbox/flat.db';
|
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.
|
* Delete test file after every test.
|
||||||
*/
|
*/
|
||||||
protected function tearDown(): void
|
protected function tearDown(): void
|
||||||
{
|
{
|
||||||
@unlink(self::$file);
|
@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 @@ public function testReadNotReadable()
|
||||||
$this->assertEquals(null, FileUtils::readFlatDB(self::$file));
|
$this->assertEquals(null, FileUtils::readFlatDB(self::$file));
|
||||||
$this->assertEquals(['test'], FileUtils::readFlatDB(self::$file, ['test']));
|
$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 @@ public function testInstallIndexWithValidSession(): void
|
||||||
static::assertIsArray($assignedVariables['languages']);
|
static::assertIsArray($assignedVariables['languages']);
|
||||||
static::assertSame('Automatic', $assignedVariables['languages']['auto']);
|
static::assertSame('Automatic', $assignedVariables['languages']['auto']);
|
||||||
static::assertSame('French', $assignedVariables['languages']['fr']);
|
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 @@ <h2 class="window-title">{'Install Shaarli'|t}</h2>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</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"}
|
{include="page.footer"}
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</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 @@ <h2 class="window-title">{'Settings'|t}</h2>
|
||||||
<span class="pure-button pure-u-lg-2-3 pure-u-3-4">{'Plugin administration'|t}</span>
|
<span class="pure-button pure-u-lg-2-3 pure-u-3-4">{'Plugin administration'|t}</span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</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"}
|
{if="!$openshaarli"}
|
||||||
<div class="tools-item">
|
<div class="tools-item">
|
||||||
<a href="{$base_path}/admin/password" title="{'Change your password'|t}">
|
<a href="{$base_path}/admin/password" title="{'Change your password'|t}">
|
||||||
|
@ -45,14 +51,6 @@ <h2 class="window-title">{'Settings'|t}</h2>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</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"}
|
{loop="$tools_plugin"}
|
||||||
<div class="tools-item">
|
<div class="tools-item">
|
||||||
{$value}
|
{$value}
|
||||||
|
|
Loading…
Reference in a new issue