aboutsummaryrefslogtreecommitdiffhomepage
path: root/application
diff options
context:
space:
mode:
authorArthurHoaro <arthur@hoa.ro>2018-07-28 09:41:29 +0200
committerGitHub <noreply@github.com>2018-07-28 09:41:29 +0200
commitad5f47adbaee1eef85e90950ab8a45fe82959924 (patch)
treed23a186661db00d36cb2b2287a7bf890fbc62cfb /application
parent8fdd65b88412a0db28c723a486650c434fe5668c (diff)
parent7b4fea0e39be9e74e9aef13e73af9bbd2b1a6397 (diff)
downloadShaarli-ad5f47adbaee1eef85e90950ab8a45fe82959924.tar.gz
Shaarli-ad5f47adbaee1eef85e90950ab8a45fe82959924.tar.zst
Shaarli-ad5f47adbaee1eef85e90950ab8a45fe82959924.zip
Merge pull request #687 from ArthurHoaro/web-thumb
Use web-thumbnailer to retrieve thumbnails
Diffstat (limited to 'application')
-rw-r--r--application/PageBuilder.php37
-rw-r--r--application/Router.php12
-rw-r--r--application/Thumbnailer.php127
-rw-r--r--application/Updater.php36
-rw-r--r--application/config/ConfigManager.php56
5 files changed, 258 insertions, 10 deletions
diff --git a/application/PageBuilder.php b/application/PageBuilder.php
index a4483870..b1abe0d0 100644
--- a/application/PageBuilder.php
+++ b/application/PageBuilder.php
@@ -1,6 +1,7 @@
1<?php 1<?php
2 2
3use Shaarli\Config\ConfigManager; 3use Shaarli\Config\ConfigManager;
4use Shaarli\Thumbnailer;
4 5
5/** 6/**
6 * This class is in charge of building the final page. 7 * This class is in charge of building the final page.
@@ -22,10 +23,20 @@ class PageBuilder
22 protected $conf; 23 protected $conf;
23 24
24 /** 25 /**
26 * @var array $_SESSION
27 */
28 protected $session;
29
30 /**
25 * @var LinkDB $linkDB instance. 31 * @var LinkDB $linkDB instance.
26 */ 32 */
27 protected $linkDB; 33 protected $linkDB;
28 34
35 /**
36 * @var null|string XSRF token
37 */
38 protected $token;
39
29 /** @var bool $isLoggedIn Whether the user is logged in **/ 40 /** @var bool $isLoggedIn Whether the user is logged in **/
30 protected $isLoggedIn = false; 41 protected $isLoggedIn = false;
31 42
@@ -33,14 +44,17 @@ class PageBuilder
33 * PageBuilder constructor. 44 * PageBuilder constructor.
34 * $tpl is initialized at false for lazy loading. 45 * $tpl is initialized at false for lazy loading.
35 * 46 *
36 * @param ConfigManager $conf Configuration Manager instance (reference). 47 * @param ConfigManager $conf Configuration Manager instance (reference).
37 * @param LinkDB $linkDB instance. 48 * @param array $session $_SESSION array
38 * @param string $token Session token 49 * @param LinkDB $linkDB instance.
50 * @param string $token Session token
51 * @param bool $isLoggedIn
39 */ 52 */
40 public function __construct(&$conf, $linkDB = null, $token = null, $isLoggedIn = false) 53 public function __construct(&$conf, $session, $linkDB = null, $token = null, $isLoggedIn = false)
41 { 54 {
42 $this->tpl = false; 55 $this->tpl = false;
43 $this->conf = $conf; 56 $this->conf = $conf;
57 $this->session = $session;
44 $this->linkDB = $linkDB; 58 $this->linkDB = $linkDB;
45 $this->token = $token; 59 $this->token = $token;
46 $this->isLoggedIn = $isLoggedIn; 60 $this->isLoggedIn = $isLoggedIn;
@@ -105,6 +119,19 @@ class PageBuilder
105 if ($this->linkDB !== null) { 119 if ($this->linkDB !== null) {
106 $this->tpl->assign('tags', $this->linkDB->linksCountPerTag()); 120 $this->tpl->assign('tags', $this->linkDB->linksCountPerTag());
107 } 121 }
122
123 $this->tpl->assign(
124 'thumbnails_enabled',
125 $this->conf->get('thumbnails.mode', Thumbnailer::MODE_NONE) !== Thumbnailer::MODE_NONE
126 );
127 $this->tpl->assign('thumbnails_width', $this->conf->get('thumbnails.width'));
128 $this->tpl->assign('thumbnails_height', $this->conf->get('thumbnails.height'));
129
130 if (! empty($_SESSION['warnings'])) {
131 $this->tpl->assign('global_warnings', $_SESSION['warnings']);
132 unset($_SESSION['warnings']);
133 }
134
108 // To be removed with a proper theme configuration. 135 // To be removed with a proper theme configuration.
109 $this->tpl->assign('conf', $this->conf); 136 $this->tpl->assign('conf', $this->conf);
110 } 137 }
diff --git a/application/Router.php b/application/Router.php
index 4df0387c..bf86b884 100644
--- a/application/Router.php
+++ b/application/Router.php
@@ -7,6 +7,8 @@
7 */ 7 */
8class Router 8class Router
9{ 9{
10 public static $AJAX_THUMB_UPDATE = 'ajax_thumb_update';
11
10 public static $PAGE_LOGIN = 'login'; 12 public static $PAGE_LOGIN = 'login';
11 13
12 public static $PAGE_PICWALL = 'picwall'; 14 public static $PAGE_PICWALL = 'picwall';
@@ -47,6 +49,8 @@ class Router
47 49
48 public static $PAGE_SAVE_PLUGINSADMIN = 'save_pluginadmin'; 50 public static $PAGE_SAVE_PLUGINSADMIN = 'save_pluginadmin';
49 51
52 public static $PAGE_THUMBS_UPDATE = 'thumbs_update';
53
50 public static $GET_TOKEN = 'token'; 54 public static $GET_TOKEN = 'token';
51 55
52 /** 56 /**
@@ -101,6 +105,14 @@ class Router
101 return self::$PAGE_FEED_RSS; 105 return self::$PAGE_FEED_RSS;
102 } 106 }
103 107
108 if (startsWith($query, 'do='. self::$PAGE_THUMBS_UPDATE)) {
109 return self::$PAGE_THUMBS_UPDATE;
110 }
111
112 if (startsWith($query, 'do='. self::$AJAX_THUMB_UPDATE)) {
113 return self::$AJAX_THUMB_UPDATE;
114 }
115
104 // At this point, only loggedin pages. 116 // At this point, only loggedin pages.
105 if (!$loggedIn) { 117 if (!$loggedIn) {
106 return self::$PAGE_LINKLIST; 118 return self::$PAGE_LINKLIST;
diff --git a/application/Thumbnailer.php b/application/Thumbnailer.php
new file mode 100644
index 00000000..7d0d9c33
--- /dev/null
+++ b/application/Thumbnailer.php
@@ -0,0 +1,127 @@
1<?php
2
3namespace Shaarli;
4
5use Shaarli\Config\ConfigManager;
6use WebThumbnailer\Exception\WebThumbnailerException;
7use WebThumbnailer\WebThumbnailer;
8use WebThumbnailer\Application\ConfigManager as WTConfigManager;
9
10/**
11 * Class Thumbnailer
12 *
13 * Utility class used to retrieve thumbnails using web-thumbnailer dependency.
14 */
15class Thumbnailer
16{
17 const COMMON_MEDIA_DOMAINS = [
18 'imgur.com',
19 'flickr.com',
20 'youtube.com',
21 'wikimedia.org',
22 'redd.it',
23 'gfycat.com',
24 'media.giphy.com',
25 'twitter.com',
26 'twimg.com',
27 'instagram.com',
28 'pinterest.com',
29 'pinterest.fr',
30 'tumblr.com',
31 'deviantart.com',
32 ];
33
34 const MODE_ALL = 'all';
35 const MODE_COMMON = 'common';
36 const MODE_NONE = 'none';
37
38 /**
39 * @var WebThumbnailer instance.
40 */
41 protected $wt;
42
43 /**
44 * @var ConfigManager instance.
45 */
46 protected $conf;
47
48 /**
49 * Thumbnailer constructor.
50 *
51 * @param ConfigManager $conf instance.
52 */
53 public function __construct($conf)
54 {
55 $this->conf = $conf;
56
57 if (! $this->checkRequirements()) {
58 $this->conf->set('thumbnails.enabled', false);
59 $this->conf->write(true);
60 // TODO: create a proper error handling system able to catch exceptions...
61 die(t('php-gd extension must be loaded to use thumbnails. Thumbnails are now disabled. Please reload the page.'));
62 }
63
64 $this->wt = new WebThumbnailer();
65 WTConfigManager::addFile('inc/web-thumbnailer.json');
66 $this->wt->maxWidth($this->conf->get('thumbnails.width'))
67 ->maxHeight($this->conf->get('thumbnails.height'))
68 ->crop(true)
69 ->debug($this->conf->get('dev.debug', false));
70 }
71
72 /**
73 * Retrieve a thumbnail for given URL
74 *
75 * @param string $url where to look for a thumbnail.
76 *
77 * @return bool|string The thumbnail relative cache file path, or false if none has been found.
78 */
79 public function get($url)
80 {
81 if ($this->conf->get('thumbnails.mode') === self::MODE_COMMON
82 && ! $this->isCommonMediaOrImage($url)
83 ) {
84 return false;
85 }
86
87 try {
88 return $this->wt->thumbnail($url);
89 } catch (WebThumbnailerException $e) {
90 // Exceptions are only thrown in debug mode.
91 error_log(get_class($e) . ': ' . $e->getMessage());
92 }
93 return false;
94 }
95
96 /**
97 * We check weather the given URL is from a common media domain,
98 * or if the file extension is an image.
99 *
100 * @param string $url to check
101 *
102 * @return bool true if it's an image or from a common media domain, false otherwise.
103 */
104 public function isCommonMediaOrImage($url)
105 {
106 foreach (self::COMMON_MEDIA_DOMAINS as $domain) {
107 if (strpos($url, $domain) !== false) {
108 return true;
109 }
110 }
111
112 if (endsWith($url, '.jpg') || endsWith($url, '.png') || endsWith($url, '.jpeg')) {
113 return true;
114 }
115
116 return false;
117 }
118
119 /**
120 * Make sure that requirements are match to use thumbnails:
121 * - php-gd is loaded
122 */
123 protected function checkRequirements()
124 {
125 return extension_loaded('gd');
126 }
127}
diff --git a/application/Updater.php b/application/Updater.php
index dece2c02..c2aa1568 100644
--- a/application/Updater.php
+++ b/application/Updater.php
@@ -2,6 +2,7 @@
2use Shaarli\Config\ConfigJson; 2use Shaarli\Config\ConfigJson;
3use Shaarli\Config\ConfigPhp; 3use Shaarli\Config\ConfigPhp;
4use Shaarli\Config\ConfigManager; 4use Shaarli\Config\ConfigManager;
5use Shaarli\Thumbnailer;
5 6
6/** 7/**
7 * Class Updater. 8 * Class Updater.
@@ -31,6 +32,11 @@ class Updater
31 protected $isLoggedIn; 32 protected $isLoggedIn;
32 33
33 /** 34 /**
35 * @var array $_SESSION
36 */
37 protected $session;
38
39 /**
34 * @var ReflectionMethod[] List of current class methods. 40 * @var ReflectionMethod[] List of current class methods.
35 */ 41 */
36 protected $methods; 42 protected $methods;
@@ -42,13 +48,17 @@ class Updater
42 * @param LinkDB $linkDB LinkDB instance. 48 * @param LinkDB $linkDB LinkDB instance.
43 * @param ConfigManager $conf Configuration Manager instance. 49 * @param ConfigManager $conf Configuration Manager instance.
44 * @param boolean $isLoggedIn True if the user is logged in. 50 * @param boolean $isLoggedIn True if the user is logged in.
51 * @param array $session $_SESSION (by reference)
52 *
53 * @throws ReflectionException
45 */ 54 */
46 public function __construct($doneUpdates, $linkDB, $conf, $isLoggedIn) 55 public function __construct($doneUpdates, $linkDB, $conf, $isLoggedIn, &$session = [])
47 { 56 {
48 $this->doneUpdates = $doneUpdates; 57 $this->doneUpdates = $doneUpdates;
49 $this->linkDB = $linkDB; 58 $this->linkDB = $linkDB;
50 $this->conf = $conf; 59 $this->conf = $conf;
51 $this->isLoggedIn = $isLoggedIn; 60 $this->isLoggedIn = $isLoggedIn;
61 $this->session = &$session;
52 62
53 // Retrieve all update methods. 63 // Retrieve all update methods.
54 $class = new ReflectionClass($this); 64 $class = new ReflectionClass($this);
@@ -480,6 +490,30 @@ class Updater
480 } 490 }
481 491
482 $this->conf->write($this->isLoggedIn); 492 $this->conf->write($this->isLoggedIn);
493 return true;
494 }
495
496 /**
497 * * Move thumbnails management to WebThumbnailer, coming with new settings.
498 */
499 public function updateMethodWebThumbnailer()
500 {
501 if ($this->conf->exists('thumbnails.mode')) {
502 return true;
503 }
504
505 $thumbnailsEnabled = $this->conf->get('thumbnail.enable_thumbnails', true);
506 $this->conf->set('thumbnails.mode', $thumbnailsEnabled ? Thumbnailer::MODE_ALL : Thumbnailer::MODE_NONE);
507 $this->conf->set('thumbnails.width', 125);
508 $this->conf->set('thumbnails.height', 90);
509 $this->conf->remove('thumbnail');
510 $this->conf->write(true);
511
512 if ($thumbnailsEnabled) {
513 $this->session['warnings'][] = t(
514 'You have enabled or changed thumbnails mode. <a href="?do=thumbs_update">Please synchronize them</a>.'
515 );
516 }
483 517
484 return true; 518 return true;
485 } 519 }
diff --git a/application/config/ConfigManager.php b/application/config/ConfigManager.php
index 82f4a368..32aaea48 100644
--- a/application/config/ConfigManager.php
+++ b/application/config/ConfigManager.php
@@ -148,6 +148,33 @@ class ConfigManager
148 } 148 }
149 149
150 /** 150 /**
151 * Remove a config element from the config file.
152 *
153 * @param string $setting Asked setting, keys separated with dots.
154 * @param bool $write Write the new setting in the config file, default false.
155 * @param bool $isLoggedIn User login state, default false.
156 *
157 * @throws \Exception Invalid
158 */
159 public function remove($setting, $write = false, $isLoggedIn = false)
160 {
161 if (empty($setting) || ! is_string($setting)) {
162 throw new \Exception(t('Invalid setting key parameter. String expected, got: '). gettype($setting));
163 }
164
165 // During the ConfigIO transition, map legacy settings to the new ones.
166 if ($this->configIO instanceof ConfigPhp && isset(ConfigPhp::$LEGACY_KEYS_MAPPING[$setting])) {
167 $setting = ConfigPhp::$LEGACY_KEYS_MAPPING[$setting];
168 }
169
170 $settings = explode('.', $setting);
171 self::removeConfig($settings, $this->loadedConfig);
172 if ($write) {
173 $this->write($isLoggedIn);
174 }
175 }
176
177 /**
151 * Check if a settings exists. 178 * Check if a settings exists.
152 * 179 *
153 * Supports nested settings with dot separated keys. 180 * Supports nested settings with dot separated keys.
@@ -272,7 +299,7 @@ class ConfigManager
272 * 299 *
273 * @param array $settings Ordered array which contains keys to find. 300 * @param array $settings Ordered array which contains keys to find.
274 * @param mixed $value 301 * @param mixed $value
275 * @param array $conf Loaded settings, then sub-array. 302 * @param array $conf Loaded settings, then sub-array.
276 * 303 *
277 * @return mixed Found setting or NOT_FOUND flag. 304 * @return mixed Found setting or NOT_FOUND flag.
278 */ 305 */
@@ -290,6 +317,27 @@ class ConfigManager
290 } 317 }
291 318
292 /** 319 /**
320 * Recursive function which find asked setting in the loaded config and deletes it.
321 *
322 * @param array $settings Ordered array which contains keys to find.
323 * @param array $conf Loaded settings, then sub-array.
324 *
325 * @return mixed Found setting or NOT_FOUND flag.
326 */
327 protected static function removeConfig($settings, &$conf)
328 {
329 if (!is_array($settings) || count($settings) == 0) {
330 return self::$NOT_FOUND;
331 }
332
333 $setting = array_shift($settings);
334 if (count($settings) > 0) {
335 return self::removeConfig($settings, $conf[$setting]);
336 }
337 unset($conf[$setting]);
338 }
339
340 /**
293 * Set a bunch of default values allowing Shaarli to start without a config file. 341 * Set a bunch of default values allowing Shaarli to start without a config file.
294 */ 342 */
295 protected function setDefaultValues() 343 protected function setDefaultValues()
@@ -333,12 +381,12 @@ class ConfigManager
333 // default state of the 'remember me' checkbox of the login form 381 // default state of the 'remember me' checkbox of the login form
334 $this->setEmpty('privacy.remember_user_default', true); 382 $this->setEmpty('privacy.remember_user_default', true);
335 383
336 $this->setEmpty('thumbnail.enable_thumbnails', true);
337 $this->setEmpty('thumbnail.enable_localcache', true);
338
339 $this->setEmpty('redirector.url', ''); 384 $this->setEmpty('redirector.url', '');
340 $this->setEmpty('redirector.encode_url', true); 385 $this->setEmpty('redirector.encode_url', true);
341 386
387 $this->setEmpty('thumbnails.width', '125');
388 $this->setEmpty('thumbnails.height', '90');
389
342 $this->setEmpty('translation.language', 'auto'); 390 $this->setEmpty('translation.language', 'auto');
343 $this->setEmpty('translation.mode', 'php'); 391 $this->setEmpty('translation.mode', 'php');
344 $this->setEmpty('translation.extensions', []); 392 $this->setEmpty('translation.extensions', []);