Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
47 / 47
100.00% covered (success)
100.00%
34 / 34
CRAP
100.00% covered (success)
100.00%
1 / 1
AbstractDocument
100.00% covered (success)
100.00%
47 / 47
100.00% covered (success)
100.00%
34 / 34
39
100.00% covered (success)
100.00%
1 / 1
 setVersion
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 setMetadata
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 setSecurity
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 setOrigin
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 getVersion
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getOrigin
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getMetadata
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getSecurity
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 hasSecurity
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getPages
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getPage
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 hasPages
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getFonts
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getFont
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 hasFonts
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getAvailableFonts
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 isFontAvailable
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 hasFont
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getStyles
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getStyle
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 hasStyles
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getAvailableStyles
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 isStyleAvailable
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 hasStyle
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getCurrentPage
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getNumberOfPages
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getCurrentFont
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getNumberOfFonts
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getForms
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getForm
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
2
 hasForms
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 addForm
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 setCompression
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 isCompressed
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 __construct
n/a
0 / 0
n/a
0 / 0
0
 addPage
n/a
0 / 0
n/a
0 / 0
0
 addPages
n/a
0 / 0
n/a
0 / 0
0
 createPage
n/a
0 / 0
n/a
0 / 0
0
 copyPage
n/a
0 / 0
n/a
0 / 0
0
 orderPages
n/a
0 / 0
n/a
0 / 0
0
 deletePage
n/a
0 / 0
n/a
0 / 0
0
 addFont
n/a
0 / 0
n/a
0 / 0
0
 addFonts
n/a
0 / 0
n/a
0 / 0
0
 embedFont
n/a
0 / 0
n/a
0 / 0
0
 embedFonts
n/a
0 / 0
n/a
0 / 0
0
 createStyle
n/a
0 / 0
n/a
0 / 0
0
 addStyle
n/a
0 / 0
n/a
0 / 0
0
 addStyles
n/a
0 / 0
n/a
0 / 0
0
 setCurrentPage
n/a
0 / 0
n/a
0 / 0
0
 setCurrentFont
n/a
0 / 0
n/a
0 / 0
0
 __toString
