Skip to content

Commit 79fada6

Browse files
author
Phil Wilkinson
committed
Added support for loading images/resources to disk instead of holding them in memory
1 parent a1a18cf commit 79fada6

File tree

4 files changed

+199
-4
lines changed

4 files changed

+199
-4
lines changed

src/PhpPresentation/Shape/Drawing/AbstractDrawingAdapter.php

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,41 @@ abstract public function getMimeType(): string;
3535
abstract public function getPath(): string;
3636

3737
/**
38+
* @param string $path File path
3839
* @return self
3940
*/
4041
abstract public function setPath(string $path);
42+
43+
/**
44+
* Set whether this is a temporary file that should be cleaned up
45+
*
46+
* @param bool $isTemporary
47+
* @return self
48+
*/
49+
abstract public function setIsTemporaryFile(bool $isTemporary);
50+
51+
/**
52+
* Load content into this object using a temporary file
53+
*
54+
* @param string $content Binary content
55+
* @param string $fileName Optional fileName for reference
56+
* @param string $prefix Prefix for the temporary file
57+
* @return self
58+
*/
59+
public function loadFromContent(string $content, string $fileName = '', string $prefix = 'PhpPresentation'): self
60+
{
61+
$tmpFile = tempnam(sys_get_temp_dir(), $prefix);
62+
file_put_contents($tmpFile, $content);
63+
64+
// Set path and mark as temporary for automatic cleanup
65+
$this->setPath($tmpFile);
66+
$this->setIsTemporaryFile(true);
67+
68+
// Set filename if provided
69+
if (!empty($fileName)) {
70+
$this->setName($fileName);
71+
}
72+
73+
return $this;
74+
}
4175
}

src/PhpPresentation/Shape/Drawing/File.php

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@ class File extends AbstractDrawingAdapter
3535
*/
3636
protected $fileName = '';
3737

38+
/**
39+
* @var bool Flag indicating if this is a temporary file that should be cleaned up
40+
*/
41+
protected $isTemporaryFile = false;
42+
3843
/**
3944
* Get Path.
4045
*/
@@ -67,6 +72,28 @@ public function setPath(string $pValue = '', bool $pVerifyFile = true): self
6772
return $this;
6873
}
6974

75+
/**
76+
* Set whether this is a temporary file that should be cleaned up
77+
*
78+
* @param bool $isTemporary
79+
* @return self
80+
*/
81+
public function setIsTemporaryFile(bool $isTemporary): self
82+
{
83+
$this->isTemporaryFile = $isTemporary;
84+
return $this;
85+
}
86+
87+
/**
88+
* Check if this is a temporary file that should be cleaned up
89+
*
90+
* @return bool
91+
*/
92+
public function isTemporaryFile(): bool
93+
{
94+
return $this->isTemporaryFile;
95+
}
96+
7097
public function getFileName(): string
7198
{
7299
return $this->fileName;
@@ -112,4 +139,36 @@ public function getIndexedFilename(): string
112139

113140
return $output;
114141
}
142+
143+
/**
144+
* {@inheritDoc}
145+
*/
146+
public function loadFromContent(string $content, string $fileName = '', string $prefix = 'PhpPresentation'): AbstractDrawingAdapter
147+
{
148+
// Create temporary file
149+
$tmpFile = tempnam(sys_get_temp_dir(), $prefix);
150+
file_put_contents($tmpFile, $content);
151+
152+
// Set path and mark as temporary
153+
$this->setPath($tmpFile);
154+
$this->setIsTemporaryFile(true);
155+
156+
// Set filename if provided
157+
if (!empty($fileName)) {
158+
$this->setFileName($fileName);
159+
}
160+
161+
return $this;
162+
}
163+
164+
/**
165+
* Clean up resources when object is destroyed
166+
*/
167+
public function __destruct()
168+
{
169+
// Remove temporary file if needed
170+
if ($this->isTemporaryFile() && $this->path && file_exists($this->path)) {
171+
@unlink($this->path);
172+
}
173+
}
115174
}

src/PhpPresentation/Shape/Drawing/Gd.php

Lines changed: 84 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ class Gd extends AbstractDrawingAdapter
3939
/**
4040
* Image resource.
4141
*
42-
* @var resource
42+
* @var GdImage|resource|null
4343
*/
4444
protected $imageResource;
4545

@@ -64,6 +64,11 @@ class Gd extends AbstractDrawingAdapter
6464
*/
6565
protected $uniqueName;
6666

67+
/**
68+
* @var bool Flag indicating if this is a temporary file that should be cleaned up
69+
*/
70+
protected $isTemporaryFile = false;
71+
6772
/**
6873
* Gd constructor.
6974
*/
@@ -77,7 +82,7 @@ public function __construct()
7782
* Get image resource.
7883
*
7984
* @param bool $isTransient Avoid the image resource being stored in memory to avoid OOM
80-
* @return ?resource
85+
* @return ?GdImage|?resource
8186
*/
8287
public function getImageResource(bool $isTransient = false)
8388
{
@@ -240,9 +245,86 @@ public function getPath(): string
240245
return $this->path;
241246
}
242247

