Passed
Pull Request — master (#41)
by Dante
02:26
created

ThumbHelper::initialize()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 7
nc 4
nop 1
dl 0
loc 10
rs 10
c 0
b 0
f 0
1
<?php
2
declare(strict_types=1);
3
4
/**
5
 * BEdita, API-first content management framework
6
 * Copyright 2019 ChannelWeb Srl, Chialab Srl
7
 *
8
 * This file is part of BEdita: you can redistribute it and/or modify
9
 * it under the terms of the GNU Lesser General Public License as published
10
 * by the Free Software Foundation, either version 3 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * See LICENSE.LGPL or <http://gnu.org/licenses/lgpl-3.0.html> for more details.
14
 */
15
namespace BEdita\WebTools\View\Helper;
16
17
use BEdita\WebTools\ApiClientProvider;
18
use Cake\Cache\Cache;
19
use Cake\Log\LogTrait;
20
use Cake\Utility\Hash;
21
use Cake\View\Helper;
22
23
/**
24
 * Helper to obtain thumbnail url
25
 */
26
class ThumbHelper extends Helper
27
{
28
    use LogTrait;
29
30
    /**
31
     * Default config for this helper.
32
     *
33
     * @var array
34
     */
35
    protected $_defaultConfig = [
36
        'cache' => '_thumbs_',
37
    ];
38
39
    /**
40
     * @var int Thumb not available
41
     */
42
    public const NOT_AVAILABLE = -10;
43
44
    /**
45
     * @var int Thumb not ready
46
     */
47
    public const NOT_READY = -20;
48
49
    /**
50
     * @var int Thumb not acceptable
51
     */
52
    public const NOT_ACCEPTABLE = -30;
53
54
    /**
55
     * @var int Thumb has no url
56
     */
57
    public const NO_URL = -40;
58
59
    /**
60
     * @var int Thumb is OK
61
     */
62
    public const OK = 1;
63
64
    /**
65
     * Use 'default' as fallback if no cache configuration is found.
66
     *
67
     * @param array $config The configuration settings provided to this helper.
68
     * @return void
69
     */
70
    public function initialize(array $config): void
71
    {
72
        parent::initialize($config);
73
        if (!empty($config['cache'])) {
74
            $this->setConfig('cache', $config['cache']);
75
        }
76
        $cacheCfg = $this->getConfig('cache');
77
        $cfg = Cache::getConfig($cacheCfg);
78
        if ($cfg === null) {
79
            $this->setConfig('cache', 'default');
80
        }
81
    }
82
83
    /**
84
     * Verify status of image thumb.
85
     * Return int representing status.
86
     * Possible values:
87
     *
88
     *   NOT_AVAILABLE: something went wrong during api call
89
     *   NOT_READY: thumb is available, but not ready
90
     *   NOT_ACCEPTABLE: image is not acceptable, api won't create thumb
91
     *   NO_URL: url not present in api response
92
     *   OK: thumb available, ready and with a proper url
93
     *
94
     * @param int|string $imageId The image ID
95
     * @param array|null $options The thumbs options
96
     * @param string|null $url The thumb url to populate when static::OK
97
     * @return int|null
98
     */
99
    public function status($imageId, ?array $options = ['preset' => 'default'], &$url = ''): ?int
100
    {
101
        if (empty($imageId) && empty($options['ids'])) {
102
            return static::NOT_ACCEPTABLE;
103
        }
104
        try {
105
            $apiClient = ApiClientProvider::getApiClient();
106
            $response = $apiClient->thumbs($imageId, $options);
107
            if (empty($response['meta']['thumbnails'][0])) {
108
                return static::NOT_AVAILABLE;
109
            }
110
            $thumb = $response['meta']['thumbnails'][0];
111
            // check thumb is ready
112
            if (!$this->isReady($thumb)) {
113
                return static::NOT_READY;
114
            }
115
            // check thumb is acceptable
116
            if (!$this->isAcceptable($thumb)) {
117
                return static::NOT_ACCEPTABLE;
118
            }
119
            // check thumb has url
120
            if (!$this->hasUrl($thumb)) {
121
                return static::NO_URL;
122
            }
123
            $url = $thumb['url'];
124
        } catch (\Exception $e) {
125
            $this->log($e->getMessage(), 'error');
126
127
            return static::NOT_AVAILABLE;
128
        }
129
130
        return static::OK;
131
    }
132
133
    /**
134
     * Obtain thumbnail using API thumbs.
135
     *
136
     * @param int $imageId The image ID.
137
     * @param array|null $options The thumbs options.
138
     * @return string|int The url if available, the status code otherwise (see Thumb constants).
139
     */
140
    public function url($imageId, $options)
141
    {
142
        $url = null;
143
        $status = $this->status($imageId, $options, $url);
144
        if ($status === static::OK) {
145
            return $url;
146
        }
147
148
        return $status;
149
    }
150
151
    /**
152
     * Verify if thumb is acceptable
153
     *
154
     * @param array $thumb The thumbnail data
155
     * @return bool the acceptable flag
156
     */
157
    private function isAcceptable($thumb = []): bool
158
    {
159
        if (isset($thumb['acceptable']) && $thumb['acceptable'] === false) {
160
            return false;
161
        }
162
163
        return true;
164
    }
165
166
    /**
167
     * Verify if thumb is ready
168
     *
169
     * @param array $thumb The thumbnail data
170
     * @return bool the ready flag
171
     */
172
    private function isReady($thumb = []): bool
173
    {
174
        if (!empty($thumb['ready']) && $thumb['ready'] === true) {
175
            return true;
176
        }
177
178
        return false;
179
    }
180
181
    /**
182
     * Verify if thumb has url
183
     *
184
     * @param array $thumb The thumbnail data
185
     * @return bool the url availability
186
     */
187
    private function hasUrl($thumb = []): bool
188
    {
189
        if (!empty($thumb['url'])) {
190
            return true;
191
        }
192
193
        return false;
194
    }
195
196
    /**
197
     * Retrieve thumb URL using cache.
198
     * Silently fail with log if no image 'id' is found in array.
199
     *
200
     * @param  array  $image   Image object array containing at least `id`
201
     * @param  string $options Thumb options
202
     * @return string
203
     */
204
    public function getUrl(array $image, array $options = []): string
205
    {
206
        if (empty($image['id'])) {
207
            $this->log(sprintf('Missing image ID - %s', json_encode($image)), 'warning');
208
209
            return '';
210
        }
211
        $thumbHash = md5((string)Hash::get($image, 'meta.media_url') . json_encode($options));
212
        $key = sprintf('%d_%s', $image['id'], $thumbHash);
213
214
        return (string)Cache::remember(
215
            $key,
216
            function () use ($image, $options) {
217
                return $this->url($image['id'], $options);
218
            },
219
            $this->getConfig('cache')
220
        );
221
    }
222
}
223