Thumbnails: add a common mode to only retrieve thumbs from popular media websites
This commit is contained in:
parent
fcba541e2f
commit
b302b3c584
9 changed files with 135 additions and 30 deletions
|
@ -1,6 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
use Shaarli\Config\ConfigManager;
|
use Shaarli\Config\ConfigManager;
|
||||||
|
use Shaarli\Thumbnailer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class is in charge of building the final page.
|
* This class is in charge of building the final page.
|
||||||
|
@ -119,7 +120,10 @@ private function initialize()
|
||||||
$this->tpl->assign('tags', $this->linkDB->linksCountPerTag());
|
$this->tpl->assign('tags', $this->linkDB->linksCountPerTag());
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->tpl->assign('thumbnails_enabled', $this->conf->get('thumbnails.enabled'));
|
$this->tpl->assign(
|
||||||
|
'thumbnails_enabled',
|
||||||
|
$this->conf->get('thumbnails.mode', Thumbnailer::MODE_NONE) !== Thumbnailer::MODE_NONE
|
||||||
|
);
|
||||||
$this->tpl->assign('thumbnails_width', $this->conf->get('thumbnails.width'));
|
$this->tpl->assign('thumbnails_width', $this->conf->get('thumbnails.width'));
|
||||||
$this->tpl->assign('thumbnails_height', $this->conf->get('thumbnails.height'));
|
$this->tpl->assign('thumbnails_height', $this->conf->get('thumbnails.height'));
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,27 @@
|
||||||
*/
|
*/
|
||||||
class Thumbnailer
|
class Thumbnailer
|
||||||
{
|
{
|
||||||
|
const COMMON_MEDIA_DOMAINS = [
|
||||||
|
'imgur.com',
|
||||||
|
'flickr.com',
|
||||||
|
'youtube.com',
|
||||||
|
'wikimedia.org',
|
||||||
|
'redd.it',
|
||||||
|
'gfycat.com',
|
||||||
|
'media.giphy.com',
|
||||||
|
'twitter.com',
|
||||||
|
'twimg.com',
|
||||||
|
'instagram.com',
|
||||||
|
'pinterest.com',
|
||||||
|
'pinterest.fr',
|
||||||
|
'tumblr.com',
|
||||||
|
'deviantart.com',
|
||||||
|
];
|
||||||
|
|
||||||
|
const MODE_ALL = 'all';
|
||||||
|
const MODE_COMMON = 'common';
|
||||||
|
const MODE_NONE = 'none';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var WebThumbnailer instance.
|
* @var WebThumbnailer instance.
|
||||||
*/
|
*/
|
||||||
|
@ -57,13 +78,42 @@ public function __construct($conf)
|
||||||
*/
|
*/
|
||||||
public function get($url)
|
public function get($url)
|
||||||
{
|
{
|
||||||
|
if ($this->conf->get('thumbnails.mode') === self::MODE_COMMON
|
||||||
|
&& ! $this->isCommonMediaOrImage($url)
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return $this->wt->thumbnail($url);
|
return $this->wt->thumbnail($url);
|
||||||
} catch (WebThumbnailerException $e) {
|
} catch (WebThumbnailerException $e) {
|
||||||
// Exceptions are only thrown in debug mode.
|
// Exceptions are only thrown in debug mode.
|
||||||
error_log(get_class($e) .': '. $e->getMessage());
|
error_log(get_class($e) . ': ' . $e->getMessage());
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We check weather the given URL is from a common media domain,
|
||||||
|
* or if the file extension is an image.
|
||||||
|
*
|
||||||
|
* @param string $url to check
|
||||||
|
*
|
||||||
|
* @return bool true if it's an image or from a common media domain, false otherwise.
|
||||||
|
*/
|
||||||
|
public function isCommonMediaOrImage($url)
|
||||||
|
{
|
||||||
|
foreach (self::COMMON_MEDIA_DOMAINS as $domain) {
|
||||||
|
if (strpos($url, $domain) !== false) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (endsWith($url, '.jpg') || endsWith($url, '.png') || endsWith($url, '.jpeg')) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
use Shaarli\Config\ConfigJson;
|
use Shaarli\Config\ConfigJson;
|
||||||
use Shaarli\Config\ConfigPhp;
|
use Shaarli\Config\ConfigPhp;
|
||||||
use Shaarli\Config\ConfigManager;
|
use Shaarli\Config\ConfigManager;
|
||||||
|
use Shaarli\Thumbnailer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class Updater.
|
* Class Updater.
|
||||||
|
@ -497,12 +498,12 @@ public function updateMethodDownloadSizeAndTimeoutConf()
|
||||||
*/
|
*/
|
||||||
public function updateMethodWebThumbnailer()
|
public function updateMethodWebThumbnailer()
|
||||||
{
|
{
|
||||||
if ($this->conf->exists('thumbnails.enabled')) {
|
if ($this->conf->exists('thumbnails.mode')) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
$thumbnailsEnabled = $this->conf->get('thumbnail.enable_thumbnails', true);
|
$thumbnailsEnabled = $this->conf->get('thumbnail.enable_thumbnails', true);
|
||||||
$this->conf->set('thumbnails.enabled', $thumbnailsEnabled);
|
$this->conf->set('thumbnails.mode', $thumbnailsEnabled ? Thumbnailer::MODE_ALL : Thumbnailer::MODE_NONE);
|
||||||
$this->conf->set('thumbnails.width', 125);
|
$this->conf->set('thumbnails.width', 125);
|
||||||
$this->conf->set('thumbnails.height', 90);
|
$this->conf->set('thumbnails.height', 90);
|
||||||
$this->conf->remove('thumbnail');
|
$this->conf->remove('thumbnail');
|
||||||
|
|
22
index.php
22
index.php
|
@ -603,7 +603,9 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager,
|
||||||
// -------- Picture wall
|
// -------- Picture wall
|
||||||
if ($targetPage == Router::$PAGE_PICWALL)
|
if ($targetPage == Router::$PAGE_PICWALL)
|
||||||
{
|
{
|
||||||
if (! $conf->get('thumbnails.enabled')) {
|
$PAGE->assign('pagetitle', t('Picture wall') .' - '. $conf->get('general.title', 'Shaarli'));
|
||||||
|
if (! $conf->get('thumbnails.mode', Thumbnailer::MODE_NONE) === Thumbnailer::MODE_NONE) {
|
||||||
|
$PAGE->assign('linksToDisplay', []);
|
||||||
$PAGE->renderPage('picwall');
|
$PAGE->renderPage('picwall');
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
@ -630,7 +632,6 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager,
|
||||||
$PAGE->assign($key, $value);
|
$PAGE->assign($key, $value);
|
||||||
}
|
}
|
||||||
|
|
||||||
$PAGE->assign('pagetitle', t('Picture wall') .' - '. $conf->get('general.title', 'Shaarli'));
|
|
||||||
$PAGE->renderPage('picwall');
|
$PAGE->renderPage('picwall');
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
@ -1013,14 +1014,13 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager,
|
||||||
$conf->set('api.secret', escape($_POST['apiSecret']));
|
$conf->set('api.secret', escape($_POST['apiSecret']));
|
||||||
$conf->set('translation.language', escape($_POST['language']));
|
$conf->set('translation.language', escape($_POST['language']));
|
||||||
|
|
||||||
$thumbnailsEnabled = extension_loaded('gd') && !empty($_POST['enableThumbnails']);
|
$thumbnailsMode = extension_loaded('gd') ? $_POST['enableThumbnails'] : Thumbnailer::MODE_NONE;
|
||||||
$conf->set('thumbnails.enabled', $thumbnailsEnabled);
|
if ($conf->get('thumbnails.enabled', Thumbnailer::MODE_NONE) !== Thumbnailer::MODE_NONE) {
|
||||||
|
|
||||||
if (! $conf->get('thumbnails.enabled') && $thumbnailsEnabled) {
|
|
||||||
$_SESSION['warnings'][] = t(
|
$_SESSION['warnings'][] = t(
|
||||||
'You have enabled thumbnails. <a href="?do=thumbs_update">Please synchonize them</a>.'
|
'You have enabled or changed thumbnails mode. <a href="?do=thumbs_update">Please synchonize them</a>.'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
$conf->set('thumbnails.mode', $thumbnailsMode);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$conf->write($loginManager->isLoggedIn());
|
$conf->write($loginManager->isLoggedIn());
|
||||||
|
@ -1061,6 +1061,7 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager,
|
||||||
$PAGE->assign('languages', Languages::getAvailableLanguages());
|
$PAGE->assign('languages', Languages::getAvailableLanguages());
|
||||||
$PAGE->assign('language', $conf->get('translation.language'));
|
$PAGE->assign('language', $conf->get('translation.language'));
|
||||||
$PAGE->assign('gd_enabled', extension_loaded('gd'));
|
$PAGE->assign('gd_enabled', extension_loaded('gd'));
|
||||||
|
$PAGE->assign('thumbnails_mode', $conf->get('thumbnails.mode', Thumbnailer::MODE_NONE));
|
||||||
$PAGE->assign('pagetitle', t('Configure') .' - '. $conf->get('general.title', 'Shaarli'));
|
$PAGE->assign('pagetitle', t('Configure') .' - '. $conf->get('general.title', 'Shaarli'));
|
||||||
$PAGE->renderPage('configure');
|
$PAGE->renderPage('configure');
|
||||||
exit;
|
exit;
|
||||||
|
@ -1162,7 +1163,7 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager,
|
||||||
$link['title'] = $link['url'];
|
$link['title'] = $link['url'];
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($conf->get('thumbnails.enabled')) {
|
if ($conf->get('thumbnails.mode', Thumbnailer::MODE_NONE) !== Thumbnailer::MODE_NONE) {
|
||||||
$thumbnailer = new Thumbnailer($conf);
|
$thumbnailer = new Thumbnailer($conf);
|
||||||
$link['thumbnail'] = $thumbnailer->get($url);
|
$link['thumbnail'] = $thumbnailer->get($url);
|
||||||
}
|
}
|
||||||
|
@ -1606,7 +1607,8 @@ function buildLinkList($PAGE, $LINKSDB, $conf, $pluginManager, $loginManager)
|
||||||
$i = ($page-1) * $_SESSION['LINKS_PER_PAGE'];
|
$i = ($page-1) * $_SESSION['LINKS_PER_PAGE'];
|
||||||
$end = $i + $_SESSION['LINKS_PER_PAGE'];
|
$end = $i + $_SESSION['LINKS_PER_PAGE'];
|
||||||
|
|
||||||
if ($conf->get('thumbnails.enabled')) {
|
$thumbnailsEnabled = $conf->get('thumbnails.mode', Thumbnailer::MODE_NONE) !== Thumbnailer::MODE_NONE;
|
||||||
|
if ($thumbnailsEnabled) {
|
||||||
$thumbnailer = new Thumbnailer($conf);
|
$thumbnailer = new Thumbnailer($conf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1633,7 +1635,7 @@ function buildLinkList($PAGE, $LINKSDB, $conf, $pluginManager, $loginManager)
|
||||||
|
|
||||||
// Thumbnails enabled, not a note,
|
// Thumbnails enabled, not a note,
|
||||||
// and (never retrieved yet or no valid cache file)
|
// and (never retrieved yet or no valid cache file)
|
||||||
if ($conf->get('thumbnails.enabled') && $link['url'][0] != '?'
|
if ($thumbnailsEnabled && $link['url'][0] != '?'
|
||||||
&& (! isset($link['thumbnail']) || ($link['thumbnail'] !== false && ! is_file($link['thumbnail'])))
|
&& (! isset($link['thumbnail']) || ($link['thumbnail'] !== false && ! is_file($link['thumbnail'])))
|
||||||
) {
|
) {
|
||||||
$elem = $LINKSDB[$keys[$i]];
|
$elem = $LINKSDB[$keys[$i]];
|
||||||
|
|
|
@ -25,14 +25,20 @@ class ThumbnailerTest extends TestCase
|
||||||
*/
|
*/
|
||||||
protected $thumbnailer;
|
protected $thumbnailer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var ConfigManager
|
||||||
|
*/
|
||||||
|
protected $conf;
|
||||||
|
|
||||||
public function setUp()
|
public function setUp()
|
||||||
{
|
{
|
||||||
$conf = new ConfigManager('tests/utils/config/configJson');
|
$this->conf = new ConfigManager('tests/utils/config/configJson');
|
||||||
$conf->set('thumbnails.width', self::WIDTH);
|
$this->conf->set('thumbnails.mode', Thumbnailer::MODE_ALL);
|
||||||
$conf->set('thumbnails.height', self::HEIGHT);
|
$this->conf->set('thumbnails.width', self::WIDTH);
|
||||||
$conf->set('dev.debug', true);
|
$this->conf->set('thumbnails.height', self::HEIGHT);
|
||||||
|
$this->conf->set('dev.debug', true);
|
||||||
|
|
||||||
$this->thumbnailer = new Thumbnailer($conf);
|
$this->thumbnailer = new Thumbnailer($this->conf);
|
||||||
// cache files in the sandbox
|
// cache files in the sandbox
|
||||||
WTConfigManager::addFile('tests/utils/config/wt.json');
|
WTConfigManager::addFile('tests/utils/config/wt.json');
|
||||||
}
|
}
|
||||||
|
@ -43,9 +49,9 @@ public function tearDown()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test a thumbnail with a custom size.
|
* Test a thumbnail with a custom size in 'all' mode.
|
||||||
*/
|
*/
|
||||||
public function testThumbnailValid()
|
public function testThumbnailAllValid()
|
||||||
{
|
{
|
||||||
$thumb = $this->thumbnailer->get('https://github.com/shaarli/Shaarli/');
|
$thumb = $this->thumbnailer->get('https://github.com/shaarli/Shaarli/');
|
||||||
$this->assertNotFalse($thumb);
|
$this->assertNotFalse($thumb);
|
||||||
|
@ -54,6 +60,29 @@ public function testThumbnailValid()
|
||||||
$this->assertEquals(self::HEIGHT, imagesy($image));
|
$this->assertEquals(self::HEIGHT, imagesy($image));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test a thumbnail with a custom size in 'common' mode.
|
||||||
|
*/
|
||||||
|
public function testThumbnailCommonValid()
|
||||||
|
{
|
||||||
|
$this->conf->set('thumbnails.mode', Thumbnailer::MODE_COMMON);
|
||||||
|
$thumb = $this->thumbnailer->get('https://imgur.com/jlFgGpe');
|
||||||
|
$this->assertNotFalse($thumb);
|
||||||
|
$image = imagecreatefromstring(file_get_contents($thumb));
|
||||||
|
$this->assertEquals(self::WIDTH, imagesx($image));
|
||||||
|
$this->assertEquals(self::HEIGHT, imagesy($image));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test a thumbnail in 'common' mode which isn't include in common websites.
|
||||||
|
*/
|
||||||
|
public function testThumbnailCommonInvalid()
|
||||||
|
{
|
||||||
|
$this->conf->set('thumbnails.mode', Thumbnailer::MODE_COMMON);
|
||||||
|
$thumb = $this->thumbnailer->get('https://github.com/shaarli/Shaarli/');
|
||||||
|
$this->assertFalse($thumb);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test a thumbnail that can't be retrieved.
|
* Test a thumbnail that can't be retrieved.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
use Shaarli\Config\ConfigJson;
|
use Shaarli\Config\ConfigJson;
|
||||||
use Shaarli\Config\ConfigManager;
|
use Shaarli\Config\ConfigManager;
|
||||||
use Shaarli\Config\ConfigPhp;
|
use Shaarli\Config\ConfigPhp;
|
||||||
|
use Shaarli\Thumbnailer;
|
||||||
|
|
||||||
require_once 'tests/Updater/DummyUpdater.php';
|
require_once 'tests/Updater/DummyUpdater.php';
|
||||||
require_once 'inc/rain.tpl.class.php';
|
require_once 'inc/rain.tpl.class.php';
|
||||||
|
@ -696,7 +697,7 @@ public function testUpdateMethodWebThumbnailerEnabled()
|
||||||
$updater = new Updater([], [], $this->conf, true, $_SESSION);
|
$updater = new Updater([], [], $this->conf, true, $_SESSION);
|
||||||
$this->assertTrue($updater->updateMethodWebThumbnailer());
|
$this->assertTrue($updater->updateMethodWebThumbnailer());
|
||||||
$this->assertFalse($this->conf->exists('thumbnail'));
|
$this->assertFalse($this->conf->exists('thumbnail'));
|
||||||
$this->assertTrue($this->conf->get('thumbnails.enabled'));
|
$this->assertEquals(\Shaarli\Thumbnailer::MODE_ALL, $this->conf->get('thumbnails.mode'));
|
||||||
$this->assertEquals(125, $this->conf->get('thumbnails.width'));
|
$this->assertEquals(125, $this->conf->get('thumbnails.width'));
|
||||||
$this->assertEquals(90, $this->conf->get('thumbnails.height'));
|
$this->assertEquals(90, $this->conf->get('thumbnails.height'));
|
||||||
$this->assertContains('You have enabled thumbnails', $_SESSION['warnings'][0]);
|
$this->assertContains('You have enabled thumbnails', $_SESSION['warnings'][0]);
|
||||||
|
@ -712,7 +713,7 @@ public function testUpdateMethodWebThumbnailerDisabled()
|
||||||
$updater = new Updater([], [], $this->conf, true, $_SESSION);
|
$updater = new Updater([], [], $this->conf, true, $_SESSION);
|
||||||
$this->assertTrue($updater->updateMethodWebThumbnailer());
|
$this->assertTrue($updater->updateMethodWebThumbnailer());
|
||||||
$this->assertFalse($this->conf->exists('thumbnail'));
|
$this->assertFalse($this->conf->exists('thumbnail'));
|
||||||
$this->assertFalse($this->conf->get('thumbnails.enabled'));
|
$this->assertEquals(Thumbnailer::MODE_NONE, $this->conf->get('thumbnails.mode'));
|
||||||
$this->assertEquals(125, $this->conf->get('thumbnails.width'));
|
$this->assertEquals(125, $this->conf->get('thumbnails.width'));
|
||||||
$this->assertEquals(90, $this->conf->get('thumbnails.height'));
|
$this->assertEquals(90, $this->conf->get('thumbnails.height'));
|
||||||
$this->assertTrue(empty($_SESSION['warnings']));
|
$this->assertTrue(empty($_SESSION['warnings']));
|
||||||
|
@ -726,7 +727,7 @@ public function testUpdateMethodWebThumbnailerNothingToDo()
|
||||||
$updater = new Updater([], [], $this->conf, true, $_SESSION);
|
$updater = new Updater([], [], $this->conf, true, $_SESSION);
|
||||||
$this->assertTrue($updater->updateMethodWebThumbnailer());
|
$this->assertTrue($updater->updateMethodWebThumbnailer());
|
||||||
$this->assertFalse($this->conf->exists('thumbnail'));
|
$this->assertFalse($this->conf->exists('thumbnail'));
|
||||||
$this->assertTrue($this->conf->get('thumbnails.enabled'));
|
$this->assertEquals(Thumbnailer::MODE_COMMON, $this->conf->get('thumbnails.mode'));
|
||||||
$this->assertEquals(90, $this->conf->get('thumbnails.width'));
|
$this->assertEquals(90, $this->conf->get('thumbnails.width'));
|
||||||
$this->assertEquals(53, $this->conf->get('thumbnails.height'));
|
$this->assertEquals(53, $this->conf->get('thumbnails.height'));
|
||||||
$this->assertTrue(empty($_SESSION['warnings']));
|
$this->assertTrue(empty($_SESSION['warnings']));
|
||||||
|
|
|
@ -76,7 +76,7 @@
|
||||||
"extensions": []
|
"extensions": []
|
||||||
},
|
},
|
||||||
"thumbnails": {
|
"thumbnails": {
|
||||||
"enabled": true,
|
"mode": "common",
|
||||||
"width": 90,
|
"width": 90,
|
||||||
"height": 53
|
"height": 53
|
||||||
}
|
}
|
||||||
|
|
|
@ -259,8 +259,17 @@ <h2 class="window-title">{'Configure'|t}</h2>
|
||||||
</div>
|
</div>
|
||||||
<div class="pure-u-lg-{$ratioInput} pure-u-{$ratioInputMobile}">
|
<div class="pure-u-lg-{$ratioInput} pure-u-{$ratioInputMobile}">
|
||||||
<div class="form-input">
|
<div class="form-input">
|
||||||
<input type="checkbox" name="enableThumbnails" id="enableThumbnails"
|
<select name="enableThumbnails" id="enableThumbnails" class="align">
|
||||||
{if="$thumbnails_enabled"}checked{/if} {if="!$gd_enabled"}disabled{/if} />
|
<option value="all" {if="$thumbnails_mode=='all'"}selected{/if}>
|
||||||
|
{'All'|t}
|
||||||
|
</option>
|
||||||
|
<option value="common" {if="$thumbnails_mode=='common'"}selected{/if}>
|
||||||
|
{'Only common media hosts'|t}
|
||||||
|
</option>
|
||||||
|
<option value="none" {if="$thumbnails_mode=='none'"}selected{/if}>
|
||||||
|
{'None'|t}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -131,8 +131,17 @@
|
||||||
<tr>
|
<tr>
|
||||||
<td valign="top"><b>Enable thumbnails</b></td>
|
<td valign="top"><b>Enable thumbnails</b></td>
|
||||||
<td>
|
<td>
|
||||||
<input type="checkbox" name="enableThumbnails" id="enableThumbnails"
|
<select name="enableThumbnails" id="enableThumbnails" class="align">
|
||||||
{if="$thumbnails_enabled"}checked{/if} {if="!$gd_enabled"}disabled{/if}>
|
<option value="all" {if="$thumbnails_mode=='all'"}selected{/if}>
|
||||||
|
{'All'|t}
|
||||||
|
</option>
|
||||||
|
<option value="common" {if="$thumbnails_mode=='common'"}selected{/if}>
|
||||||
|
{'Only common media hosts'|t}
|
||||||
|
</option>
|
||||||
|
<option value="none" {if="$thumbnails_mode=='none'"}selected{/if}>
|
||||||
|
{'None'|t}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
<label for="enableThumbnails">
|
<label for="enableThumbnails">
|
||||||
{if="! $gd_enabled"}
|
{if="! $gd_enabled"}
|
||||||
{'You need to enable the extension <code>php-gd</code> to use thumbnails.'|t}
|
{'You need to enable the extension <code>php-gd</code> to use thumbnails.'|t}
|
||||||
|
|
Loading…
Reference in a new issue