Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
82.76% covered (success)
82.76%
24 / 29
66.67% covered (warning)
66.67%
6 / 9
CRAP
0.00% covered (danger)
0.00%
0 / 1
ParentObject
82.76% covered (success)
82.76%
24 / 29
66.67% covered (warning)
66.67%
6 / 9
11.62
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 parse
93.33% covered (success)
93.33%
14 / 15
0.00% covered (danger)
0.00%
0 / 1
2.00
 addKid
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 removeKid
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 setKids
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getCount
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getKids
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 hasKid
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 __toString
100.00% covered (success)
100.00%
2 / 2
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-2024 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\Build\PdfObject;
15
16/**
17 * Pdf parent object class
18 *
19 * @category   Pop
20 * @package    Pop\Pdf
21 * @author     Nick Sagona, III <dev@nolainteractive.com>
22 * @copyright  Copyright (c) 2009-2024 NOLA Interactive, LLC. (http://www.nolainteractive.com)
23 * @license    http://www.popphp.org/license     New BSD License
24 * @version    5.0.0
25 */
26class ParentObject extends AbstractObject
27{
28
29    /**
30     * PDF parent object index
31     * @var ?int
32     */
33    protected ?int $index = 2;
34
35    /**
36     * PDF parent kids
37     * @var array
38     */
39    protected array $kids = [];
40
41    /**
42     * Constructor
43     *
44     * Instantiate a PDF parent object.
45     *
46     * @param  int $index
47     */
48    public function __construct(int $index = 2)
49    {
50        $this->setIndex($index);
51        $this->setData("[{parent_index}] 0 obj\n<</Type/Pages/Count [{count}]/Kids[[{kids}]]>>\nendobj\n");
52    }
53
54    /**
55     * Parse a parent object from a string
56     *
57     * @param  string $stream
58     * @return ParentObject
59     */
60    public static function parse(string $stream): ParentObject
61    {
62        $parent = new self();
63
64        $parent->setIndex(substr($stream, 0, strpos($stream, ' ')));
65        $stream = str_replace($parent->getIndex() . ' 0 obj', '[{parent_index}] 0 obj', $stream);
66
67        // Determine the kids count.
68        $matches = [];
69        preg_match('/\/Count\s\d*/', $stream, $matches);
70        $count  = $matches[0];
71        $count  = str_replace('/Count ', '', $count);
72        $stream = str_replace('Count ' . $count, 'Count [{count}]', $stream);
73
74        // Determine the kids object indices.
75        $kids = trim(substr($stream, (strpos($stream, '/Kids') + 5)));
76        $kids = (str_starts_with($kids, '[')) ? substr($kids, 0, strpos($kids, ']') + 1) :
77            substr($kids, 0, (strpos($kids, ' R') + 2));
78
79        $kidIndices = $parent->getDictionaryReferences(substr($stream, (strpos($stream, '/Kids') + 5)));
80
81        $parent->setKids($kidIndices);
82        $parent->setData(str_replace($kids, '[[{kids}]]', $stream) . "\n");
83
84        return $parent;
85    }
86
87    /**
88     * Add a kid index to the parent object
89     *
90     * @param  int $kid
91     * @return ParentObject
92     */
93    public function addKid(int$kid): ParentObject
94    {
95        $this->kids[] = (int)$kid;
96        return $this;
97    }
98
99    /**
100     * Remove a kid index from the parent object
101     *
102     * @param  int $kid
103     * @return ParentObject
104     */
105    public function removeKid(int $kid): ParentObject
106    {
107        if ($this->hasKid($kid)) {
108            unset($this->kids[array_search($kid, $this->kids)]);
109        }
110        return $this;
111    }
112
113    /**
114     * Set the parent object kids
115     *
116     * @param  array $kids
117     * @return ParentObject
118     */
119    public function setKids(array $kids): ParentObject
120    {
121        $this->kids = $kids;
122        return $this;
123    }
124
125    /**
126     * Get the parent object kid count
127     *
128     * @return int
129     */
130    public function getCount(): int
131    {
132        return count($this->kids);
133    }
134
135    /**
136     * Get the parent object kid indices
137     *
138     * @return array
139     */
140    public function getKids(): array
141    {
142        return $this->kids;
143    }
144
145    /**
146     * Determine whether the parent object contains a kid object index
147     *
148     * @param  int $kid
149     * @return bool
150     */
151    public function hasKid(int $kid): bool
152    {
153        return (in_array($kid, $this->kids));
154    }
155
156    /**
157     * Method to print the parent object.
158     *
159     * @return string
160     */
161    public function __toString(): string
162    {
163        return str_replace(['[{parent_index}]', '[{count}]', '[{kids}]'],
164            [$this->index, count($this->kids), implode(" 0 R ", $this->kids) . " 0 R"], $this->data);
165    }
166
167}