ThumbHelper   A
last analyzed

Complexity

Total Complexity 24

Size/Duplication

Total Lines 197
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 59
c 2
b 0
f 0
dl 0
loc 197
rs 10
wmc 24

7 Methods

Rating   Name   Duplication   Size   Complexity  
A initialize() 0 10 3
B status() 0 35 8
A getUrl() 0 16 3
A isAcceptable() 0 7 3
A isReady() 0 7 3
A hasUrl() 0 7 2
A url() 0 9 2
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
use Exception;
23
24
/**
25
 * Helper to obtain thumbnail url
26
 */
27
class ThumbHelper extends Helper
28
{
29
    use LogTrait;
30
31
    /**
32
     * Default config for this helper.
33
     *
34
     * @var array
35
     */
36
    protected array $_defaultConfig = [
37
        'cache' => '_thumbs_',
38
    ];
39
40
    /**
41
     * @var int Thumb not available
42
     */
43
    public const NOT_AVAILABLE = -10;
44
45
    /**
46
     * @var int Thumb not ready
47
     */
48
    public const NOT_READY = -20;
49
50
    /**
51
     * @var int Thumb not acceptable
52
     */
53
    public const NOT_ACCEPTABLE = -30;
54
55
    /**
56
     * @var int Thumb has no url
57
     */
58
    public const NO_URL = -40;
59
60
    /**
61
     * @var int Thumb is OK
62
     */
63
    public const OK = 1;
64
65
    /**
66
     * Use 'default' as fallback if no cache configuration is found.
67
     *
68
     * @param array $config The configuration settings provided to this helper.
69
     * @return void
70
     */
71
    public function initialize(array $config): void
72
    {
73
        parent::initialize($config);
74
        if (!empty($config['cache'])) {
75
            $this->setConfig('cache', $config['cache']);
76
        }
77
        $cacheCfg = $this->getConfig('cache');
78
        $cfg = Cache::getConfig($cacheCfg);
79
        if ($cfg === null) {
80
            $this->setConfig('cache', 'default');
81
        }
82
    }
83
84
    /**
85
     * Verify status of image thumb.
86
     * Return int representing status.
87
     * Possible values:
88
     *
89
     *   NOT_AVAILABLE: something went wrong during api call
90
     *   NOT_READY: thumb is available, but not ready
91
     *   NOT_ACCEPTABLE: image is not acceptable, api won't create thumb
92
     *   NO_URL: url not present in api response
93
     *   OK: thumb available, ready and with a proper url
94
     *
95
     * @param string|int|null $imageId The image ID
96
     * @param array|null $options The thumbs options
97
     * @param string|null $url The thumb url to populate when static::OK
98
     * @return int|null
99
     */
100
    public function status(
101
        int|string|null $imageId,
102
        ?array $options = ['preset' => 'default'],
103
        ?string &$url = ''
104
    ): ?int {
105
        if (empty($imageId) && empty($options['ids'])) {
106
            return static::NOT_ACCEPTABLE;
107
        }
108
        try {
109
            $apiClient = ApiClientProvider::getApiClient();
110
            $response = $apiClient->thumbs($imageId, $options);
111
            if (empty($response['meta']['thumbnails'][0])) {
112
                return static::NOT_AVAILABLE;
113
            }
114
            $thumb = $response['meta']['thumbnails'][0];
115
            // check thumb is acceptable
116
            if (!$this->isAcceptable($thumb)) {
117
                return static::NOT_ACCEPTABLE;
118
            }
119
            // check thumb is ready
120
            if (!$this->isReady($thumb)) {
121
                return static::NOT_READY;
122
            }
123
            // check thumb has url
124
            if (!$this->hasUrl($thumb)) {
125
                return static::NO_URL;
126
            }
127
            $url = $thumb['url'];
128
        } catch (Exception $e) {
129
            $this->log($e->getMessage(), 'error');
130
131
            return static::NOT_AVAILABLE;
132
        }
133
134
        return static::OK;
135
    }
136
137
    /**
138
     * Obtain thumbnail using API thumbs.
139
     *
140
     * @param int $imageId The image ID.
141
     * @param array|null $options The thumbs options.
142
     * @return string|int The url if available, the status code otherwise (see Thumb constants).
143
     */
144
    public function url(int $imageId, ?array $options): string|int
145
    {
146
        $url = null;
147
        $status = $this->status($imageId, $options, $url);
148
        if ($status === static::OK) {
149
            return $url;
150
        }
151
152
        return $status;
153
    }
154
155
    /**
156
     * Verify if thumb is acceptable
157
     *
158
     * @param array $thumb The thumbnail data
159
     * @return bool the acceptable flag
160
     */
161
    private function isAcceptable(array $thumb = []): bool
162
    {
163
        if (isset($thumb['acceptable']) && $thumb['acceptable'] === false) {
164
            return false;
165
        }
166
167
        return true;
168
    }
169
170
    /**
171
     * Verify if thumb is ready
172
     *
173
     * @param array $thumb The thumbnail data
174
     * @return bool the ready flag
175
     */
176
    private function isReady(array $thumb = []): bool
177
    {
178
        if (!empty($thumb['ready']) && $thumb['ready'] === true) {
179
            return true;
180
        }
181
182
        return false;
183
    }
184
185
    /**
186
     * Verify if thumb has url
187
     *
188
     * @param array $thumb The thumbnail data
189
     * @return bool the url availability
190
     */
191
    private function hasUrl(array $thumb = []): bool
192
    {
193
        if (!empty($thumb['url'])) {
194
            return true;
195
        }
196
197
        return false;
198
    }
199
200
    /**
201
     * Retrieve thumb URL using cache.
202
     * Silently fail with log if no image 'id' is found in array.
203
     *
204
     * @param array|null $image Image object array containing at least `id`
205
     * @param string $options Thumb options
206
     * @return string
207
     */
208
    public function getUrl(?array $image, array $options = []): string
209
    {
210
        if (empty($image) || empty($image['id'])) {
211
            $this->log(sprintf('Missing image ID - %s', json_encode($image)), 'warning');
212
213
            return '';
214
        }
215
        $thumbHash = md5((string)Hash::get($image, 'meta.media_url') . json_encode($options));
216
        $key = sprintf('%d_%s', $image['id'], $thumbHash);
217
218
        return (string)Cache::remember(
219
            $key,
220
            function () use ($image, $options) {
221
                return $this->url($image['id'], $options);
222
            },
223
            $this->getConfig('cache')
224
        );
225
    }
226
}
227