248+
/**
249+
* Set Path.
250+
*
251+
* @param string $path File path
252+
* @return self
253+
*/
243254
public function setPath(string $path): self
244255
{
245256
$this->path = $path;
257+
return $this;
258+
}
259+
260+
/**
261+
* Set whether this is a temporary file that should be cleaned up
262+
*
263+
* @param bool $isTemporary
264+
* @return self
265+
*/
266+
public function setIsTemporaryFile(bool $isTemporary): self
267+
{
268+
$this->isTemporaryFile = $isTemporary;
269+
return $this;
270+
}
271+
272+
/**
273+
* Check if this is a temporary file that should be cleaned up
274+
*
275+
* @return bool
276+
*/
277+
public function isTemporaryFile(): bool
278+
{
279+
return $this->isTemporaryFile;
280+
}
281+
282+
/**
283+
* Clean up resources when object is destroyed
284+
*/
285+
public function __destruct()
286+
{
287+
// Free GD image resource if it exists
288+
if ($this->imageResource) {
289+
imagedestroy($this->imageResource);
290+
$this->imageResource = null;
291+
}
292+
293+
// Remove temporary file if needed
294+
if ($this->isTemporaryFile && !empty($this->path) && file_exists($this->path)) {
295+
@unlink($this->path);
296+
}
297+
}
298+
299+
/**
300+
* {@inheritDoc}
301+
*/
302+
public function loadFromContent(string $content, string $fileName = '', string $prefix = 'PhpPresentationGd'): AbstractDrawingAdapter
303+
{
304+
$image = @imagecreatefromstring($content);
305+
if ($image === false) {
306+
return $this;
307+
}
308+
309+
$tmpFile = tempnam(sys_get_temp_dir(), $prefix);
310+
file_put_contents($tmpFile, $content);
311+
312+
// Set image resource
313+
$this->setImageResource($image);
314+
315+
// Set path and mark as temporary for automatic cleanup
316+
$this->setPath($tmpFile);
317+
$this->setIsTemporaryFile(true);
318+
319+
if (!empty($fileName)) {
320+
$this->setName($fileName);
321+
}
322+
323+
$info = getimagesizefromstring($content);
324+
if (isset($info['mime'])) {
325+
$this->setMimeType($info['mime']);
326+
$this->setRenderingFunction(str_replace('/', '', $info['mime']));
327+
}
246328

247329
return $this;
248330
}

src/PhpPresentation/Slide/Background/Image.php

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
namespace PhpOffice\PhpPresentation\Slide\Background;
2222

2323
use PhpOffice\PhpPresentation\Exception\FileNotFoundException;
24+
use PhpOffice\PhpPresentation\Shape\Drawing\AbstractDrawingAdapter;
2425
use PhpOffice\PhpPresentation\Slide\AbstractBackground;
2526

2627
class Image extends AbstractBackground
@@ -47,6 +48,11 @@ class Image extends AbstractBackground
4748
*/
4849
protected $width;
4950

51+
/**
52+
* @var AbstractDrawingAdapter|null
53+
*/
54+
protected $image;
55+
5056
/**
5157
* Get Path.
5258
*/
@@ -63,7 +69,7 @@ public function getPath(): ?string
6369
*
6470
* @return self
6571
*/
66-
public function setPath(string $pValue = '', bool $pVerifyFile = true)
72+
public function setPath(string $pValue = '', bool $pVerifyFile = true): Image
6773
{
6874
if ($pVerifyFile) {
6975
if (!file_exists($pValue)) {
@@ -80,6 +86,20 @@ public function setPath(string $pValue = '', bool $pVerifyFile = true)
8086
return $this;
8187
}
8288

89+
/**
90+
* Set the image using a drawing adapter (keeps a reference to the object to manage file lifecycle)
91+
*
92+
* @param AbstractDrawingAdapter $image Drawing adapter containing image data
93+
* @return self
94+
* @throws FileNotFoundException
95+
*/
96+
public function setImage(AbstractDrawingAdapter $image): self
97+
{
98+
$this->image = $image;
99+
$this->setPath($image->getPath());
100+
return $this;
101+
}
102+
83103
/**
84104
* Get Filename.
85105
*/
@@ -105,7 +125,7 @@ public function getExtension(): string
105125
*
106126
* @return string
107127
*/
108-
public function getIndexedFilename($numSlide)
128+
public function getIndexedFilename($numSlide): string
109129
{
110130
return 'background_' . $numSlide . '.' . $this->getExtension();
111131
}

0 commit comments

Comments
 (0)