Passed
Branch dev/3.0.0 (c487fc)
by Gilles
01:48
created

Dom::parseTag()   F

Complexity

Conditions 27
Paths 79

Size

Total Lines 153
Code Lines 102

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 92
CRAP Score 27.023

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 27
eloc 102
c 1
b 0
f 0
nc 79
nop 0
dl 0
loc 153
ccs 92
cts 95
cp 0.9684
crap 27.023
rs 3.3333

How to fix   Long Method    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
declare(strict_types=1);
4
5
namespace PHPHtmlParser;
6
7
use GuzzleHttp\Psr7\Request;
8
use Http\Adapter\Guzzle6\Client;
9
use PHPHtmlParser\Contracts\Dom\CleanerInterface;
10
use PHPHtmlParser\Contracts\Dom\ParserInterface;
11
use PHPHtmlParser\Contracts\DomInterface;
12
use PHPHtmlParser\Discovery\CleanerDiscovery;
13
use PHPHtmlParser\Discovery\DomParserDiscovery;
14
use PHPHtmlParser\Dom\Node\Collection;
15
use PHPHtmlParser\Dom\RootAccessTrait;
16
use PHPHtmlParser\Exceptions\ChildNotFoundException;
17
use PHPHtmlParser\Exceptions\CircularException;
18
use PHPHtmlParser\Exceptions\LogicalException;
19
use PHPHtmlParser\Exceptions\NotLoadedException;
20
use PHPHtmlParser\Exceptions\StrictException;
21
use PHPHtmlParser\Exceptions\UnknownChildTypeException;
22
use Psr\Http\Client\ClientExceptionInterface;
23
use Psr\Http\Client\ClientInterface;
24
use Psr\Http\Message\RequestInterface;
25
26
/**
27
 * Class Dom.
28
 */