n/a
0 / 0
n/a
0 / 0
0
1<?php
2declare(strict_types=1);
3/**
4 * Pop PHP Framework (https://www.popphp.org/)
5 *
6 * @link       https://github.com/popphp/popphp-framework
7 * @author     Nick Sagona, III <nick@popphp.org>
8 * @copyright  Copyright (c) 2009-2026 Nick Sagona, III
9 * @license    https://www.popphp.org/license     New BSD License
10 */
11
12/**
13 * @namespace
14 */
15namespace Pop\Pdf\Document;
16
17/**
18 * Abstract Pdf document class
19 *
20 * @category   Pop
21 * @package    Pop\Pdf
22 * @author     Nick Sagona, III <nick@popphp.org>
23 * @copyright  Copyright (c) 2009-2026 Nick Sagona, III
24 * @license    https://www.popphp.org/license     New BSD License
25 * @version    6.2.0
26 */
27abstract class AbstractDocument implements DocumentInterface
28{
29
30    /**
31     * Document origin constants
32     */
33    const ORIGIN_TOP_LEFT     = 'ORIGIN_TOP_LEFT';
34    const ORIGIN_TOP_RIGHT    = 'ORIGIN_TOP_RIGHT';
35    const ORIGIN_BOTTOM_LEFT  = 'ORIGIN_BOTTOM_LEFT';
36    const ORIGIN_BOTTOM_RIGHT = 'ORIGIN_BOTTOM_RIGHT';
37    const ORIGIN_CENTER       = 'ORIGIN_CENTER';
38
39    /**
40     * PDF version
41     * @var float
42     */
43    protected float $version = 1.7;
44
45    /**
46     * PDF metadata for the info object
47     * @var ?Metadata
48     */
49    protected ?Metadata $metadata = null;
50
51    /**
52     * Security
53     * @var ?Security
54     */
55    protected ?Security $security = null;
56
57    /**
58     * Pages array
59     * @var array
60     */
61    protected array $pages = [];
62
63    /**
64     * Fonts array
65     * @var array
66     */
67    protected array $fonts = [];
68
69    /**
70     * Styles array
71     * @var array
72     */
73    protected array $styles = [];
74
75    /**
76     * Forms array
77     * @var array
78     */
79    protected array $forms = [];
80
81    /**
82     * Current page
83     * @var ?int
84     */
85    protected ?int $currentPage = null;
86
87    /**
88     * Current font
89     * @var ?string
90     */
91    protected ?string $currentFont = null;
92
93    /**
94     * Compression property
95     * @var bool
96     */
97    protected bool$compression = false;
98
99    /**
100     * Document origin
101     * @var string
102     */
103    protected string $origin = 'ORIGIN_BOTTOM_LEFT';
104
105    /**
106     * Set the document version
107     *
108     * @param  float $version
109     * @return AbstractDocument
110     */
111    public function setVersion(float $version): AbstractDocument
112    {
113        $this->version = $version;
114        return $this;
115    }
116
117    /**
118     * Set the document metadata
119     *
120     * @param  Metadata $metadata
121     * @return AbstractDocument
122     */
123    public function setMetadata(Metadata $metadata): AbstractDocument
124    {
125        $this->metadata = $metadata;
126        return $this;
127    }
128
129    /**
130     * Set the document security/encryption configuration
131     *
132     * @param  Security $security
133     * @return AbstractDocument
134     */
135    public function setSecurity(Security $security): AbstractDocument
136    {
137        $this->security = $security;
138        return $this;
139    }
140
141    /**
142     * Set the document origin
143     *
144     * @param  string $origin
145     * @return AbstractDocument
146     */
147    public function setOrigin(string $origin): AbstractDocument
148    {
149        if (defined('Pop\Pdf\Document\AbstractDocument::' . $origin)) {
150            $this->origin = $origin;
151        }
152        return $this;
153    }
154
155    /**
156     * Get the document version
157     *
158     * @return float
159     */
160    public function getVersion(): float
161    {
162        return $this->version;
163    }
164
165    /**
166     * Get the document origin
167     *
168     * @return string
169     */
170    public function getOrigin(): string
171    {
172        return $this->origin;
173    }
174
175    /**
176     * Get the document metadata
177     *
178     * @return ?Metadata
179     */
180    public function getMetadata(): ?Metadata
181    {
182        return $this->metadata;
183    }
184
185    /**
186     * Get the document security/encryption configuration
187     *
188     * @return ?Security
189     */
190    public function getSecurity(): ?Security
191    {
192        return $this->security;
193    }
194
195    /**
196     * Determine whether the document has a security/encryption configuration
197     *
198     * @return bool
199     */
200    public function hasSecurity(): bool
201    {
202        return ($this->security !== null);
203    }
204
205    /**
206     * Get the PDF page objects array
207     *
208     * @return array
209     */
210    public function getPages(): array
211    {
212        return $this->pages;
213    }
214
215    /**
216     * Get a PDF page object
217     *
218     * @param  int $p
219     * @throws \Pop\Pdf\Exception
220     * @return Page
221     */
222    public function getPage(int $p): Page
223    {
224        if (!isset($this->pages[$p - 1])) {
225            throw new \Pop\Pdf\Exception('Error: That page (' . $p . ') does not exist.');
226        }
227        return $this->pages[$p - 1];
228    }
229
230    /**
231     * Determine if the document has page objects
232     *
233     * @return bool
234     */
235    public function hasPages(): bool
236    {
237        return (count($this->pages) > 0);
238    }
239
240    /**
241     * Get the PDF font objects array
242     *
243     * @return array
244     */
245    public function getFonts(): array
246    {
247        return $this->fonts;
248    }
249
250    /**
251     * Get a PDF font object
252     *
253     * @param  string $name
254     * @throws \Pop\Pdf\Exception
255     * @return Font
256     */
257    public function getFont(string $name): Font
258    {
259        if (!isset($this->fonts[$name])) {
260            throw new \Pop\Pdf\Exception("Error: The font '" . $name . "' has not been added to the PDF document.");
261        }
262        return $this->fonts[$name];
263    }
264
265    /**
266     * Determine if the document has font objects
267     *
268     * @return bool
269     */
270    public function hasFonts(): bool
271    {
272        return (count($this->fonts) > 0);
273    }
274
275    /**
276     * Get available fonts that have been added to the PDF document
277     *
278     * @return array
279     */
280    public function getAvailableFonts(): array
281    {
282        return array_keys($this->fonts);
283    }
284
285    /**
286     * Determine if a font has been added to the PDF document
287     *
288     * @param  string $font
289     * @return bool
290     */
291    public function isFontAvailable(string $font): bool
292    {
293        return array_key_exists($font, $this->fonts);
294    }
295
296    /**
297     * Determine if a font has been added to the PDF document (alias)
298     *
299     * @param  string $font
300     * @return bool
301     */
302    public function hasFont(string $font): bool
303    {
304        return array_key_exists($font, $this->fonts);
305    }
306
307    /**
308     * Get the PDF style objects array
309     *
310     * @return array
311     */
312    public function getStyles(): array
313    {
314        return $this->styles;
315    }
316
317    /**
318     * Get a PDF style object
319     *
320     * @param  string $name
321     * @throws \Pop\Pdf\Exception
322     * @return Style
323     */
324    public function getStyle(string $name): Style
325    {
326        if (!isset($this->styles[$name])) {
327            throw new \Pop\Pdf\Exception("Error: The style '" . $name . "' has not been added to the PDF document.");
328        }
329        return $this->styles[$name];
330    }
331
332    /**
333     * Determine if the document has style objects
334     *
335     * @return bool
336     */
337    public function hasStyles(): bool
338    {
339        return (count($this->styles) > 0);
340    }
341
342    /**
343     * Get available styles that have been added to the PDF document
344     *
345     * @return array
346     */
347    public function getAvailableStyles(): array
348    {
349        return array_keys($this->styles);
350    }
351
352    /**
353     * Determine if a style has been added to the PDF document
354     *
355     * @param  string $style
356     * @return bool
357     */
358    public function isStyleAvailable(string $style): bool
359    {
360        return array_key_exists($style, $this->styles);
361    }
362
363    /**
364     * Determine if a style has been added to the PDF document (alias)
365     *
366     * @param  string $style
367     * @return bool
368     */
369    public function hasStyle(string $style): bool
370    {
371        return array_key_exists($style, $this->styles);
372    }
373
374    /**
375     * Get the current page number
376     *
377     * @return ?int
378     */
379    public function getCurrentPage(): ?int
380    {
381        return $this->currentPage;
382    }
383
384    /**
385     * Get the current number of pages
386     *
387     * @return int
388     */
389    public function getNumberOfPages(): int
390    {
391        return count($this->pages);
392    }
393
394    /**
395     * Get the current font
396     *
397     * @return ?string
398     */
399    public function getCurrentFont(): ?string
400    {
401        return $this->currentFont;
402    }
403
404    /**
405     * Get the current number of fonts
406     *
407     * @return int
408     */
409    public function getNumberOfFonts(): int
410    {
411        return count($this->fonts);
412    }
413
414    /**
415     * Get form objects
416     *
417     * @return array
418     */
419    public function getForms(): array
420    {
421        return $this->forms;
422    }
423
424    /**
425     * Get form objects
426     *
427     * @param  string $name
428     * @return ?Form
429     */
430    public function getForm(string $name): ?Form
431    {
432        return (isset($this->forms[$name])) ? $this->forms[$name] : null;
433    }
434
435    /**
436     * Determine if the document has form objects
437     *
438     * @return bool
439     */
440    public function hasForms(): bool
441    {
442        return (count($this->forms) > 0);
443    }
444
445    /**
446     * Add form
447     *
448     * @param  Form $form
449     * @return AbstractDocument
450     */
451    public function addForm(Form $form): AbstractDocument
452    {
453        $this->forms[$form->getName()] = $form;
454        return $this;
455    }
456
457    /**
458     * Set the compression
459     *
460     * @param  bool $compression
461     * @return AbstractDocument
462     */
463    public function setCompression(bool $compression): AbstractDocument
464    {
465        $this->compression = $compression;
466        return $this;
467    }
468
469    /**
470     * Determine whether the PDF is compressed or not
471     *
472     * @return bool
473     */
474    public function isCompressed(): bool
475    {
476        return $this->compression;
477    }
478
479    /**
480     * Constructor
481     *
482     * Instantiate a PDF document
483     *
484     * @param  ?Page     $page
485     * @param  ?Metadata $metadata
486     * @return AbstractDocument
487     */
488    abstract public function __construct(?Page $page = null, ?Metadata $metadata = null);
489
490    /**
491     * Add a page to the PDF document
492     *
493     * @param  Page $page
494     * @return AbstractDocument
495     */
496    abstract public function addPage(Page $page): AbstractDocument;
497
498    /**
499     * Add pages to the PDF document
500     *
501     * @param  array $pages
502     * @return AbstractDocument
503     */
504    abstract public function addPages(array $pages): AbstractDocument;
505
506    /**
507     * Create and return a new page object, adding it to the PDF document
508     *
509     * @param  mixed $size
510     * @param  mixed $height
511     * @return Page
512     */
513    abstract public function createPage(mixed $size, mixed $height = null): Page;
514
515    /**
516     * Copy and return a page of the PDF, adding it to the PDF document
517     *
518     * @param  int $p
519     * @throws Exception
520     * @return Page
521     */
522    abstract public function copyPage(int $p): Page;
523
524    /**
525     * Order the pages
526     *
527     * @param  array $pages
528     * @throws Exception
529     * @return AbstractDocument
530     */
531    abstract public function orderPages(array $pages): AbstractDocument;
532
533    /**
534     * Delete a page from the PDF document
535     *
536     * @param  int $p
537     * @throws Exception
538     * @return AbstractDocument
539     */
540    abstract public function deletePage(int $p): AbstractDocument;
541
542    /**
543     * Add a font
544     *
545     * @param  Font $font
546     * @throws Exception
547     * @return AbstractDocument
548     */
549    abstract public function addFont(Font $font): AbstractDocument;
550
551    /**
552     * Add fonts
553     *
554     * @param  array $fonts
555     * @throws Exception
556     * @return AbstractDocument
557     */
558    abstract public function addFonts(array $fonts): AbstractDocument;
559
560    /**
561     * Embed a font
562     *
563     * @param  Font $font
564     * @param  bool $embedOverride
565     * @throws Exception
566     * @return AbstractDocument
567     */
568    abstract public function embedFont(Font $font, bool $embedOverride = false): AbstractDocument;
569
570    /**
571     * Embed fonts
572     *
573     * @param  array $fonts
574     * @param  bool $embedOverride
575     * @throws Exception
576     * @return AbstractDocument
577     */
578    abstract public function embedFonts(array $fonts, bool $embedOverride = false): AbstractDocument;
579
580    /**
581     * Create style
582     *
583     * @param  Style|string $style
584     * @return AbstractDocument
585     */
586    abstract public function createStyle(Style|string $style, ?string $font = null, int|float|null $size = null): AbstractDocument;
587
588    /**
589     * Add a style
590     *
591     * @param  Style|string $style
592     * @return AbstractDocument
593     */
594    abstract public function addStyle(Style|string $style): AbstractDocument;
595
596    /**
597     * Add styles
598     *
599     * @param  array $styles
600     * @return AbstractDocument
601     */
602    abstract public function addStyles(array $styles): AbstractDocument;
603
604    /**
605     * Set the current page of the PDF document
606     *
607     * @param  int $p
608     * @throws Exception
609     * @return AbstractDocument
610     */
611    abstract public function setCurrentPage(int $p): AbstractDocument;
612
613    /**
614     * Set the current font of the PDF document
615     *
616     * @param  string $name
617     * @throws Exception
618     * @return AbstractDocument
619     */
620    abstract public function setCurrentFont(string $name): AbstractDocument;
621
622    /**
623     * Output the PDF document to string
624     *
625     * @return string
626     */
627    abstract public function __toString(): string;
628
629}