PluginProbe
TablePress – Tables in WordPress made easy / 3.4
TablePress – Tables in WordPress made easy v3.4
3.4 3.3.4 3.3.3 3.3.2 3.3.1 trunk 1.12 1.14 1.9.2 2.0.4 2.1.7 2.1.8 2.2 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.3 2.3.1 2.3.2 2.4 2.4.1 2.4.2 2.4.3 All 45 releases
tablepress / libraries / vendor / PhpSpreadsheet / Worksheet / MemoryDrawing.php

MemoryDrawing.php in TablePress – Tables in WordPress made easy 3.4, at libraries/vendor/PhpSpreadsheet/Worksheet/MemoryDrawing.php

327 lines 6.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace TablePress\PhpOffice\PhpSpreadsheet\Worksheet;
4
5 use GdImage;
6 use TablePress\PhpOffice\PhpSpreadsheet\Exception;
7 use TablePress\PhpOffice\PhpSpreadsheet\Shared\File;
8
9 class MemoryDrawing extends BaseDrawing
10 {
11 // Rendering functions
12 const RENDERING_DEFAULT = 'imagepng';
13 const RENDERING_PNG = 'imagepng';
14 const RENDERING_GIF = 'imagegif';
15 const RENDERING_JPEG = 'imagejpeg';
16
17 // MIME types
18 const MIMETYPE_DEFAULT = 'image/png';
19 const MIMETYPE_PNG = 'image/png';
20 const MIMETYPE_GIF = 'image/gif';
21 const MIMETYPE_JPEG = 'image/jpeg';
22
23 const SUPPORTED_MIME_TYPES = [
24 self::MIMETYPE_GIF,
25 self::MIMETYPE_JPEG,
26 self::MIMETYPE_PNG,
27 ];
28
29 /**
30 * Image resource.
31 * @var null|\GdImage
32 */
33 private $imageResource = null;
34
35 /**
36 * Rendering function.
37 *
38 * @var callable-string
39 */
40 private string $renderingFunction;
41
42 /**
43 * Mime type.
44 */
45 private string $mimeType;
46
47 /**
48 * Unique name.
49 */
50 private string $uniqueName;
51
52 /**
53 * Create a new MemoryDrawing.
54 */
55 public function __construct()
56 {
57 // Initialise values
58 $this->renderingFunction = self::RENDERING_DEFAULT;
59 $this->mimeType = self::MIMETYPE_DEFAULT;
60 $this->uniqueName = md5(mt_rand(0, 9999) . time() . mt_rand(0, 9999));
61
62 // Initialize parent
63 parent::__construct();
64 }
65
66 public function __destruct()
67 {
68 if ($this->imageResource) {
69 if (\PHP_VERSION_ID < 80000) {
70 @imagedestroy($this->imageResource);
71 }
72 $this->imageResource = null;
73 }
74 $this->worksheet = null;
75 }
76
77 public function __clone()
78 {
79 parent::__clone();
80 $this->cloneResource();
81 }
82
83 private function cloneResource(): void
84 {
85 if (!$this->imageResource) {
86 return;
87 }
88
89 $width = (int) imagesx($this->imageResource);
90 $height = (int) imagesy($this->imageResource);
91
92 if (imageistruecolor($this->imageResource)) {
93 $clone = imagecreatetruecolor($width, $height);
94 if (!$clone) {
95 throw new Exception('Could not clone image resource');
96 }
97
98 imagealphablending($clone, false);
99 imagesavealpha($clone, true);
100 } else {
101 $clone = imagecreate($width, $height);
102 if (!$clone) {
103 throw new Exception('Could not clone image resource');
104 }
105
106 // If the image has transparency...
107 $transparent = imagecolortransparent($this->imageResource);
108 if ($transparent >= 0) {
109 // Starting with Php8.0, next function throws rather than return false
110 $rgb = imagecolorsforindex($this->imageResource, $transparent);
111
112 imagesavealpha($clone, true);
113 $color = imagecolorallocatealpha($clone, $rgb['red'], $rgb['green'], $rgb['blue'], $rgb['alpha']);
114 if ($color === false) {
115 throw new Exception('Could not get image alpha color');
116 }
117
118 imagefill($clone, 0, 0, $color);
119 }
120 }
121
122 //Create the Clone!!
123 imagecopy($clone, $this->imageResource, 0, 0, 0, 0, $width, $height);
124
125 $this->imageResource = $clone;
126 }
127
128 /**
129 * @param resource $imageStream Stream data to be converted to a Memory Drawing
130 *
131 * @throws Exception
132 */
133 public static function fromStream($imageStream): self
134 {
135 $streamValue = stream_get_contents($imageStream);
136
137 return self::fromString($streamValue);
138 }
139
140 /**
141 * @param string $imageString String data to be converted to a Memory Drawing
142 *
143 * @throws Exception
144 */
145 public static function fromString(string $imageString): self
146 {
147 $gdImage = @imagecreatefromstring($imageString);
148 if ($gdImage === false) {
149 throw new Exception('Value cannot be converted to an image');
150 }
151
152 $mimeType = self::identifyMimeType($imageString);
153 if (imageistruecolor($gdImage) || imagecolortransparent($gdImage) >= 0) {
154 imagesavealpha($gdImage, true);
155 }
156 $renderingFunction = self::identifyRenderingFunction($mimeType);
157
158 $drawing = new self();
159 $drawing->setImageResource($gdImage);
160 $drawing->setRenderingFunction($renderingFunction);
161 $drawing->setMimeType($mimeType);
162
163 return $drawing;
164 }
165
166 /** @return callable-string */
167 private static function identifyRenderingFunction(string $mimeType): string
168 {
169 switch ($mimeType) {
170 case self::MIMETYPE_PNG:
171 return self::RENDERING_PNG;
172 case self::MIMETYPE_JPEG:
173 return self::RENDERING_JPEG;
174 case self::MIMETYPE_GIF:
175 return self::RENDERING_GIF;
176 default:
177 return self::RENDERING_DEFAULT;
178 }
179 }
180
181 /**
182 * @throws Exception
183 */
184 private static function identifyMimeType(string $imageString): string
185 {
186 $temporaryFileName = File::temporaryFilename();
187 file_put_contents($temporaryFileName, $imageString);
188
189 $mimeType = self::identifyMimeTypeUsingGd($temporaryFileName);
190 if ($mimeType !== null) {
191 unlink($temporaryFileName);
192
193 return $mimeType;
194 }
195
196 unlink($temporaryFileName);
197
198 return self::MIMETYPE_DEFAULT;
199 }
200
201 /** @internal */
202 protected static string $getImageSize = 'getImageSize';
203
204 private static function identifyMimeTypeUsingGd(string $temporaryFileName): ?string
205 {
206 if (function_exists(static::$getImageSize)) {
207 $imageSize = @getimagesize($temporaryFileName);
208 if (is_array($imageSize)) {
209 $mimeType = $imageSize['mime'];
210
211 return self::supportedMimeTypes($mimeType);
212 }
213 }
214
215 return null;
216 }
217
218 private static function supportedMimeTypes(?string $mimeType = null): ?string
219 {
220 if (in_array($mimeType, self::SUPPORTED_MIME_TYPES, true)) {
221 return $mimeType;
222 }
223
224 return null;
225 }
226
227 /**
228 * Get image resource.
229 */
230 public function getImageResource(): ?GdImage
231 {
232 return $this->imageResource;
233 }
234
235 /**
236 * Set image resource.
237 *
238 * @return $this
239 */
240 public function setImageResource(?GdImage $value)
241 {
242 $this->imageResource = $value;
243
244 if ($this->imageResource !== null) {
245 // Get width/height
246 $this->width = (int) imagesx($this->imageResource);
247 $this->height = (int) imagesy($this->imageResource);
248 }
249
250 return $this;
251 }
252
253 /**
254 * Get rendering function.
255 *
256 * @return callable-string
257 */
258 public function getRenderingFunction(): string
259 {
260 return $this->renderingFunction;
261 }
262
263 /**
264 * Set rendering function.
265 *
266 * @param callable-string $value see self::RENDERING_*
267 *
268 * @return $this
269 */
270 public function setRenderingFunction(string $value)
271 {
272 $this->renderingFunction = $value;
273
274 return $this;
275 }
276
277 /**
278 * Get mime type.
279 */
280 public function getMimeType(): string
281 {
282 return $this->mimeType;
283 }
284
285 /**
286 * Set mime type.
287 *
288 * @param string $value see self::MIMETYPE_*
289 *
290 * @return $this
291 */
292 public function setMimeType(string $value)
293 {
294 $this->mimeType = $value;
295
296 return $this;
297 }
298
299 /**
300 * Get indexed filename (using image index).
301 */
302 public function getIndexedFilename(): string
303 {
304 $extension = strtolower($this->getMimeType());
305 $extension = explode('/', $extension);
306 $extension = $extension[1];
307
308 return $this->uniqueName . $this->getImageIndex() . '.' . $extension;
309 }
310
311 /**
312 * Get hash code.
313 *
314 * @return string Hash code
315 */
316 public function getHashCode(): string
317 {
318 return md5(
319 $this->renderingFunction
320 . $this->mimeType
321 . $this->uniqueName
322 . parent::getHashCode()
323 . __CLASS__
324 );
325 }
326 }
327