29
class Dom implements DomInterface
30
{
31
    use RootAccessTrait;
32
33
    /**
34
     * The charset we would like the output to be in.
35
     *
36
     * @var string
37
     */
38
    private $defaultCharset = 'UTF-8';
39
40
    /**
41
     * The document string.
42
     *
43
     * @var Content
44
     */
45
    private $content;
46
47
    /**
48
     * A global options array to be used by all load calls.
49
     *
50
     * @var ?Options
51
     */
52
    private $globalOptions;
53
54
    /**
55
     * @var ParserInterface
56
     */
57
    private $domParser;
58
    /**
59
     * @var CleanerInterface
60
     */
61
    private $domCleaner;
62
63 294
    public function __construct(?ParserInterface $domParser = null, ?CleanerInterface $domCleaner = null)
64
    {
65 294
        if ($domParser === null) {
66 294
            $domParser = DomParserDiscovery::find();
67
        }
68 294
        if ($domCleaner === null) {
69 294
            $domCleaner = CleanerDiscovery::find();
70
        }
71
72 294
        $this->domParser = $domParser;
73 294
        $this->domCleaner = $domCleaner;
74 294
    }
75
76
    /**
77
     * Returns the inner html of the root node.
78
     *
79
     * @throws ChildNotFoundException
80
     * @throws UnknownChildTypeException
81
     * @throws NotLoadedException
82
     */
83 24
    public function __toString(): string
84
    {
85 24
        $this->isLoaded();
86
87 24
        return $this->root->innerHtml();
88
    }
89
90
    /**
91
     * Loads the dom from a document file/url.
92
     *
93
     * @throws ChildNotFoundException
94
     * @throws CircularException
95
     * @throws Exceptions\ContentLengthException
96
     * @throws LogicalException
97
     * @throws StrictException
98
     */
99 57
    public function loadFromFile(string $file, ?Options $options = null): Dom
100
    {
101 57
        $content = @\file_get_contents($file);
102 57
        if ($content === false) {
103 3
            throw new LogicalException('file_get_contents failed and returned false when trying to read "' . $file . '".');
104
        }
105
106 54
        return $this->loadStr($content, $options);
107
    }
108
109
    /**
110
     * Use a curl interface implementation to attempt to load
111
     * the content from a url.
112
     *
113
     * @throws ChildNotFoundException
114
     * @throws CircularException
115
     * @throws Exceptions\ContentLengthException
116
     * @throws LogicalException
117
     * @throws StrictException
118
     * @throws ClientExceptionInterface
119
     */
120 6
    public function loadFromUrl(string $url, ?Options $options, ?ClientInterface $client = null, ?RequestInterface $request = null): Dom
121
    {
122 6
        if ($client === null) {
123
            $client = new Client();
124
        }
125 6
        if ($request === null) {
126 3
            $request = new Request('GET', $url);
127
        }
128
129 6
        $response = $client->sendRequest($request);
130 6
        $content = $response->getBody()->getContents();
131
132 6
        return $this->loadStr($content, $options);
133
    }
134
135
    /**
136
     * Parsers the html of the given string. Used for load(), loadFromFile(),
137
     * and loadFromUrl().
138
     *
139
     * @throws ChildNotFoundException
140
     * @throws CircularException
141
     * @throws Exceptions\ContentLengthException
142
     * @throws LogicalException
143
     * @throws StrictException
144
     */
145 285
    public function loadStr(string $str, ?Options $options = null): Dom
146
    {
147 285
        $localOptions = new Options();
148 285
        if ($this->globalOptions !== null) {
149 75
            $localOptions = $localOptions->setFromOptions($this->globalOptions);
150
        }
151 285
        if ($options !== null) {
152 9
            $localOptions = $localOptions->setFromOptions($options);
153
        }
154
155 285
        $html = $this->domCleaner->clean($str, $localOptions);
156
157 285
        $this->content = new Content($html);
158
159 285
        $this->root = $this->domParser->parse($localOptions, $this->content, strlen($str));
160 279
        $this->domParser->detectCharset($localOptions, $this->defaultCharset, $this->root);
161
162 279
        return $this;
163
    }
164
165
    /**
166
     * Sets a global options array to be used by all load calls.
167
     *
168
     *
169
     */
170 75
    public function setOptions(Options $options): Dom
171
    {
172 75
        $this->globalOptions = $options;
173
174 75
        return $this;
175
    }
176
177
    /**
178
     * Find elements by css selector on the root node.
179
     *
180
     * @return mixed|Collection|null
181
     * @throws NotLoadedException
182
     *
183
     * @throws ChildNotFoundException
184
     */
185 213
    public function find(string $selector, int $nth = null)
186
    {
187 213
        $this->isLoaded();
188
189 210
        return $this->root->find($selector, $nth);
190
    }
191
192
    /**
193
     * Simple wrapper function that returns an element by the
194
     * id.
195
     *
196
     * @param $id
197
     *
198
     * @return mixed|Collection|null
199
     * @throws NotLoadedException
200
     *
201
     * @throws ChildNotFoundException
202
     */
203 12
    public function getElementById($id)
204
    {
205 12
        $this->isLoaded();
206
207 12
        return $this->find('#' . $id, 0);
208
    }
209
210
    /**
211
     * Simple wrapper function that returns all elements by
212
     * tag name.
213
     *
214
     * @return mixed|Collection|null
215
     * @throws NotLoadedException
216
     *
217
     * @throws ChildNotFoundException
218
     */
219 15
    public function getElementsByTag(string $name)
220
    {
221 15
        $this->isLoaded();
222
223 15
        return $this->find($name);
224
    }
225
226
    /**
227
     * Simple wrapper function that returns all elements by
228
     * class name.
229
     *
230
     * @return mixed|Collection|null
231
     * @throws NotLoadedException
232
     *
233
     * @throws ChildNotFoundException
234
     */
235 3
    public function getElementsByClass(string $class)
236
    {
237 3
        $this->isLoaded();
238
239 3
        return $this->find('.' . $class);
240
    }
241
242
    /**
243
     * Checks if the load methods have been called.
244
     *
245
     * @throws NotLoadedException
246
     */
247 270
    private function isLoaded(): void
248
    {
249 270
        if (\is_null($this->content)) {
250 3
            throw new NotLoadedException('Content is not loaded!');
251
        }
252
    }
253
}