Image::upload()   A
last analyzed

Complexity

Conditions 4
Paths 4

Size

Total Lines 19
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 11
c 1
b 0
f 0
nc 4
nop 4
dl 0
loc 19
rs 9.9
1
<?php
2
3
namespace SimpSyst\Uploader;
4
5
/**
6
 * Class SimpSyst Image
7
 *
8
 * @author Diego Matos <https://github.com/diegoamatos>
9
 * @package SimpSyst\Uploader
10
 */
11
class Image extends Uploader
12
{
13
    /**
14
     * Allow jpg, png and gif images, use from check. For new extensions check the imageCrete method
15
     * @var array allowed media types
16
     */
17
    protected static $allowTypes = [
18
        "image/jpeg",
19
        "image/png",
20
        "image/gif",
21
    ];
22
23
    /**
24
     * @param array $image
25
     * @param string $name
26
     * @param int $width
27
     * @param array|null $quality
28
     * @return string
29
     * @throws \Exception
30
     */
31
    public function upload(array $image, string $name, int $width = 2000, ?array $quality = null): string
32
    {
33
        if (empty($image['type'])) {
34
            throw new \Exception("Not a valid data from image");
35
        }
36
37
        if (!$this->imageCreate($image)) {
38
            throw new \Exception("Not a valid image type or extension");
39
        } else {
40
            $this->name($name);
41
        }
42
43
        if ($this->ext == "gif") {
44
            move_uploaded_file("{$image['tmp_name']}", "{$this->path}/{$this->name}");
45
            return "{$this->path}/{$this->name}";
46
        }
47
48
        $this->imageGenerate($width, ($quality ?? ["jpg" => 75, "png" => 5]));
49
        return "{$this->path}/{$this->name}";
50
    }
51
52
    /**
53
     * Image create and valid extension from mime-type
54
     * https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types#Image_types
55
     *
56
     * @param array $image
57
     * @return bool
58
     */
59
    protected function imageCreate(array $image): bool
60
    {
61
        if ($image['type'] == "image/jpeg") {
62
            $this->file = imagecreatefromjpeg($image['tmp_name']);
0 ignored issues
show
Documentation Bug introduced by
It seems like imagecreatefromjpeg($image['tmp_name']) can also be of type GdImage. However, the property $file is declared as type resource. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
63
            $this->ext = "jpg";
64
            $this->checkAngle($image);
65
            return true;
66
        }
67
68
        if ($image['type'] == "image/png") {
69
            $this->file = imagecreatefrompng($image['tmp_name']);
70
            $this->ext = "png";
71
            return true;
72
        }
73
74
        if ($image['type'] == "image/gif") {
75
            $this->ext = "gif";
76
            return true;
77
        }
78
79
        return false;
80
    }
81
82
    /**
83
     * @param int $width
84
     * @param array $quality
85
     */
86
    private function imageGenerate(int $width, array $quality): void
87
    {
88
        $fileX = imagesx($this->file);
89
        $fileY = imagesy($this->file);
90
        $imageW = ($width < $fileX ? $width : $fileX);
91
        $imageH = ($imageW * $fileY) / $fileX;
92
        $imageCreate = imagecreatetruecolor($imageW, $imageH);
93
94
        if ($this->ext == "jpg") {
95
            imagecopyresampled($imageCreate, $this->file, 0, 0, 0, 0, $imageW, $imageH, $fileX, $fileY);
96
            imagejpeg($imageCreate, "{$this->path}/{$this->name}", $quality['jpg']);
97
        }
98
99
        if ($this->ext == "png") {
100
            imagealphablending($imageCreate, false);
101
            imagesavealpha($imageCreate, true);
102
            imagecopyresampled($imageCreate, $this->file, 0, 0, 0, 0, $imageW, $imageH, $fileX, $fileY);
103
            imagepng($imageCreate, "{$this->path}/{$this->name}", $quality['png']);
104
        }
105
106
        imagedestroy($this->file);
107
        imagedestroy($imageCreate);
108
    }
109
110
    /**
111
     * Check image (JPG, PNG) angle and rotate from exif data.
112
     * @param $image
113
     */
114
    private function checkAngle($image): void
115
    {
116
        $exif = @exif_read_data($image["tmp_name"]);
117
        $orientation = (!empty($exif["Orientation"]) ? $exif["Orientation"] : null);
118
119
        switch ($orientation) {
120
            case 8:
121
                $this->file = imagerotate($this->file, 90, 0);
0 ignored issues
show
Documentation Bug introduced by
It seems like imagerotate($this->file, 90, 0) can also be of type GdImage. However, the property $file is declared as type resource. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
122
                break;
123
            case 3:
124
                $this->file = imagerotate($this->file, 180, 0);
125
                break;
126
            case 6:
127
                $this->file = imagerotate($this->file, -90, 0);
128
                break;
129
        }
130
131
        return;
132
    }
133
}
134