Passed
Push — assets ( 3e13ea...57a633 )
by Arnaud
13:03 queued 10:25
created

Image::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 3
rs 10
1
<?php
2
/**
3
 * This file is part of the Cecil/Cecil package.
4
 *
5
 * Copyright (c) Arnaud Ligny <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace Cecil\Assets;
12
13
use Cecil\Exception\Exception;
14
use Cecil\Util;
15
use Intervention\Image\Exception\NotReadableException;
16
use Intervention\Image\ImageManagerStatic as ImageManager;
17
18
class Image extends AbstractAsset
19
{
20
    /** @var string */
21
    private $path;
22
    /** @var int */
23
    private $size;
24
    /** @var bool */
25
    private $local = true;
26
    /** @var string */
27
    private $source;
28
    /** @var string */
29
    private $cachePath;
30
    /** @var string */
31
    private $destination = null;
32
33
    const CACHE_THUMBS_PATH = 'images/thumbs';
34
35
    /**
36
     * Resizes an image.
37
     *
38
     * @param string $path Image path (relative from static/ dir or external).
39
     * @param int    $size Image new size (width).
40
     *
41
     * @return string Path to the image thumbnail
42
     */
43
    public function resize(string $path, int $size): string
44
    {
45
        // is not a local image?
46
        if (Util::isExternalUrl($path)) {
47
            $this->local = false;
48
        }
49
50
        $this->path = '/'.ltrim($path, '/');
51
        if (!$this->local) {
52
            $this->path = $path;
53
        }
54
        $this->size = $size;
55
        $returnPath = '/'.Util::joinPath(self::CACHE_THUMBS_PATH, $this->size.$this->path);
56
57
        // source file
58
        $this->setSource();
59
60
        // images cache path
61
        $this->cachePath = Util::joinFile(
62
            $this->config->getCachePath(),
63
            self::CACHE_ASSETS_DIR,
64
            self::CACHE_THUMBS_PATH
65
        );
66
67
        // is size is already OK?
68
        list($width, $height) = getimagesize($this->source);
69
        if ($width <= $this->size && $height <= $this->size) {
70
            return $this->path;
71
        }
72
73
        // if GD extension is not installed: can't process
74
        if (!extension_loaded('gd')) {
75
            throw new Exception('GD extension is required to use images resize.');
76
        }
77
78
        $this->destination = Util::joinFile($this->cachePath, $this->size.$this->path);
79
80
        if (Util::getFS()->exists($this->destination)) {
81
            return $returnPath;
82
        }
83
84
        // image object
85
        try {
86
            $img = ImageManager::make($this->source);
87
            $img->resize($this->size, null, function (\Intervention\Image\Constraint $constraint) {
88
                $constraint->aspectRatio();
89
                $constraint->upsize();
90
            });
91
        } catch (NotReadableException $e) {
92
            throw new Exception(sprintf('Cannot get image "%s"', $this->path));
93
        }
94
95
        // return data:image for external image
96
        if (!$this->local) {
97
            return (string) $img->encode('data-url');
98
        }
99
100
        // save file
101
        Util::getFS()->mkdir(dirname($this->destination));
102
        $img->save($this->destination);
103
104
        // return new path
105
        return $returnPath;
106
    }
107
108
    /**
109
     * Set the source file path.
110
     *
111
     * @return void
112
     */
113
    private function setSource(): void
114
    {
115
        if ($this->local) {
116
            $this->source = $this->config->getStaticPath().$this->path;
117
            if (!Util::getFS()->exists($this->source)) {
118
                throw new Exception(sprintf('Can\'t process "%s": file doesn\'t exists.', $this->source));
119
            }
120
121
            return;
122
        }
123
124
        $this->source = $this->path;
125
        if (!Util::isUrlFileExists($this->source)) {
126
            throw new Exception(sprintf('Can\'t process "%s": remonte file doesn\'t exists.', $this->source));
127
        }
128
    }
129
}
130