Completed
Push — master ( f426cf...89f4ba )
by Dan Michael O.
03:59 queued 01:41
created

CachedImage   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 126
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 19
c 1
b 0
f 0
lcom 1
cbo 3
dl 0
loc 126
rs 10

10 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 11 3
A getMetadata() 0 11 2
A setMetadata() 0 9 1
A width() 0 4 1
A height() 0 4 1
A mime() 0 4 1
A size() 0 4 1
A download() 0 6 1
C store() 0 31 7
A thumb() 0 4 1
1
<?php
2
3
namespace Colligator;
4
5
use Intervention\Image\Image;
6
use Intervention\Image\ImageManager;
7
use League\Flysystem\AdapterInterface;
8
use League\Flysystem\Config as FlysystemConfig;
9
10
class CachedImage
11
{
12
    public $sourceUrl;
13
    public $maxHeight;
14
    public $cacheKey;
15
    protected $_metadata;
16
17
    public function __construct($url, $maxHeight = 0, AdapterInterface $filesystem = null, ImageManager $imageManager = null)
18
    {
19
        $this->sourceUrl = $url;
20
        $this->maxHeight = intval($maxHeight);
21
        $this->filesystem = $filesystem ?: \Storage::disk('s3')->getAdapter();
22
        $this->imageManager = $imageManager ?: app('Intervention\Image\ImageManager');
23
        $maxAge = 3153600; // 30 days
24
        $this->fsConfig = new FlysystemConfig([
25
            'CacheControl' => 'max-age=' . $maxAge . ', public',
26
        ]);
27
    }
28
29
    public function getMetadata()
30
    {
31
        if (is_null($this->_metadata)) {
32
            $data = $this->filesystem->read($this->cacheKey);
33
            $contents = strval($data['contents']);
34
            $img = $this->imageManager->make($contents);
35
            $this->setMetadata($contents, $img);
36
        }
37
38
        return $this->_metadata;
39
    }
40
41
    protected function setMetadata($file, Image $img)
42
    {
43
        $this->_metadata = [
44
            'size'   => strlen($file),
45
            'width'  => $img->width(),
46
            'height' => $img->height(),
47
            'mime'   => $img->mime(),
48
        ];
49
    }
50
51
    public function width()
52
    {
53
        return $this->getMetadata()['width'];
54
    }
55
56
    public function height()
57
    {
58
        return $this->getMetadata()['height'];
59
    }
60
61
    public function mime()
62
    {
63
        return $this->getMetadata()['mime'];
64
    }
65
66
    public function size()
67
    {
68
        return $this->getMetadata()['size'];
69
    }
70
71
    /**
72
     * Retrieves the content of an URL.
73
     *
74
     * @return string
75
     */
76
    public function download()
77
    {
78
        // TODO: Use flysystem-http-downloader instead, but needs update
79
        // https://github.com/indigophp/flysystem-http-downloader/pull/2
80
        return file_get_contents($this->sourceUrl);
81
    }
82
83
    /**
84
     * Store a file in cache.
85
     *
86
     * @throws \ErrorException
87
     *
88
     * @return CachedImage
89
     */
90
    public function store($data = null)
91
    {
92
        if (is_null($data)) {
93
            $data = $this->download();
94
            if (!$data) {
95
                throw new \ErrorException('[CoverCache] Failed to download ' . $this->sourceUrl);
96
            }
97
        }
98
99
        $img = $this->imageManager->make($data);
100
        if ($this->maxHeight && $img->height() > $this->maxHeight) {
101
            \Log::debug('[CachedImage] Resizing from ' . $img->height() . ' to ' . $this->maxHeight);
102
            $img->heighten($this->maxHeight);
103
            $data = strval($img->encode('jpg'));
104
        }
105
106
        if ($img->width() / $img->height() > 1.4) {
107
            throw new \ErrorException('[CoverCache] Not accepting images with w/h ratio > 1.4');
108
        }
109
110
        $this->setMetadata($data, $img);
111
112
        \Log::debug('[CachedImage] Storing image as ' . $img->width() . ' x ' . $img->height() . ', ' . strlen($data) . ' bytes');
113
        if (!$this->filesystem->write($this->cacheKey, $data, $this->fsConfig)) {
114
            throw new \ErrorException('[CoverCache] Failed to upload thumb to S3');
115
        }
116
117
        \Log::debug('[CachedImage] Wrote cached version as ' . $this->cacheKey);
118
119
        return $this;
120
    }
121
122
    /**
123
     * Return a representation with height no more than $maxHeight.
124
     *
125
     * @param string $maxHeight
126
     *
127
     * @throws \ErrorException
128
     *
129
     * @return CachedImage
130
     */
131
    public function thumb($maxHeight)
132
    {
133
        return \CoverCache::putBlob(file_get_contents($this->cacheKey), $maxHeight);
134
    }
135
}
136