Passed
Push — master ( 668c77...c11634 )
by Gilles
02:19
created

Dom::clean()   F

Complexity

Conditions 21
Paths 158

Size

Total Lines 94
Code Lines 51

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 35
CRAP Score 36.4057

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 21
eloc 51
c 2
b 0
f 0
nc 158
nop 1
dl 0
loc 94
ccs 35
cts 52
cp 0.6731
crap 36.4057
rs 3.6833

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 297
    public function __construct(?ParserInterface $domParser = null, ?CleanerInterface $domCleaner = null)
64
    {
65 297
        if ($domParser === null) {
66 297
            $domParser = DomParserDiscovery::find();
67
        }
68 297
        if ($domCleaner === null) {
69 297
            $domCleaner = CleanerDiscovery::find();
70
        }
71
72 297
        $this->domParser = $domParser;
73 297
        $this->domCleaner = $domCleaner;
74 297
    }
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 = null, ?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 288
    public function loadStr(string $str, ?Options $options = null): Dom
146
    {
147 288
        $localOptions = new Options();
148 288
        if ($this->globalOptions !== null) {
149 75
            $localOptions = $localOptions->setFromOptions($this->globalOptions);
150
        }
151 288
        if ($options !== null) {
152 9
            $localOptions = $localOptions->setFromOptions($options);
153
        }
154
155 288
        $html = $this->domCleaner->clean($str, $localOptions, $this->defaultCharset);
156
157 288
        $this->content = new Content($html);
158
159 288
        $this->root = $this->domParser->parse($localOptions, $this->content, \strlen($str));
160 282
        $this->domParser->detectCharset($localOptions, $this->defaultCharset, $this->root);
161
162 282
        return $this;
163
    }
164
165
    /**
166
     * Sets a global options array to be used by all load calls.
167
     */
168 75
    public function setOptions(Options $options): Dom
169
    {
170 75
        $this->globalOptions = $options;
171
172 75
        return $this;
173
    }
174
175
    /**
176
     * Find elements by css selector on the root node.
177
     *
178
     * @throws NotLoadedException
179
     * @throws ChildNotFoundException
180
     *
181
     * @return mixed|Collection|null
182
     */
183 213
    public function find(string $selector, int $nth = null)
184
    {
185 213
        $this->isLoaded();
186
187 210
        return $this->root->find($selector, $nth);
188
    }
189
190
    /**
191
     * Simple wrapper function that returns an element by the
192
     * id.
193
     *
194
     * @param $id
195
     *
196
     * @throws NotLoadedException
197
     * @throws ChildNotFoundException
198
     *
199
     * @return mixed|Collection|null
200
     */
201 12
    public function getElementById($id)
202
    {
203 12
        $this->isLoaded();
204
205 12
        return $this->find('#' . $id, 0);
206
    }
207
208
    /**
209
     * Simple wrapper function that returns all elements by
210
     * tag name.
211
     *
212
     * @throws NotLoadedException
213
     * @throws ChildNotFoundException
214
     *
215
     * @return mixed|Collection|null
216
     */
217 15
    public function getElementsByTag(string $name)
218
    {
219 15
        $this->isLoaded();
220
221 15
        return $this->find($name);
222
    }
223
224
    /**
225
     * Simple wrapper function that returns all elements by
226
     * class name.
227
     *
228
     * @throws NotLoadedException
229
     * @throws ChildNotFoundException
230
     *
231
     * @return mixed|Collection|null
232
     */
233 3
    public function getElementsByClass(string $class)
234
    {
235 3
        $this->isLoaded();
236
237 3
        return $this->find('.' . $class);
238
    }
239
240
    /**
241
     * Checks if the load methods have been called.
242
     *
243
     * @throws NotLoadedException
244
     */
245 273
    private function isLoaded(): void
246
    {
247 273
        if (\is_null($this->content)) {
248 3
            throw new NotLoadedException('Content is not loaded!');
249
        }
250 270
    }
251
}
252