Skip to content

Commit e0e33df

Browse files
Merge remote-tracking branch '36039/fix-for-issue-#35706' into comm_voted_v3
2 parents b864fd3 + 607af55 commit e0e33df

File tree

4 files changed

+378
-3
lines changed

4 files changed

+378
-3
lines changed

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

Lines changed: 12 additions & 3 deletions
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;
@@ -61,6 +62,11 @@ abstract class AbstractPdf extends \Magento\Framework\DataObject
6162
*/
6263
private $rtlTextHandler;
6364

65+
/**
66+
* @var \Magento\Framework\File\Pdf\Image
67+
*/
68+
private $image;
69+
6470
/**
6571
* Retrieve PDF
6672
*
@@ -149,6 +155,7 @@ abstract public function getPdf();
149155
* @param array $data
150156
* @param Database $fileStorageDatabase
151157
* @param RtlTextHandler|null $rtlTextHandler
158+
* @param Image $image
152159
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
153160
*/
154161
public function __construct(
@@ -164,7 +171,8 @@ public function __construct(
164171
\Magento\Sales\Model\Order\Address\Renderer $addressRenderer,
165172
array $data = [],
166173
Database $fileStorageDatabase = null,
167-
?RtlTextHandler $rtlTextHandler = null
174+
?RtlTextHandler $rtlTextHandler = null,
175+
?Image $image = null
168176
) {
169177
$this->addressRenderer = $addressRenderer;
170178
$this->_paymentData = $paymentData;
@@ -179,6 +187,7 @@ public function __construct(
179187
$this->inlineTranslation = $inlineTranslation;
180188
$this->fileStorageDatabase = $fileStorageDatabase ?: ObjectManager::getInstance()->get(Database::class);
181189
$this->rtlTextHandler = $rtlTextHandler ?: ObjectManager::getInstance()->get(RtlTextHandler::class);
190+
$this->image = $image ?: ObjectManager::getInstance()->get(Image::class);
182191
parent::__construct($data);
183192
}
184193

@@ -279,7 +288,7 @@ protected function insertLogo(&$page, $store = null)
279288
$this->fileStorageDatabase->saveFileToFilesystem($imagePath);
280289
}
281290
if ($this->_mediaDirectory->isFile($imagePath)) {
282-
$image = \Zend_Pdf_Image::imageWithPath($this->_mediaDirectory->getAbsolutePath($imagePath));
291+
$image = $this->image->imageWithPathAdvanced($this->_mediaDirectory->getAbsolutePath($imagePath));
283292
$top = 830;
284293
//top border of the page
285294
$widthLimit = 270;
@@ -522,7 +531,7 @@ protected function insertOrder(&$page, $obj, $putOrderId = true)
522531

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

0 commit comments

Comments
 (0)