Test Failed
Pull Request — master (#9)
by Laurens
02:12
created

ImageFileUpload::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
c 0
b 0
f 0
rs 9.4285
cc 1
eloc 4
nc 1
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace LauLamanApps\IzettleApi\API\Image;
6
7
use Exception;
8
use LauLamanApps\IzettleApi\API\Image\Exceptions\FileIsNotAnImageException;
9
use LauLamanApps\IzettleApi\API\Image\Exceptions\ImageIsToSmallException;
10
use LauLamanApps\IzettleApi\API\Image\Exceptions\ImageTypeNotAllowedException;
11
use LauLamanApps\IzettleApi\API\Image\Exceptions\MaximumImageFileSizeExcededException;
12
13
interface ImageUploadRequestInterface
14
{
15
    public function getUploadRequest(): array;
16
}
17
18
final class ImageUrlUpload implements ImageUploadRequestInterface
0 ignored issues
show
Coding Style Compatibility introduced by
Each interface must be in a file by itself

Having each class in a dedicated file usually plays nice with PSR autoloaders and is therefore a well established practice. If you use other autoloaders, you might not want to follow this rule.

Loading history...
19
{
20
    /**
21
     * @var
22
     */
23
    private $imageUrl;
24
25
    public function __construct( string $imageUrl)
26
    {
27
        $this->imageUrl = $imageUrl;
28
    }
29
30
    public function getUploadRequest(): array
31
    {
32
        return [
33
            'imageUrl' => $this->imageUrl
34
        ];
35
    }
36
}
37
38
final class ImageFileUpload implements ImageUploadRequestInterface
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class should be in its own file to aid autoloaders.

Having each class in a dedicated file usually plays nice with PSR autoloaders and is therefore a well established practice. If you use other autoloaders, you might not want to follow this rule.

Loading history...
39
{
40
    const ALLOWED_FILE_TYPES = [
41
        IMAGETYPE_GIF => 'GIF',
42
        IMAGETYPE_JPEG => 'JPEG',
43
        IMAGETYPE_PNG => 'PNG',
44
        IMAGETYPE_BMP => 'BMP',
45
        IMAGETYPE_TIFF_II => 'TIFF',
46
        IMAGETYPE_TIFF_MM => 'TIFF'
47
    ];
48
    const MAX_FILE_SIZE_MB = 5;
49
    const MINIMAL_HEIGHT = 50;
50
    const MINIMAL_WIDTH = 50;
51
52
    private $imageFormat;
53
    private $imageData;
54
55
    private function __construct(string $filename)
56
    {
57
        $this->validateFile($filename);
58
        $this->imageFormat = self::ALLOWED_FILE_TYPES[exif_imagetype($filename)];
59
        $this->imageData = file_get_contents($filename);
60
    }
61
62
    public function getUploadRequest(): array
63
    {
64
        return [
65
            'imageFormat' => $this->imageFormat,
66
            'imageData' => $this->imageData,
67
        ];
68
    }
69
70
71
    private function validateFile($file)
72
    {
73
        self::validateFileSize($file);
74
        self::validatedImageType($file);
75
        self::validateImageSize($file);
76
    }
77
78
    private static function validateFileSize($file)
79
    {
80
        $maxFileSizeBytes = (self::MAX_FILE_SIZE_MB * 1024 * 1024);
81
        if (filesize($file) > $maxFileSizeBytes) {
82
            throw new MaximumImageFileSizeExcededException(sprintf('Max file size is \'%d Mb\'', self::MAX_FILE_SIZE_MB));
83
        }
84
    }
85
86
    private static function validatedImageType(string $file)
87
    {
88
        $type = false;
89
90
        try {
91
            $type = exif_imagetype($file);
92
        } catch (Exception $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
93
        }
94
95
        if ($type == false) {
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing $type of type integer to the boolean false. If you are specifically checking for 0, consider using something more explicit like === 0 instead.
Loading history...
96
            throw new FileIsNotAnImageException();
97
        }
98
99
        if (!array_key_exists($type, self::ALLOWED_FILE_TYPES)) {
100
            throw new ImageTypeNotAllowedException(
101
                sprintf('Allowed: %s', implode(', ', self::ALLOWED_FILE_TYPES))
102
            );
103
        }
104
    }
105
106
    private static function validateImageSize($file)
107
    {
108
        list($width, $height) = getimagesize($file);
109
110
        if ($width < self::MINIMAL_WIDTH or $height < self::MINIMAL_HEIGHT) {
111
            throw new ImageIsToSmallException(
112
                sprintf(
113
                    'Minimal image dimensions not met. Required: \'%dx%d\' Provided: \'%dx%d\'',
114
                    self::MINIMAL_HEIGHT,
115
                    self::MINIMAL_WIDTH,
116
                    $height,
117
                    $width
118
                )
119
            );
120
        }
121
    }
122
}
123