Passed
Pull Request — master (#41)
by Paolo
02:14
created

ThumbHelper::url()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 5
c 1
b 0
f 0
nc 2
nop 2
dl 0
loc 9
rs 10
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
        if (Cache::getConfig($this->getConfig('cache')) === null) {
73
            $this->setConfig('cache', 'default');
74
        }
75
    }
76
77
    /**
78
     * Verify status of image thumb.
79
     * Return int representing status.
80
     * Possible values:
81
     *
82
     *   NOT_AVAILABLE: something went wrong during api call
83
     *   NOT_READY: thumb is available, but not ready
84
     *   NOT_ACCEPTABLE: image is not acceptable, api won't create thumb
85
     *   NO_URL: url not present in api response
86
     *   OK: thumb available, ready and with a proper url
87
     *
88
     * @param int|string $imageId The image ID
89
     * @param array|null $options The thumbs options
90
     * @param string|null $url The thumb url to populate when static::OK
91
     * @return int|null
92
     */
93
    public function status($imageId, ?array $options = ['preset' => 'default'], &$url = ''): ?int
94
    {
95
        if (empty($imageId) && empty($options['ids'])) {
96
            return static::NOT_ACCEPTABLE;
97
        }
98
        try {
99
            $apiClient = ApiClientProvider::getApiClient();
100
            $response = $apiClient->thumbs($imageId, $options);
101
            if (empty($response['meta']['thumbnails'][0])) {
102
                return static::NOT_AVAILABLE;
103
            }
104
            $thumb = $response['meta']['thumbnails'][0];
105
            // check thumb is ready
106
            if (!$this->isReady($thumb)) {
107
                return static::NOT_READY;
108
            }
109
            // check thumb is acceptable
110
            if (!$this->isAcceptable($thumb)) {
111
                return static::NOT_ACCEPTABLE;
112
            }
113
            // check thumb has url
114
            if (!$this->hasUrl($thumb)) {
115
                return static::NO_URL;
116
            }
117
            $url = $thumb['url'];
118
        } catch (\Exception $e) {
119
            $this->log($e->getMessage(), 'error');
120
121
            return static::NOT_AVAILABLE;
122
        }
123
124
        return static::OK;
125
    }
126
127
    /**
128
     * Obtain thumbnail using API thumbs.
129
     *
130
     * @param int $imageId The image ID.
131
     * @param array|null $options The thumbs options.
132
     * @return string|int The url if available, the status code otherwise (see Thumb constants).
133
     */
134
    public function url($imageId, $options)
135
    {
136
        $url = null;
137
        $status = $this->status($imageId, $options, $url);
138
        if ($status === static::OK) {
139
            return $url;
140
        }
141
142
        return $status;
143
    }
144
145
    /**
146
     * Verify if thumb is acceptable
147
     *
148
     * @param array $thumb The thumbnail data
149
     * @return bool the acceptable flag
150
     */
151
    private function isAcceptable($thumb = []): bool
152
    {
153
        if (isset($thumb['acceptable']) && $thumb['acceptable'] === false) {
154
            return false;
155
        }
156
157
        return true;
158
    }
159
160
    /**
161
     * Verify if thumb is ready
162
     *
163
     * @param array $thumb The thumbnail data
164
     * @return bool the ready flag
165
     */
166
    private function isReady($thumb = []): bool
167
    {
168
        if (!empty($thumb['ready']) && $thumb['ready'] === true) {
169
            return true;
170
        }
171
172
        return false;
173
    }
174
175
    /**
176
     * Verify if thumb has url
177
     *
178
     * @param array $thumb The thumbnail data
179
     * @return bool the url availability
180
     */
181
    private function hasUrl($thumb = []): bool
182
    {
183
        if (!empty($thumb['url'])) {
184
            return true;
185
        }
186
187
        return false;
188
    }
189
190
    /**
191
     * Retrieve thumb URL using cache.
192
     * Silently fail with log if no image 'id' is found in array.
193
     *
194
     * @param  array  $image   Image object array containing at least `id`
195
     * @param  string $options Thumb options
196
     * @return string
197
     */
198
    public function getUrl(array $image, array $options = []): string
199
    {
200
        if (empty($image['id'])) {
201
            $this->log(sprintf('Missing image ID - %s', json_encode($image)), 'warning');
202
203
            return '';
204
        }
205
        $thumbHash = md5((string)Hash::get($image, 'meta.media_url') . json_encode($options));
206
        $key = sprintf('%d_%s', $image['id'], $thumbHash);
207
208
        return (string)Cache::remember(
209
            $key,
210
            function () use ($image, $options) {
211
                return $this->url($image['id'], $options);
212
            },
213
            $this->getConfig('cache')
214
        );
215
    }
216
}
217