Passed
Push — fix-assets-images-managment ( a7deda...445b39 )
by Arnaud
06:17 queued 39s
created

Image   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 125
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 61
c 2
b 0
f 0
dl 0
loc 125
rs 10
wmc 16

3 Methods

Rating   Name   Duplication   Size   Complexity  
B resize() 0 42 9
A __construct() 0 3 1
B doResize() 0 44 6
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\Config;
15
use Cecil\Exception\Exception;
16
use Cecil\Util;
17
use Intervention\Image\Exception\NotReadableException;
18
use Intervention\Image\ImageManagerStatic as ImageManager;
19
20
class Image
21
{
22
    /** @var Config */
23
    private $config;
24
    /** @var string */
25
    private $path;
26
    /** @var string */
27
    private $size;
28
    /** @var bool */
29
    private $external;
30
    /** @var string */
31
    private $source;
32
    /** @var string */
33
    private $destination = null;
34
    /** @var string */
35
    private $imageRelPath = null;
36
    /** @var string */
37
    private $thumbsDir = null;
38
39
    public function __construct(Builder $builder)
40
    {
41
        $this->config = $builder->getConfig();
42
    }
43
44
    /**
45
     * Resize an image.
46
     *
47
     * @param string $path       Image path (relative from static/ dir or external)
48
     * @param int    $this->size Image new size (width)
49
     *
50
     * @return string Path to image thumbnail
51
     */
52
    public function resize(string $path, int $size): string
53
    {
54
        $this->path = $path;
55
        $this->size = $size;
56
        $this->source = $path;
57
58
        // is external image?
59
        if (Util::isExternalUrl($this->path)) {
60
            $this->external = true;
61
        }
62
63
        if (!$this->external) {
64
            $this->source = $this->config->getStaticPath().'/'.ltrim($this->path, '/');
65
            if (!Util::getFS()->exists($this->source)) {
66
                throw new Exception(sprintf('Can\'t resize "%s": file doesn\'t exists.', $this->path));
67
            }
68
            // ie: .cache/images/thumbs/300
69
            $this->thumbsDir = (string) $this->config->get('cache.dir')
70
                .'/'.(string) $this->config->get('cache.images.dir')
71
                .'/'.(string) $this->config->get('cache.images.thumbs.dir')
72
                .'/'.$this->size;
73
            // ie: .cache/images/thumbs/300/img/logo.png
74
            $this->imageRelPath = $this->thumbsDir.'/'.ltrim($this->path, '/');
75
            // where to write file
76
            $this->destination = $this->config->getDestinationDir().'/'.$this->imageRelPath;
77
            if ($this->config->isCacheDirIsAbsolute()) {
78
                $this->destination = $this->imageRelPath;
79
            }
80
        }
81
82
        // is size is already OK?
83
        list($width, $height) = getimagesize($this->external ? $this->path : $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
            return $this->path;
91
        }
92
93
        return $this->doResize();
94
    }
95
96
    /**
97
     * Resize with Intervention ImageManager.
98
     *
99
     * @return string
100
     */
101
    private function doResize(): string
102
    {
103
        try {
104
            // external image
105
            if ($this->external) {
106
                try {
107
                    $img = ImageManager::make($this->path);
108
                    $img->resize($this->size, null, function (\Intervention\Image\Constraint $constraint) {
0 ignored issues
show
Bug introduced by
$this->size of type string is incompatible with the type integer expected by parameter $width of Intervention\Image\Image::resize(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

108
                    $img->resize(/** @scrutinizer ignore-type */ $this->size, null, function (\Intervention\Image\Constraint $constraint) {
Loading history...
109
                        $constraint->aspectRatio();
110
                        $constraint->upsize();
111
                    });
112
                } catch (NotReadableException $e) {
113
                    throw new Exception(sprintf('Cannot get image "%s"', $this->path));
114
                }
115
116
                // return data:image
117
                return (string) $img->encode('data-url');
118
            }
119
            // local image
120
            if (!Util::getFS()->exists($this->destination)) {
121
                $img = ImageManager::make($this->source);
122
                $img->resize($this->size, null, function (\Intervention\Image\Constraint $constraint) {
123
                    $constraint->aspectRatio();
124
                    $constraint->upsize();
125
                });
126
                // is a sub dir is necessary?
127
                $imageSubDir = Util::getFS()->makePathRelative(
128
                    '/'.dirname($this->imageRelPath),
129
                    '/'.$this->thumbsDir.'/'
130
                );
131
                if (!empty($imageSubDir)) {
132
                    $destDir = $this->config->getCacheImagesThumbsPath().'/'.$this->size.'/'.$imageSubDir;
133
                    Util::getFS()->mkdir($destDir);
134
                }
135
                $img->save($this->destination);
136
            }
137
138
            // return relative path
139
            return '/'.$this->config->get('cache.images.dir')
0 ignored issues
show
Bug introduced by
Are you sure $this->config->get('cache.images.dir') of type array|mixed|null can be used in concatenation? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

139
            return '/'./** @scrutinizer ignore-type */ $this->config->get('cache.images.dir')
Loading history...
140
                .'/'.(string) $this->config->get('cache.images.thumbs.dir')
141
                .'/'.$this->size
142
                .'/'.ltrim($this->path, '/');
143
        } catch (\Exception $e) {
144
            throw new \Exception(sprintf("Error during \"%s\" process.\n%s", get_class($this), $e->getMessage()));
145
        }
146
    }
147
}
148