Completed
Push — master ( 079ab0...b45199 )
by David
01:21
created

Cacher::getCachedImagePathName()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 3
1
<?php
2
3
namespace GNAHotelSolutions\ImageCacher;
4
5
class Cacher
6
{
7
    /** @var string  */
8
    protected $cachePath;
9
    
10
    /** @var string  */
11
    protected $cacheRootPath;
12
13
    /** @var string */
14
    protected $imagesRootPath;
15
16
    public function __construct(string $cachePath = 'cache/images', string $cacheRootPath = '', string $imagesRootPath = '')
17
    {
18
        $this->cachePath = $cachePath;
19
        $this->cacheRootPath = rtrim($cacheRootPath, '/');
20
        $this->imagesRootPath = rtrim($imagesRootPath, '/');
21
    }
22
23
    public function resize($image, $width = null, $height = null): Image
24
    {
25
        return $this->manipulate($image, $width, $height, false);
26
    }
27
28
    public function crop($image, $width = null, $height = null): Image
29
    {
30
        return $this->manipulate($image, $width, $height, true);
31
    }
32
33
    protected function manipulate($image, $width = null, $height = null, bool $cropImage = false): Image
34
    {
35
        if (is_string($image)) {
36
            $image = new Image($image, $this->imagesRootPath);
37
        }
38
39
        if ($this->isSmallerThanRequested($image, $width, $height)) {
40
            return $image;
41
        }
42
43
        $resizedWidth = $width ?? round($height * $image->getAspectRatio());
44
        $resizedHeight = $height ?? round($width / $image->getAspectRatio());
45
46
        if ($this->isAlreadyCached($image, $resizedWidth, $resizedHeight)) {
47
            return new Image($this->getCachedImagePathName($image, $resizedWidth, $resizedHeight), $this->cacheRootPath);
48
        }
49
50
        $layout = imagecreatetruecolor($resizedWidth, $resizedHeight);
51
52
        if ($this->isAlpha($image)) {
53
            imagealphablending($layout, false);
54
            imagesavealpha($layout, true);
55
        }
56
57
        if ($cropImage) {
58
            [$cutWidth, $cutHeight] = $this->getCutEdges($image, $resizedWidth, $resizedHeight);
0 ignored issues
show
Bug introduced by
The variable $cutWidth seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?

This error can happen if you refactor code and forget to move the variable initialization.

Let’s take a look at a simple example:

function someFunction() {
    $x = 5;
    echo $x;
}

The above code is perfectly fine. Now imagine that we re-order the statements:

function someFunction() {
    echo $x;
    $x = 5;
}

In that case, $x would be read before it is initialized. This was a very basic example, however the principle is the same for the found issue.

Loading history...
Bug introduced by
The variable $cutHeight seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?

This error can happen if you refactor code and forget to move the variable initialization.

Let’s take a look at a simple example:

function someFunction() {
    $x = 5;
    echo $x;
}

The above code is perfectly fine. Now imagine that we re-order the statements:

function someFunction() {
    echo $x;
    $x = 5;
}

In that case, $x would be read before it is initialized. This was a very basic example, however the principle is the same for the found issue.

Loading history...
59
            $cutX = ($image->getWidth() - $cutWidth) / 2;
0 ignored issues
show
Bug introduced by
The variable $cutWidth seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?

This error can happen if you refactor code and forget to move the variable initialization.

Let’s take a look at a simple example:

function someFunction() {
    $x = 5;
    echo $x;
}

The above code is perfectly fine. Now imagine that we re-order the statements:

function someFunction() {
    echo $x;
    $x = 5;
}

In that case, $x would be read before it is initialized. This was a very basic example, however the principle is the same for the found issue.

Loading history...
60
            $cutY = ($image->getHeight() - $cutHeight) / 2;
0 ignored issues
show
Bug introduced by
The variable $cutHeight seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?

This error can happen if you refactor code and forget to move the variable initialization.

Let’s take a look at a simple example:

function someFunction() {
    $x = 5;
    echo $x;
}

The above code is perfectly fine. Now imagine that we re-order the statements:

function someFunction() {
    echo $x;
    $x = 5;
}

In that case, $x would be read before it is initialized. This was a very basic example, however the principle is the same for the found issue.

Loading history...
61
        } else {
62
            $cutWidth = $image->getWidth();
63
            $cutHeight = $image->getHeight();
64
            $cutX = 0;
65
            $cutY = 0;
66
        }
67
68
        imagecopyresampled($layout, $this->getImageResource($image), 0, 0, $cutX, $cutY, $resizedWidth, $resizedHeight, $cutWidth, $cutHeight);
0 ignored issues
show
Bug introduced by
The variable $cutWidth does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
Bug introduced by
The variable $cutHeight does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
69
70
        $this->saveImage($image, $layout, $resizedWidth, $resizedHeight);
71
72
        return new Image($this->getCachedImagePathName($image, $resizedWidth, $resizedHeight), $this->cacheRootPath);
73
    }
74
75
    protected function isSmallerThanRequested(Image $image, $width, $height): bool
76
    {
77
        return (! $width && ! $height) || $image->isSmallerThan($width, $height);
78
    }
79
80
    protected function isAlreadyCached(Image $image, $width, $height): bool
81
    {
82
        return file_exists($this->getCachedImageFullName($image, $width, $height));
83
    }
84
85
    protected function getCachedImageFullName(Image $image, $width, $height): string
86
    {
87
        if ($this->cacheRootPath === '') {
88
            return $this->getCachedImagePathName($image, $width, $height);
89
        }
90
91
        return "{$this->cacheRootPath}/{$this->getCachedImagePathName($image, $width, $height)}";
92
    }
93
94
    protected function getCachedImagePathName(Image $image, $width, $height): string
95
    {
96
        return "{$this->cachePath}/{$this->getCachedImageName($image, $width, $height)}";
97
    }
98
99
    protected function getCachedImageName(Image $image, $width, $height): string
100
    {
101
        return "{$this->getCacheImagePath($image->getPath(), $width, $height)}/{$image->getName()}";
102
    }
103
104
    protected function getCacheImagePath(string $path, $width, $height): string
105
    {
106
        return "{$path}/{$width}x{$height}";
107
    }
108
109
    protected function isAlpha(Image $image): bool
110
    {
111
        return in_array($image->getType(), ['gif', 'png']);
112
    }
113
114
    protected function getImageResource(Image $image)
115
    {
116
        if ($image->getType() === 'jpeg') {
117
            return imagecreatefromjpeg($image->getOriginalFullPath());
118
        }
119
120
        if ($image->getType() === 'png') {
121
            return imagecreatefrompng($image->getOriginalFullPath());
122
        }
123
124
        if ($image->getType() === 'gif') {
125
            return imagecreatefromgif($image->getOriginalFullPath());
126
        }
127
128
        throw new \Exception("Image type [{$image->getType()}] not supported.");
129
    }
130
131
    protected function getCutEdges(Image $image, int $width, int $height): array
132
    {
133
        $aspectRatio = $width / $height;
134
135
        $cutEdgeWidth = round($image->getHeight() * $aspectRatio);
136
137
        if ($cutEdgeWidth > $image->getWidth()) {
138
            $cutEdgeWidth = $image->getWidth();
139
        }
140
141
        $cutEdgeHeight = round($cutEdgeWidth / $aspectRatio);
142
143
        return [$cutEdgeWidth, $cutEdgeHeight];
144
    }
145
146
    protected function saveImage(Image $image, $layout, $width, $height): string
147
    {
148
        $this->createCacheDirectoryIfNotExists($image, $width, $height);
149
150
        if ($image->getType() === 'jpeg') {
151
            return imagejpeg($layout, $this->getCachedImageFullName($image, $width, $height));
152
        }
153
154
        if ($image->getType() === 'png') {
155
            return imagepng($layout, $this->getCachedImageFullName($image, $width, $height));
156
        }
157
158
        if ($image->getType() === 'gif') {
159
            return imagegif($layout, $this->getCachedImageFullName($image, $width, $height));
160
        }
161
162
        throw new \Exception("Image type [{$image->getType()}] not supported.");
163
    }
164
165
    protected function createCacheDirectoryIfNotExists(Image $image, $width, $height): void
166
    {
167
        $cachePath = ltrim("{$this->cacheRootPath}/{$this->cachePath}/{$this->getCacheImagePath($image->getPath(), $width, $height)}", '/');
168
169
        if (! file_exists($cachePath)) {
170
            mkdir($cachePath, 0777, true);
171
        }
172
    }
173
}
174