aboutsummaryrefslogtreecommitdiffhomepage
path: root/application/Thumbnailer.php
blob: 167d62967891ebcb3fc4c17ee1f18b481ab523ac (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
<?php

namespace Shaarli;

use Shaarli\Config\ConfigManager;
use WebThumbnailer\Exception\WebThumbnailerException;
use WebThumbnailer\WebThumbnailer;
use WebThumbnailer\Application\ConfigManager as WTConfigManager;

/**
 * Class Thumbnailer
 *
 * Utility class used to retrieve thumbnails using web-thumbnailer dependency.
 */
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.
     */
    protected $wt;

    /**
     * @var ConfigManager instance.
     */
    protected $conf;

    /**
     * Thumbnailer constructor.
     *
     * @param ConfigManager $conf instance.
     */
    public function __construct($conf)
    {
        $this->conf = $conf;

        if (! $this->checkRequirements()) {
            $this->conf->set('thumbnails.mode', Thumbnailer::MODE_NONE);
            $this->conf->write(true);
            // TODO: create a proper error handling system able to catch exceptions...
            die(t(
                'php-gd extension must be loaded to use thumbnails. '
                .'Thumbnails are now disabled. Please reload the page.'
            ));
        }

        $this->wt = new WebThumbnailer();
        WTConfigManager::addFile('inc/web-thumbnailer.json');
        $this->wt->maxWidth($this->conf->get('thumbnails.width'))
                 ->maxHeight($this->conf->get('thumbnails.height'))
                 ->crop(true)
                 ->debug($this->conf->get('dev.debug', false));
    }

    /**
     * Retrieve a thumbnail for given URL
     *
     * @param string $url where to look for a thumbnail.
     *
     * @return bool|string The thumbnail relative cache file path, or false if none has been found.
     */
    public function get($url)
    {
        if ($this->conf->get('thumbnails.mode') === self::MODE_COMMON
            && ! $this->isCommonMediaOrImage($url)
        ) {
            return false;
        }

        try {
            return $this->wt->thumbnail($url);
        } catch (WebThumbnailerException $e) {
            // Exceptions are only thrown in debug mode.
            error_log(get_class($e) . ': ' . $e->getMessage());
        }
        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;
    }

    /**
     * Make sure that requirements are match to use thumbnails:
     *   - php-gd is loaded
     */
    protected function checkRequirements()
    {
        return extension_loaded('gd');
    }
}