Skip to content

Commit 4faa250

Browse files
committed
#35706 Remote storage issue #35706
- Created new ImageFactory class that is refactored service class Zend_Pdf_Resource_ImageFactory for using external S3 Storage images in invoice
1 parent bcb0fea commit 4faa250

File tree

3 files changed

+192
-1
lines changed

3 files changed

+192
-1
lines changed

app/code/Magento/Sales/Model/Order/Pdf/AbstractPdf.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
use Magento\Framework\App\Filesystem\DirectoryList;
1010
use Magento\Framework\App\ObjectManager;
11+
use Magento\Framework\File\Pdf\Image;
1112
use Magento\MediaStorage\Helper\File\Storage\Database;
1213
use Magento\Sales\Model\RtlTextHandler;
1314
use Magento\Store\Model\ScopeInterface;
@@ -279,7 +280,7 @@ protected function insertLogo(&$page, $store = null)
279280
$this->fileStorageDatabase->saveFileToFilesystem($imagePath);
280281
}
281282
if ($this->_mediaDirectory->isFile($imagePath)) {
282-
$image = \Zend_Pdf_Image::imageWithPath($this->_mediaDirectory->getAbsolutePath($imagePath));
283+
$image = Image::imageWithPath($this->_mediaDirectory->getAbsolutePath($imagePath));
283284
$top = 830;
284285
//top border of the page
285286
$widthLimit = 270;
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
namespace Magento\Framework\File\Pdf;
4+
5+
use Magento\Framework\File\Pdf\ImageResource\ImageFactory;
6+
use Zend_Pdf_Image;
7+
8+
abstract class Image extends Zend_Pdf_Image
9+
{
10+
/**
11+
* Filepath of image file
12+
*
13+
* @param string $filePath
14+
* @return \Zend_Pdf_Resource_Image|\Zend_Pdf_Resource_Image_Jpeg|\Zend_Pdf_Resource_Image_Png|\Zend_Pdf_Resource_Image_Tiff|object
15+
* @throws \Magento\Framework\Exception\FileSystemException
16+
* @throws \Zend_Pdf_Exception
17+
*/
18+
public static function imageWithPath($filePath)
19+
{
20+
return ImageFactory::factory($filePath);
21+
}
22+
}
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
declare(strict_types=1);
8+
9+
namespace Magento\Framework\File\Pdf\ImageResource;
10+
11+
use Exception;
12+
use finfo;
13+
use Magento\Framework\App\Filesystem\DirectoryList;
14+
use Magento\Framework\App\ObjectManager;
15+
use Magento\Framework\Filesystem;
16+
use Magento\Framework\Filesystem\Directory\ReadInterface;
17+
use Zend_Pdf_Exception;
18+
use Zend_Pdf_Resource_ImageFactory;
19+
20+
class ImageFactory extends Zend_Pdf_Resource_ImageFactory
21+
{
22+
/**
23+
* New zend image factory instance
24+
*
25+
* @param string $filename
26+
* @return \Zend_Pdf_Resource_Image_Jpeg|\Zend_Pdf_Resource_Image_Png|\Zend_Pdf_Resource_Image_Tiff|object
27+
* @throws \Magento\Framework\Exception\FileSystemException
28+
* @throws \Zend_Pdf_Exception
29+
* @SuppressWarnings(PHPMD.LongVariable)
30+
*/
31+
public static function factory($filename)
32+
{
33+
$filesystem = ObjectManager::getInstance()->get(Filesystem::class);
34+
$mediaReader = $filesystem->getDirectoryRead(DirectoryList::MEDIA);
35+
if (!$mediaReader->isFile($filename)) {
36+
#require_once 'Zend/Pdf/Exception.php';
37+
throw new Zend_Pdf_Exception("Cannot create image resource. File not found.");
38+
}
39+
$tempFilenameFromBucketOrDisk = self::createTemporaryFileAndPutContent($mediaReader, $filename);
40+
$tempResourceFilePath = self::getFilePathOfTemporaryFile($tempFilenameFromBucketOrDisk);
41+
$typeOfImage = self::getTypeOfImage($tempResourceFilePath, $filename);
42+
$zendPdfImage = self::getZendPdfImage($typeOfImage, $tempResourceFilePath);
43+
self::removeTemoraryFile($tempFilenameFromBucketOrDisk);
44+
return $zendPdfImage;
45+
}
46+
47+
/**
48+
* Create a temporary file and put content of the original file into it
49+
*
50+
* @param ReadInterface $mediaReader
51+
* @param string $filename
52+
* @return resource
53+
* @throws \Magento\Framework\Exception\FileSystemException
54+
* @throws \Zend_Pdf_Exception
55+
* @SuppressWarnings(PHPMD.LongVariable)
56+
*/
57+
protected static function createTemporaryFileAndPutContent(ReadInterface $mediaReader, string $filename)
58+
{
59+
$tempFilenameFromBucketOrDisk = tmpfile();
60+
if ($tempFilenameFromBucketOrDisk === false) {
61+
#require_once 'Zend/Pdf/Exception.php';
62+
throw new Zend_Pdf_Exception('Cannot create temporary file');
63+
}
64+
fwrite($tempFilenameFromBucketOrDisk, $mediaReader->readFile($filename));
65+
return $tempFilenameFromBucketOrDisk;
66+
}
67+
68+
/**
69+
* Returns the path of the temporary file or nothing
70+
*
71+
* @param resource $tempFilenameFromBucketOrDisk
72+
* @return string
73+
* @SuppressWarnings(PHPMD.LongVariable)
74+
*/
75+
protected static function getFilePathOfTemporaryFile($tempFilenameFromBucketOrDisk): string
76+
{
77+
try {
78+
return stream_get_meta_data($tempFilenameFromBucketOrDisk)['uri'];
79+
} catch (Exception $e) {
80+
return '';
81+
}
82+
}
83+
84+
/**
85+
* Get mime-type in safe way except internal errors
86+
*
87+
* @param string $filepath
88+
* @param string $baseFileName
89+
* @return mixed|string
90+
* @throws \Zend_Pdf_Exception
91+
*/
92+
protected static function getTypeOfImage(string $filepath, string $baseFileName)
93+
{
94+
if (class_exists('finfo', false) && !empty($filepath)) {
95+
$finfo = new finfo(FILEINFO_MIME_TYPE);
96+
$classicMimeType = $finfo->file($filepath);
97+
} elseif (function_exists('mime_content_type') && !empty($filepath)) {
98+
$classicMimeType = mime_content_type($filepath);
99+
} else {
100+
$classicMimeType = self::fetchFallbackMimeType($baseFileName);
101+
}
102+
if (!empty($classicMimeType)) {
103+
return explode("/", $classicMimeType)[1] ?? '';
104+
} else {
105+
return '';
106+
}
107+
}
108+
109+
/**
110+
* Fall back fetching of mimetype by original base file name
111+
*
112+
* @param string $baseFileName
113+
* @return string
114+
* @throws \Zend_Pdf_Exception
115+
*/
116+
protected static function fetchFallbackMimeType(string $baseFileName): string
117+
{
118+
$extension = pathinfo($baseFileName, PATHINFO_EXTENSION);
119+
switch (strtolower($extension)) {
120+
case 'jpg':
121+
//Fall through to next case;
122+
case 'jpe':
123+
//Fall through to next case;
124+
case 'jpeg':
125+
$classicMimeType = 'image/jpeg';
126+
break;
127+
case 'png':
128+
$classicMimeType = 'image/png';
129+
break;
130+
case 'tif':
131+
//Fall through to next case;
132+
case 'tiff':
133+
$classicMimeType = 'image/tiff';
134+
break;
135+
default:
136+
#require_once 'Zend/Pdf/Exception.php';
137+
throw new Zend_Pdf_Exception(
138+
"Cannot create image resource. File extension not known or unsupported type."
139+
);
140+
}
141+
return $classicMimeType;
142+
}
143+
144+
/**
145+
* Creates instance of Zend_Pdf_Resource_Image
146+
*
147+
* @param string $typeOfImage
148+
* @param string $tempResourceFilePath
149+
* @return \Zend_Pdf_Resource_Image_Jpeg|\Zend_Pdf_Resource_Image_Png|\Zend_Pdf_Resource_Image_Tiff|object
150+
*/
151+
protected static function getZendPdfImage($typeOfImage, $tempResourceFilePath)
152+
{
153+
$classToUseAsPdfImage = sprintf('Zend_Pdf_Resource_Image_%s', ucfirst($typeOfImage));
154+
return new $classToUseAsPdfImage($tempResourceFilePath);
155+
}
156+
157+
/**
158+
* Removes the temporary file from disk
159+
*
160+
* @param resource $tempFilenameFromBucketOrDisk
161+
* @return void
162+
* @SuppressWarnings(PHPMD.LongVariable)
163+
*/
164+
protected static function removeTemoraryFile($tempFilenameFromBucketOrDisk): void
165+
{
166+
fclose($tempFilenameFromBucketOrDisk);
167+
}
168+
}

0 commit comments

Comments
 (0)