Passed
Push — assets ( cbf9d3...044e3f )
by Arnaud
08:02 queued 05:11
created

Image::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 4
rs 10
c 2
b 0
f 0
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\Builder;
14
use Cecil\Exception\Exception;
15
use Cecil\Util;
16
use Intervention\Image\Exception\NotReadableException;
17
use Intervention\Image\ImageManagerStatic as ImageManager;
18
19
class Image
20
{
21
    /** @var Builder */
22
    protected $builder;
23
    /** @var Config */
0 ignored issues
show
Bug introduced by
The type Cecil\Assets\Config was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
24
    protected $config;
25
    /** @var string */
26
    private $path;
27
    /** @var int */
28
    private $size;
29
    /** @var bool */
30
    private $local = true;
31
    /** @var string */
32
    private $source;
33
    /** @var string */
34
    private $cachePath;
35
    /** @var string */
36
    private $destination = null;
37
38
    const CACHE_ASSETS_DIR = 'assets';
39
    const CACHE_THUMBS_PATH = 'images/thumbs';
40
41
    /**
42
     * @param Builder
43
     */
44
    public function __construct(Builder $builder)
45
    {
46
        $this->builder = $builder;
47
        $this->config = $builder->getConfig();
0 ignored issues
show
Documentation Bug introduced by
It seems like $builder->getConfig() of type Cecil\Config is incompatible with the declared type Cecil\Assets\Config of property $config.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
48
    }
49
50
    /**
51
     * Resizes an image.
52
     *
53
     * @param string $path Image path (relative from static/ dir or external).
54
     * @param int    $size Image new size (width).
55
     *
56
     * @return string Path to the image thumbnail
57
     */
58
    public function resize(string $path, int $size): string
59
    {
60
        // is not a local image?
61
        if (Util::isExternalUrl($path)) {
62
            $this->local = false;
63
        }
64
65
        $this->path = '/'.ltrim($path, '/');
66
        if (!$this->local) {
67
            $this->path = $path;
68
        }
69
        $this->size = $size;
70
        $returnPath = '/'.Util::joinPath(self::CACHE_THUMBS_PATH, $this->size.$this->path);
71
72
        // source file
73
        $this->setSource();
74
75
        // images cache path
76
        $this->cachePath = Util::joinFile(
77
            $this->config->getCachePath(),
78
            self::CACHE_ASSETS_DIR,
79
            self::CACHE_THUMBS_PATH
80
        );
81
82
        // is size is already OK?
83
        list($width, $height) = getimagesize($this->source);
84
        if ($width <= $this->size && $height <= $this->size) {
85
            return $this->path;
86
        }
87
88
        // if GD extension is not installed: can't process
89
        if (!extension_loaded('gd')) {
90
            throw new Exception('GD extension is required to use images resize.');
91
        }
92
93
        $this->destination = Util::joinFile($this->cachePath, $this->size.$this->path);
94
95
        if (Util::getFS()->exists($this->destination)) {
96
            return $returnPath;
97
        }
98
99
        // image object
100
        try {
101
            $img = ImageManager::make($this->source);
102
            $img->resize($this->size, null, function (\Intervention\Image\Constraint $constraint) {
103
                $constraint->aspectRatio();
104
                $constraint->upsize();
105
            });
106
        } catch (NotReadableException $e) {
107
            throw new Exception(sprintf('Cannot get image "%s"', $this->path));
108
        }
109
110
        // return data:image for external image
111
        if (!$this->local) {
112
            return (string) $img->encode('data-url');
113
        }
114
115
        // save file
116
        Util::getFS()->mkdir(dirname($this->destination));
117
        $img->save($this->destination);
118
119
        // return new path
120
        return $returnPath;
121
    }
122
123
    /**
124
     * Set the source file path.
125
     *
126
     * @return void
127
     */
128
    private function setSource(): void
129
    {
130
        if ($this->local) {
131
            $this->source = $this->config->getStaticPath().$this->path;
132
            if (!Util::getFS()->exists($this->source)) {
133
                throw new Exception(sprintf('Can\'t process "%s": file doesn\'t exists.', $this->source));
134
            }
135
136
            return;
137
        }
138
139
        $this->source = $this->path;
140
        if (!Util::isUrlFileExists($this->source)) {
141
            throw new Exception(sprintf('Can\'t process "%s": remonte file doesn\'t exists.', $this->source));
142
        }
143
    }
144
}
145