88namespace PhpMyAdmin \Gis ;
99
1010use PhpMyAdmin \Config ;
11- use PhpMyAdmin \Core ;
1211use PhpMyAdmin \Dbal \DatabaseInterface ;
1312use PhpMyAdmin \Gis \Ds \Extent ;
13+ use PhpMyAdmin \Gis \Ds \FileDownload ;
1414use PhpMyAdmin \Gis \Ds \ScaleData ;
1515use PhpMyAdmin \Image \ImageWrapper ;
16- use PhpMyAdmin \Sanitize ;
1716use PhpMyAdmin \Util ;
1817use TCPDF ;
1918
2221use function htmlspecialchars ;
2322use function is_string ;
2423use function max ;
25- use function mb_strlen ;
26- use function mb_strtolower ;
27- use function mb_substr ;
24+ use function ob_get_clean ;
25+ use function ob_start ;
2826use function rtrim ;
2927use function trim ;
3028
@@ -246,43 +244,6 @@ private function fetchRawData(string $modifiedSql): array
246244 return $ modifiedResult ->fetchAllAssoc ();
247245 }
248246
249- /**
250- * Sanitizes the file name.
251- *
252- * @param string $fileName file name
253- * @param string $ext extension of the file
254- *
255- * @return string the sanitized file name
256- */
257- private function sanitizeName (string $ fileName , string $ ext ): string
258- {
259- $ fileName = Sanitize::sanitizeFilename ($ fileName );
260-
261- // Check if the user already added extension;
262- // get the substring where the extension would be if it was included
263- $ requiredExtension = '. ' . $ ext ;
264- $ extensionLength = mb_strlen ($ requiredExtension );
265- $ userExtension = mb_substr ($ fileName , -$ extensionLength );
266- if (mb_strtolower ($ userExtension ) !== $ requiredExtension ) {
267- $ fileName .= $ requiredExtension ;
268- }
269-
270- return $ fileName ;
271- }
272-
273- /**
274- * Handles common tasks of writing the visualization to file for various formats.
275- *
276- * @param string $fileName file name
277- * @param string $type mime type
278- * @param string $ext extension of the file
279- */
280- private function writeToFile (string $ fileName , string $ type , string $ ext ): void
281- {
282- $ fileName = $ this ->sanitizeName ($ fileName , $ ext );
283- Core::downloadHeader ($ fileName , $ type );
284- }
285-
286247 /**
287248 * Generate the visualization in SVG format.
288249 *
@@ -312,16 +273,10 @@ public function asSVG(): string
312273 return $ this ->svg ();
313274 }
314275
315- /**
316- * Saves as a SVG image to a file.
317- *
318- * @param string $fileName File name
319- */
320- public function toFileAsSvg (string $ fileName ): void
276+ /** Get SVG image as string + type infos. */
277+ private function asSvgFile (): FileDownload
321278 {
322- $ img = $ this ->svg ();
323- $ this ->writeToFile ($ fileName , 'image/svg+xml ' , 'svg ' );
324- echo $ img ;
279+ return new FileDownload (mime: 'image/svg+xml ' , extension: 'svg ' , blob: $ this ->svg ());
325280 }
326281
327282 /**
@@ -345,20 +300,22 @@ private function png(): ImageWrapper|null
345300 return $ image ;
346301 }
347302
348- /**
349- * Saves as a PNG image to a file.
350- *
351- * @param string $fileName File name
352- */
353- public function toFileAsPng (string $ fileName ): void
303+ /** Get PNG image as string (blob) + type infos. */
304+ private function asPngFile (): FileDownload |null
354305 {
355306 $ image = $ this ->png ();
356307 if ($ image === null ) {
357- return ;
308+ return null ;
358309 }
359310
360- $ this ->writeToFile ($ fileName , 'image/png ' , 'png ' );
361- $ image ->png (null , 9 , PNG_ALL_FILTERS );
311+ ob_start ();
312+ $ ok = $ image ->png (null , 9 , PNG_ALL_FILTERS );
313+ $ output = ob_get_clean ();
314+ if (! $ ok || $ output === false ) {
315+ return null ;
316+ }
317+
318+ return new FileDownload (mime: 'image/png ' , extension: 'png ' , blob: $ output );
362319 }
363320
364321 /**
@@ -371,18 +328,15 @@ public function asOl(): array
371328 return $ this ->prepareDataSet ($ this ->data , 'ol ' );
372329 }
373330
374- /**
375- * Saves as a PDF to a file.
376- *
377- * @param string $fileName File name
378- */
379- public function toFileAsPdf (string $ fileName ): void
331+ /** Get image PDF as string (blob) + type infos. */
332+ private function asPdfFile (): FileDownload
380333 {
381- $ fileName = $ this ->sanitizeName ($ fileName , 'pdf ' );
382334 $ pdf = $ this ->createEmptyPdf (Config::getInstance ()->config ->PDFDefaultPageSize ?? 'A4 ' );
383335 $ this ->prepareDataSet ($ this ->data , 'pdf ' , $ pdf );
384336
385- $ pdf ->Output ($ fileName , 'D ' );
337+ $ blob = $ pdf ->Output ('' , 'S ' );
338+
339+ return new FileDownload (mime: 'application/pdf ' , extension: 'pdf ' , blob: $ blob );
386340 }
387341
388342 private function createEmptyPdf (string $ format ): TCPDF
@@ -406,18 +360,15 @@ private function createEmptyPdf(string $format): TCPDF
406360 /**
407361 * Convert file to given format
408362 *
409- * @param string $filename Filename
410- * @param string $format Output format
363+ * @param 'svg'|'png'|'pdf' $format Output format
411364 */
412- public function toFile (string $ filename , string $ format ): void
365+ public function toFile (string $ format ): FileDownload | null
413366 {
414- if ($ format === 'svg ' ) {
415- $ this ->toFileAsSvg ($ filename );
416- } elseif ($ format === 'png ' ) {
417- $ this ->toFileAsPng ($ filename );
418- } elseif ($ format === 'pdf ' ) {
419- $ this ->toFileAsPdf ($ filename );
420- }
367+ return match ($ format ) {
368+ 'svg ' => $ this ->asSvgFile (),
369+ 'png ' => $ this ->asPngFile (),
370+ 'pdf ' => $ this ->asPdfFile (),
371+ };
421372 }
422373
423374 /**
0 commit comments