Completed
Push — master ( 9157af...94c184 )
by Michele
04:14
created

Tree::parseParentElement()   D

Complexity

Conditions 9
Paths 9

Size

Total Lines 27
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 19
CRAP Score 9

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 27
ccs 19
cts 19
cp 1
rs 4.909
cc 9
eloc 20
nc 9
nop 3
crap 9
1
<?php
2
3
namespace CHMLib\TOCIndex;
4
5
use CHMLib\CHM;
6
use CHMLib\Map;
7
use DOMDocument;
8
use DOMElement;
9
use DOMXpath;
10
use Exception;
11
12
/**
13
 * A list of items in the TOC or in the Index of an CHM file.
14
 */
15
class Tree
16
{
17
    /**
18
     * List of Item instances children of this tree.
19
     *
20
     * @var Item[]
21
     */
22
    protected $items;
23
24
    /**
25
     * Initializes the instance.
26
     */
27 1
    public function __construct()
28
    {
29 1
        $this->items = array();
30 1
    }
31
32
    /**
33
     * Get the items contained in this tree.
34
     *
35
     * @return Item[]
36
     */
37 1
    public function getItems()
38
    {
39 1
        return $this->items;
40
    }
41
42
    /**
43
     * Resolve the items contained in other CHM files.
44
     *
45
     * @param Map $map
46
     *
47
     * @throws Exception Throw an Exception in case of errors.
48
     */
49 1
    public function resolve(Map $map)
50
    {
51 1
        $result = array();
52 1
        foreach ($this->items as $item) {
53 1
            $result = array_merge($result, $item->resolve($map));
54
        }
55
56 1
        $this->items = $result;
57 1
    }
58
59
    /**
60
     * Create a new instance starting from the whole TOC/Index source 'HTML'.
61
     *
62
     * @param CHM $chm The parent CHM instance.
63
     * @param string $data The contents of the .hhc/.hhk file.
64
     *
65
     * @throws Exception Throw an Exception in case of errors.
66
     *
67
     * @return static
68
     */
69 1
    public static function fromString(CHM $chm, $data)
70
    {
71 1
        if (!class_exists('DOMDocument', false) || !class_exists('DOMXpath', false)) {
72
            throw new Exception('Missing PHP extension: php-xml');
73
        }
74 1
        $result = new static();
75 1
        $data = trim((string) $data);
76 1
        if (stripos($data, '<object') !== false) {
77 1
            $doc = new DOMDocument();
78 1
            $charset = 'ISO-8859-1';
79 1
            if (preg_match('%^<\?xml\s+encoding\s*=\s*"([^"]+)"%i', $data, $m)) {
80
                $charset = $m[1];
0 ignored issues
show
Unused Code introduced by
$charset is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
81
            } else {
82 1
                if (preg_match('%<meta\s+http-equiv\s*=\s*"Content-Type"\s+content\s*=\s*"text/html;\s*charset=([^"]+)">%i', $data, $m)) {
83
                    $charset = $m[1];
84
                }
85 1
                $data = '<?xml encoding="'.$charset.'">'.$data;
86
            }
87
            // LI elements are very often malformed/misplaced: let's remove them
88 1
            $data = preg_replace('$</?li((\\s+[^>]*)|\\s*)>$i', '', $data);
89 1
            if (@$doc->loadHTML($data) !== true) {
90
                throw new Exception('Failed to parse the .hhc/.hhk file contents');
91
            }
92 1
            $result->parseParentElement($chm, $doc->documentElement, 0);
93
        }
94
95 1
        return $result;
96
    }
97
98
    /**
99
     * Depth of the found child items.
100
     *
101
     * @var int
102
     */
103
    protected $depth;
104
105
    /**
106
     * Parse a DOMElement and read the items/sub trees.
107
     *
108
     * @param CHM $chm
109
     * @param DOMElement $parentElement
110
     * @param int $depth
111
     */
112 1
    protected function parseParentElement(CHM $chm, DOMElement $parentElement, $depth)
113
    {
114 1
        foreach ($parentElement->childNodes as $node) {
115 1
            if ($node->nodeType === XML_ELEMENT_NODE) {
116 1
                switch (strtolower($node->tagName)) {
117 1
                    case 'object':
118 1
                        if (strtolower($node->getAttribute('type')) === 'text/sitemap') {
119 1
                            $this->depth = $depth;
120 1
                            $this->items[] = new Item($chm, $node);
121
                        }
122 1
                        break;
123 1
                    case 'ul':
124 1
                    case 'ol':
125 1
                        $n = count($this->items);
126 1
                        if ($n > 0 && $depth >= $this->depth) {
127 1
                            $this->items[$n - 1]->getChildren()->parseParentElement($chm, $node, $depth + 1);
128
                        } else {
129 1
                            $this->parseParentElement($chm, $node, $depth + 1);
130
                        }
131 1
                        break;
132
                    default:
133 1
                        $this->parseParentElement($chm, $node, $depth + 1);
134 1
                        break;
135
                }
136
            }
137
        }
138 1
    }
139
}
140