Completed
Push — feature-images ( 23dd6d...defc63 )
by Arnaud
11:45 queued 08:49
created

Image::resize()   C

Complexity

Conditions 13
Paths 92

Size

Total Lines 98
Code Lines 48

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 13
eloc 48
c 2
b 0
f 0
nc 92
nop 2
dl 0
loc 98
rs 6.6166

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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 int */
27
    private $size;
28
    /** @var bool */
29
    private $local = true;
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
    /** @var string */
39
    private $cacheDir;
40
41
    const CACHE_IMAGES_DIR = 'images';
42
    const CACHE_IMAGES_THUMBS_DIR = 'thumbs';
43
44
    public function __construct(Builder $builder)
45
    {
46
        $this->config = $builder->getConfig();
47
    }
48
49
    /**
50
     * Resize an image.
51
     *
52
     * @param string $path       Image path (relative from static/ dir or external)
53
     * @param int    $this->size Image new size (width)
54
     *
55
     * @return string Path to image thumbnail
56
     */
57
    public function resize(string $path, int $size): string
58
    {
59
        /**
60
         * path = /images/img-1.jpg
61
         * path = https://example.com/img-2.png.
62
         */
63
        $this->path = $path;
64
        $this->size = $size;
65
66
        // is not a local image?
67
        if (Util::isExternalUrl($this->path)) {
68
            $this->local = false;
69
        }
70
71
        // source file
72
        if ($this->local) {
73
            $this->source = $this->config->getStaticPath().'/'.ltrim($this->path, '/');
74
            if (!Util::getFS()->exists($this->source)) {
75
                throw new Exception(sprintf('Can\'t process "%s": file doesn\'t exists.', $this->source));
76
            }
77
        } else {
78
            $this->source = $this->path;
79
            if (!Util::isUrlFileExists($this->source)) {
80
                throw new Exception(sprintf('Can\'t process "%s": file doesn\'t exists.', $this->source));
81
            }
82
        }
83
84
        // images cache path
85
        $this->cachePath = $this->config->getCachePath().'/'.self::CACHE_IMAGES_DIR;
0 ignored issues
show
Bug Best Practice introduced by
The property cachePath does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
86
87
        // is size is already OK?
88
        list($width, $height) = getimagesize($this->source);
89
        if ($width <= $this->size && $height <= $this->size) {
90
            return $this->path;
91
        }
92
93
        // if GD extension is not installed: can't process
94
        if (!extension_loaded('gd')) {
95
            return $this->path;
96
        }
97
98
        // ie: .cache/images/thumbs/300
99
        $this->thumbsDir = $this->cacheDir.'/'.self::CACHE_IMAGES_THUMBS_DIR.'/'.$this->size;
100
        // ie: .cache/images/thumbs/300/img/logo.png
101
        $this->imageRelPath = $this->thumbsDir.'/'.ltrim($this->path, '/');
102
        // where to write the file
103
        $this->destination = $this->config->getDestinationDir().'/'.$this->imageRelPath;
104
        if ($this->config->isCacheDirIsAbsolute()) {
105
            $this->destination = $this->imageRelPath;
106
        }
107
108
        if (Util::getFS()->exists($this->destination)) {
109
            return $this->path;
110
        }
111
112
        // Image object
113
        try {
114
            $img = ImageManager::make($this->source);
115
116
            // DEBUG
117
            var_dump($img->width());
0 ignored issues
show
Security Debugging Code introduced by
var_dump($img->width()) looks like debug code. Are you sure you do not want to remove it?
Loading history...
118
            var_dump($img->height());
119
120
            $img->resize($this->size, null, function (\Intervention\Image\Constraint $constraint) {
121
                $constraint->aspectRatio();
122
                $constraint->upsize();
123
            });
124
125
            // DEBUG
126
            var_dump($img->width());
127
            var_dump($img->height());
128
            //die();
129
        } catch (NotReadableException $e) {
130
            throw new Exception(sprintf('Cannot get image "%s"', $this->path));
131
        }
132
133
        // return data:image
134
        if (!$this->local) {
135
            return (string) $img->encode('data-url');
136
        }
137
138
        // save/write file
139
        // is a sub dir is necessary?
140
        $imageSubDir = Util::getFS()->makePathRelative(
141
            '/'.dirname($this->imageRelPath),
142
            '/'.$this->thumbsDir.'/'
143
        );
144
        if (!empty($imageSubDir)) {
145
            $destDir = $this->config->getCacheImagesThumbsPath().'/'.$this->size.'/'.$imageSubDir;
146
            Util::getFS()->mkdir($destDir);
147
        }
148
        //$img->save($this->destination);
149
150
        // return relative path
151
        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

151
        return '/'./** @scrutinizer ignore-type */ $this->config->get('cache.images.dir')
Loading history...
152
            .'/'.(string) $this->config->get('cache.images.thumbs.dir')
153
            .'/'.$this->size
154
            .'/'.ltrim($this->path, '/');
155
    }
156
157
    /**
158
     * Resize with Intervention ImageManager.
159
     *
160
     * @return string
161
     */
162
    private function doResize(): string
0 ignored issues
show
Unused Code introduced by
The method doResize() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
163
    {
164
        try {
165
            //
166
        } catch (\Exception $e) {
0 ignored issues
show
Unused Code introduced by
catch (\Exception $e) is not reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
167
            throw new \Exception(sprintf("Error during \"%s\" process.\n%s", get_class($this), $e->getMessage()));
168
        }
169
    }
170
}
171