Passed
Pull Request — master (#4142)
by Owen
13:37
created

Drawing::setIsURL()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 2
dl 0
loc 5
rs 10
c 0
b 0
f 0
ccs 1
cts 1
cp 1
cc 1
nc 1
nop 1
crap 1
1
<?php
2
3
namespace PhpOffice\PhpSpreadsheet\Worksheet;
4
5
use PhpOffice\PhpSpreadsheet\Exception as PhpSpreadsheetException;
6
use ZipArchive;
7
8
class Drawing extends BaseDrawing
9
{
10
    const IMAGE_TYPES_CONVERTION_MAP = [
11
        IMAGETYPE_GIF => IMAGETYPE_PNG,
12
        IMAGETYPE_JPEG => IMAGETYPE_JPEG,
13
        IMAGETYPE_PNG => IMAGETYPE_PNG,
14
        IMAGETYPE_BMP => IMAGETYPE_PNG,
15
    ];
16
17
    /**
18
     * Path.
19
     */
20
    private string $path;
21
22
    /**
23
     * Whether or not we are dealing with a URL.
24
     */
25
    private bool $isUrl;
26
27
    /**
28
     * Create a new Drawing.
29
     */
30 178
    public function __construct()
31
    {
32
        // Initialise values
33 178
        $this->path = '';
34 178
        $this->isUrl = false;
35
36
        // Initialize parent
37 178
        parent::__construct();
38
    }
39
40
    /**
41
     * Get Filename.
42
     */
43 1
    public function getFilename(): string
44
    {
45 1
        return basename($this->path);
46
    }
47
48
    /**
49
     * Get indexed filename (using image index).
50
     */
51 39
    public function getIndexedFilename(): string
52
    {
53 39
        return md5($this->path) . '.' . $this->getExtension();
54
    }
55
56
    /**
57
     * Get Extension.
58
     */
59 39
    public function getExtension(): string
60
    {
61 39
        $exploded = explode('.', basename($this->path));
62
63 39
        return $exploded[count($exploded) - 1];
64
    }
65
66
    /**
67
     * Get full filepath to store drawing in zip archive.
68
     */
69 3
    public function getMediaFilename(): string
70
    {
71 3
        if (!array_key_exists($this->type, self::IMAGE_TYPES_CONVERTION_MAP)) {
72 1
            throw new PhpSpreadsheetException('Unsupported image type in comment background. Supported types: PNG, JPEG, BMP, GIF.');
73
        }
74
75 3
        return sprintf('image%d%s', $this->getImageIndex(), $this->getImageFileExtensionForSave());
76
    }
77
78
    /**
79
     * Get Path.
80
     */
81 83
    public function getPath(): string
82
    {
83 83
        return $this->path;
84
    }
85
86
    /**
87
     * Set Path.
88
     *
89
     * @param string $path File path
90
     * @param bool $verifyFile Verify file
91
     * @param ?ZipArchive $zip Zip archive instance
92
     *
93
     * @return $this
94
     */
95 90
    public function setPath(string $path, bool $verifyFile = true, ?ZipArchive $zip = null): static
96
    {
97 90
        if (preg_match('~^data:image/[a-z]+;base64,~', $path) === 1) {
98
            $this->path = $path;
99 43
100 1
            return $this;
101
        }
102 1
103 1
        if ($verifyFile === false && !str_starts_with($path, 'zip:')) {
104 1
            throw new PhpSpreadsheetException('Only zip files can set verifyFile to false');
105 1
        }
106 1
107 1
        $this->path = '';
108 1
        // Check if a URL has been passed. https://stackoverflow.com/a/2058596/1252979
109 1
        if (filter_var($path, FILTER_VALIDATE_URL)) {
110
            if (!preg_match('/^(http|https|file|ftp|s3):/', $path)) {
111
                throw new PhpSpreadsheetException('Invalid protocol for linked drawing');
112 42
            }
113 39
            // Implicit that it is a URL, rather store info than running check above on value in other places.
114 39
            $this->isUrl = true;
115 5
            $imageContents = @file_get_contents($path);
116 5
            if ($imageContents !== false) {
117 5
                $filePath = tempnam(sys_get_temp_dir(), 'Drawing');
118 5
                if ($filePath) {
119 5
                    file_put_contents($filePath, $imageContents);
120
                    if (file_exists($filePath)) {
121
                        if ($this->isImage($filePath)) {
122
                            $this->path = $path;
123
                            $this->setSizesAndType($filePath);
124
                        }
125 57
                        unlink($filePath);
126
                    }
127
                }
128 90
            }
129
        } elseif ($zip instanceof ZipArchive) {
130
            $zipPath = explode('#', $path)[1];
131
            if ($zip->locateName($zipPath) !== false) {
132
                if ($this->isImage($path)) {
133
                    $this->path = $path;
134 2
                    $this->setSizesAndType($path);
135
                }
136 2
            }
137
        } elseif (file_exists($path)) {
138
            if ($this->isImage($path)) {
139
                $this->path = $path;
140
                $this->setSizesAndType($path);
141
            }
142
        }
143
144
        return $this;
145
    }
146
147
    private function isImage(string $path): bool
148
    {
149
        return str_starts_with((string) mime_content_type($path), 'image/');
150
    }
151
152
    /**
153
     * Get isURL.
154
     */
155
    public function getIsURL(): bool
156 37
    {
157
        return $this->isUrl;
158 37
    }
159 37
160 37
    /**
161 37
     * Set isURL.
162 37
     *
163
     * @return $this
164
     */
165
    public function setIsURL(bool $isUrl): self
166
    {
167
        $this->isUrl = $isUrl;
168 1
169
        return $this;
170 1
    }
171 1
172
    /**
173
     * Get hash code.
174 1
     *
175
     * @return string Hash code
176
     */
177
    public function getHashCode(): string
178
    {
179
        return md5(
180 3
            $this->path
181
            . parent::getHashCode()
182 3
            . __CLASS__
183 1
        );
184
    }
185
186 3
    /**
187
     * Get Image Type for Save.
188 3
     */
189
    public function getImageTypeForSave(): int
190
    {
191
        if (!array_key_exists($this->type, self::IMAGE_TYPES_CONVERTION_MAP)) {
192
            throw new PhpSpreadsheetException('Unsupported image type in comment background. Supported types: PNG, JPEG, BMP, GIF.');
193
        }
194 3
195
        return self::IMAGE_TYPES_CONVERTION_MAP[$this->type];
196 3
    }
197 1
198
    /**
199
     * Get Image file extention for Save.
200 3
     */
201
    public function getImageFileExtensionForSave(bool $includeDot = true): string
202
    {
203
        if (!array_key_exists($this->type, self::IMAGE_TYPES_CONVERTION_MAP)) {
204
            throw new PhpSpreadsheetException('Unsupported image type in comment background. Supported types: PNG, JPEG, BMP, GIF.');
205
        }
206
207
        $result = image_type_to_extension(self::IMAGE_TYPES_CONVERTION_MAP[$this->type], $includeDot);
208
209
        return "$result";
210
    }
211
212
    /**
213
     * Get Image mime type.
214
     */
215
    public function getImageMimeType(): string
216
    {
217
        if (!array_key_exists($this->type, self::IMAGE_TYPES_CONVERTION_MAP)) {
218
            throw new PhpSpreadsheetException('Unsupported image type in comment background. Supported types: PNG, JPEG, BMP, GIF.');
219
        }
220
221
        return image_type_to_mime_type(self::IMAGE_TYPES_CONVERTION_MAP[$this->type]);
222
    }
223
}
224