Test Failed
Pull Request — master (#510)
by Jeremy
04:34 queued 02:12
created

Header::getDetails()   C

Complexity

Conditions 12
Paths 28

Size

Total Lines 34
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 13.9437

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 12
eloc 21
c 1
b 0
f 0
nc 28
nop 1
dl 0
loc 34
ccs 16
cts 21
cp 0.7619
crap 13.9437
rs 6.9666

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * @file
5
 *          This file is part of the PdfParser library.
6
 *
7
 * @author  Sébastien MALOT <[email protected]>
8
 * @date    2017-01-03
9
 *
10
 * @license LGPLv3
11
 * @url     <https://github.com/smalot/pdfparser>
12
 *
13
 *  PdfParser is a pdf library written in PHP, extraction oriented.
14
 *  Copyright (C) 2017 - Sébastien MALOT <[email protected]>
15
 *
16
 *  This program is free software: you can redistribute it and/or modify
17
 *  it under the terms of the GNU Lesser General Public License as published by
18
 *  the Free Software Foundation, either version 3 of the License, or
19
 *  (at your option) any later version.
20
 *
21
 *  This program is distributed in the hope that it will be useful,
22
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
23
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24
 *  GNU Lesser General Public License for more details.
25
 *
26
 *  You should have received a copy of the GNU Lesser General Public License
27
 *  along with this program.
28
 *  If not, see <http://www.pdfparser.org/sites/default/LICENSE.txt>.
29
 */
30
31
namespace Smalot\PdfParser;
32
33
use Smalot\PdfParser\Element\ElementArray;
34
use Smalot\PdfParser\Element\ElementMissing;
35
use Smalot\PdfParser\Element\ElementStruct;
36
use Smalot\PdfParser\Element\ElementXRef;
37
38
/**
39
 * Class Header
40
 */
41
class Header
42
{
43
    /**
44
     * @var Document
45
     */
46
    protected $document = null;
47
48
    /**
49
     * @var Element[]
50
     */
51
    protected $elements = null;
52
53
    /**
54
     * @param Element[] $elements list of elements
55
     * @param Document  $document document
56
     */
57 65
    public function __construct(array $elements = [], ?Document $document = null)
58
    {
59 65
        $this->elements = $elements;
60 65
        $this->document = $document;
61 65
    }
62
63 43
    public function init()
64
    {
65 43
        foreach ($this->elements as $element) {
66 43
            if ($element instanceof Element) {
67 43
                $element->init();
68
            }
69
        }
70 43
    }
71
72
    /**
73
     * Returns all elements.
74
     */
75 36
    public function getElements()
76
    {
77 36
        foreach ($this->elements as $name => $element) {
78 36
            $this->resolveXRef($name);
79
        }
80
81 36
        return $this->elements;
82
    }
83
84
    /**
85
     * Used only for debug.
86
     */
87 1
    public function getElementTypes(): array
88
    {
89 1
        $types = [];
90
91 1
        foreach ($this->elements as $key => $element) {
92 1
            $types[$key] = \get_class($element);
93
        }
94
95 1
        return $types;
96
    }
97
98 34
    public function getDetails(bool $deep = true): array
99
    {
100 34
        $values = [];
101 34
        $elements = $this->getElements();
102
103 34
        foreach ($elements as $key => $element) {
104 34
            if ($element instanceof self && $deep) {
105
                $values[$key] = $element->getDetails($deep);
106 34
            } elseif ($element instanceof PDFObject && $deep) {
107
                $values[$key] = $element->getDetails(false);
108 34
            } elseif ($element instanceof ElementArray) {
109
                if ($deep) {
110
                    $values[$key] = $element->getDetails();
111
                }
112 34
            } elseif ($element instanceof Element) {
113 34
                $values[$key] = (string) $element;
114
            }
115
        }
116
117
        // ensure detail information aren't badly encoded
118 34
        foreach ($values as $key => $value) {
119 34
            if (false === preg_match('!!u', $value)) {
120 4
                $font = $this->document->getFirstFont();
121 4
                if ($font) {
122 4
                    $newValue = $font->decodeContent($value);
123
                } else {
124
                    $newValue = mb_convert_encoding($value, 'UTF-8', 'Windows-1252');
125
                }
126
127 4
                $values[$key] = $newValue;
128
            }
129
        }
130
131 34
        return $values;
132
    }
133
134
    /**
135
     * Indicate if an element name is available in header.
136
     *
137
     * @param string $name the name of the element
138
     */
139 47
    public function has(string $name): bool
140
    {
141 47
        return \array_key_exists($name, $this->elements);
142
    }
143
144
    /**
145
     * @return Element|PDFObject
146
     */
147 50
    public function get(string $name)
148
    {
149 50
        if (\array_key_exists($name, $this->elements)) {
150 49
            return $this->resolveXRef($name);
151
        }
152
153 47
        return new ElementMissing();
154
    }
155
156
    /**
157
     * Resolve XRef to object.
158
     *
159
     * @return Element|PDFObject
160
     *
161
     * @throws \Exception
162
     */
163 50
    protected function resolveXRef(string $name)
164
    {
165 50
        if (($obj = $this->elements[$name]) instanceof ElementXRef && null !== $this->document) {
166
            /** @var ElementXRef $obj */
167 38
            $object = $this->document->getObjectById($obj->getId());
168
169 38
            if (null === $object) {
170 2
                return new ElementMissing();
171
            }
172
173
            // Update elements list for future calls.
174 38
            $this->elements[$name] = $object;
175
        }
176
177 50
        return $this->elements[$name];
178
    }
179
180
    /**
181
     * @param string   $content  The content to parse
182
     * @param Document $document The document
183
     * @param int      $position The new position of the cursor after parsing
184
     */
185 21
    public static function parse(string $content, Document $document, int &$position = 0): self
186
    {
187
        /* @var Header $header */
188 21
        if ('<<' == substr(trim($content), 0, 2)) {
189 20
            $header = ElementStruct::parse($content, $document, $position);
190
        } else {
191 8
            $elements = ElementArray::parse($content, $document, $position);
192 8
            $header = new self([], $document);
193
194 8
            if ($elements) {
195 7
                $header = new self($elements->getRawContent(), null);
196
            }
197
        }
198
199 21
        if ($header) {
200 21
            return $header;
201
        }
202
203
        // Build an empty header.
204
        return new self([], $document);
205
    }
206
}
207