Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
97.22% covered (success)
97.22%
70 / 72
88.89% covered (success)
88.89%
16 / 18
CRAP
0.00% covered (danger)
0.00%
0 / 1
Document
97.22% covered (success)
97.22%
70 / 72
88.89% covered (success)
88.89%
16 / 18
39
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
3
 addPage
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 addPages
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 createPage
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 copyPage
85.71% covered (success)
85.71%
6 / 7
0.00% covered (danger)
0.00%
0 / 1
3.03
 orderPages
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
5
 deletePage
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
4
 addFont
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
3
 embedFont
88.89% covered (success)
88.89%
8 / 9
0.00% covered (danger)
0.00%
0 / 1
5.03
 setCurrentPage
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 setCurrentFont
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 importObjects
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 importFonts
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 hasImportedObjects
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 hasImportedFonts
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getImportObjects
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getImportedFonts
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 __toString
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2/**
3 * Pop PHP Framework (http://www.popphp.org/)
4 *
5 * @link       https://github.com/popphp/popphp-framework
6 * @author     Nick Sagona, III <dev@nolainteractive.com>
7 * @copyright  Copyright (c) 2009-2023 NOLA Interactive, LLC. (http://www.nolainteractive.com)
8 * @license    http://www.popphp.org/license     New BSD License
9 */
10
11/**
12 * @namespace
13 */
14namespace Pop\Pdf;
15
16use Pop\Pdf\Document\AbstractDocument;
17use Pop\Pdf\Document\Page;
18use Pop\Pdf\Document\Font;
19use Pop\Pdf\Document\Metadata;
20
21/**
22 * Pdf document class
23 *
24 * @category   Pop
25 * @package    Pop\Pdf
26 * @author     Nick Sagona, III <dev@nolainteractive.com>
27 * @copyright  Copyright (c) 2009-2023 NOLA Interactive, LLC. (http://www.nolainteractive.com)
28 * @license    http://www.popphp.org/license     New BSD License
29 * @version    4.2.0
30 */
31class Document extends AbstractDocument
32{
33
34    /**
35     * Imported objects
36     * @var array
37     */
38    protected $importedObjects = [];
39
40    /**
41     * Imported fonts
42     * @var array
43     */
44    protected $importedFonts = [];
45
46    /**
47     * Constructor
48     *
49     * Instantiate a PDF document
50     *
51     * @param  Page     $page
52     * @param  Metadata $metadata
53     */
54    public function __construct(Page $page = null, Metadata $metadata = null)
55    {
56        if (null !== $page) {
57            $this->addPage($page);
58        }
59        $metadata = (null !== $metadata) ? $metadata : new Metadata();
60        $this->setMetadata($metadata);
61    }
62
63    /**
64     * Add a page to the PDF document
65     *
66     * @param  Page $page
67     * @return Document
68     */
69    public function addPage(Page $page)
70    {
71        $this->pages[]     = $page;
72        $this->currentPage = count($this->pages);
73        return $this;
74    }
75
76    /**
77     * Add pages to the PDF document
78     *
79     * @param  array $pages
80     * @return Document
81     */
82    public function addPages(array $pages)
83    {
84        foreach ($pages as $page) {
85            $this->addPage($page);
86        }
87        return $this;
88    }
89
90    /**
91     * Create and return a new page object, adding it to the PDF document
92     *
93     * @param  mixed $size
94     * @param  int   $height
95     * @return Page
96     */
97    public function createPage($size, $height = null)
98    {
99        $page = new Page($size, $height);
100        $this->addPage($page);
101        return $page;
102    }
103
104    /**
105     * Copy and return a page of the PDF, adding it to the PDF document
106     *
107     * @param  int     $p
108     * @param  boolean $preserveContent
109     * @throws Exception
110     * @return Page
111     */
112    public function copyPage($p, $preserveContent = true)
113    {
114        if (!isset($this->pages[$p - 1])) {
115            throw new Exception("Error: That page (" . $p . ") does not exist.");
116        }
117
118        $page = clone $this->pages[$p - 1];
119
120        if (!$preserveContent) {
121            $page->clearContent();
122        }
123
124        $this->addPage($page);
125        return $page;
126    }
127
128    /**
129     * Order the pages
130     *
131     * @param  array $pages
132     * @throws Exception
133     * @return Document
134     */
135    public function orderPages(array $pages)
136    {
137        $newOrder = [];
138
139        // Check if the numbers of pages passed equals the number of pages in the PDF.
140        if (count($pages) != count($this->pages)) {
141            throw new Exception('Error: The pages array passed does not contain the same number of pages as the PDF.');
142        }
143
144        // Make sure each page passed is within the PDF and not out of range.
145        foreach ($pages as $value) {
146            if (!array_key_exists(($value - 1), $this->pages)) {
147                throw new Exception('Error: The pages array passed contains a page that does not exist.');
148            }
149        }
150
151        // Set the new order of the page objects.
152        foreach ($pages as $value) {
153            $newOrder[] = $this->pages[$value - 1];
154        }
155
156        // Set the pages arrays to the new order.
157        $this->pages = $newOrder;
158        return $this;
159    }
160
161    /**
162     * Delete a page from the PDF document
163     *
164     * @param  int $p
165     * @throws Exception
166     * @return Document
167     */
168    public function deletePage($p)
169    {
170        if (!isset($this->pages[$p - 1])) {
171            throw new Exception("Error: That page (" . $p . ") does not exist.");
172        }
173
174        unset($this->pages[$p - 1]);
175
176        // Reset current page if current page was the one deleted
177        if ($this->currentPage == $p) {
178            $this->currentPage = (count($this->pages) > 0) ? (count($this->pages) - 1) : null;
179        }
180
181        return $this;
182    }
183
184    /**
185     * Add a font
186     *
187     * @param  Font    $font
188     * @param  boolean $embedOverride
189     * @return Document
190     */
191    public function addFont(Font $font, $embedOverride = false)
192    {
193        if (!$font->isStandard()) {
194            $this->embedFont($font, $embedOverride);
195        } else {
196            if (!array_key_exists($font->getName(), $this->fonts)) {
197                $this->fonts[$font->getName()] = $font;
198                $this->currentFont = $font->getName();
199            }
200        }
201
202        return $this;
203    }
204
205    /**
206     * Add a font
207     *
208     * @param  Font    $font
209     * @param  boolean $embedOverride
210     * @return Document
211     */
212    public function embedFont(Font $font, $embedOverride = false)
213    {
214        if (!$font->isEmbedded()) {
215            $this->addFont($font);
216        } else {
217            if (!$font->parser()->isEmbeddable() && !$embedOverride) {
218                throw new Exception('Error: The font license does not allow for it to be embedded.');
219            }
220
221            if (!array_key_exists($font->parser()->getFontName(), $this->fonts)) {
222                $font->parser()->setCompression($this->compression);
223                $this->fonts[$font->parser()->getFontName()] = $font;
224                $this->currentFont = $font->parser()->getFontName();
225            }
226        }
227
228        return $this;
229    }
230
231    /**
232     * Set the current page of the PDF document
233     *
234     * @param  int $p
235     * @throws Exception
236     * @return Document
237     */
238    public function setCurrentPage($p)
239    {
240        // Check if the page exists.
241        if (!isset($this->pages[$p - 1])) {
242            throw new Exception("Error: That page (" . $p . ") does not exist.");
243        }
244        $this->currentPage = $p;
245
246        return $this;
247    }
248
249    /**
250     * Set the current font of the PDF document
251     *
252     * @param  string $name
253     * @throws Exception
254     * @return Document
255     */
256    public function setCurrentFont($name)
257    {
258        // Check if the font exists.
259        if (!isset($this->fonts[$name])) {
260            throw new Exception("Error: The font '" . $name . "' has not been added to the PDF document.");
261        }
262        $this->currentFont = $name;
263
264        return $this;
265    }
266
267    /**
268     * Import objects into document
269     *
270     * @param  array $objects
271     * @return Document
272     */
273    public function importObjects(array $objects)
274    {
275        $this->importedObjects = $objects;
276        return $this;
277    }
278
279    /**
280     * Import fonts into document
281     *
282     * @param  array $fonts
283     * @return Document
284     */
285    public function importFonts(array $fonts)
286    {
287        foreach ($fonts as $font) {
288            $this->fonts[$font['name']] = $font;
289        }
290        $this->importedFonts = $fonts;
291        return $this;
292    }
293
294    /**
295     * Determine if the document has imported objects
296     *
297     * @return boolean
298     */
299    public function hasImportedObjects()
300    {
301        return (count($this->importedObjects) > 0);
302    }
303
304    /**
305     * Determine if the document has imported fonts
306     *
307     * @return boolean
308     */
309    public function hasImportedFonts()
310    {
311        return (count($this->importedFonts) > 0);
312    }
313
314    /**
315     * Get the imported objects
316     *
317     * @return array
318     */
319    public function getImportObjects()
320    {
321        return $this->importedObjects;
322    }
323
324    /**
325     * Get the import fonts
326     *
327     * @return array
328     */
329    public function getImportedFonts()
330    {
331        return $this->importedFonts;
332    }
333
334    /**
335     * Output the PDF document to string
336     *
337     * @return string
338     */
339    public function __toString()
340    {
341        $compiler = new Build\Compiler();
342        $compiler->finalize($this);
343        return $compiler->getOutput();
344    }
345
346}