Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
55.00% covered (warning)
55.00%
11 / 20
20.00% covered (danger)
20.00%
1 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
HtmlDocument
52.63% covered (warning)
52.63%
10 / 19
20.00% covered (danger)
20.00%
1 / 5
20.63
0.00% covered (danger)
0.00%
0 / 1
 __construct
83.33% covered (warning)
83.33%
5 / 6
0.00% covered (danger)
0.00%
0 / 1
3.04
 importNode
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 build
80.00% covered (warning)
80.00%
4 / 5
0.00% covered (danger)
0.00%
0 / 1
2.03
 save
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 path
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3declare(strict_types=1);
4
5namespace PeServer\Core\Html;
6
7use DOMDocument;
8use DOMElement;
9use PeServer\Core\Html\HtmlTagElement;
10use PeServer\Core\Html\HtmlElementBase;
11use PeServer\Core\Html\HtmlXPath;
12use PeServer\Core\Throws\HtmlDocumentException;
13use PeServer\Core\Throws\Throws;
14use ValueError;
15
16libxml_use_internal_errors(true);
17
18/**
19 * `DOMDocument` ラッパー。
20 *
21 * JSでもそうだけどなんでDOMは地味に使い辛いんかね。
22 */
23class HtmlDocument extends HtmlElementBase
24{
25    #region variable
26
27    /**
28     * 生で使用する用。
29     */
30    public readonly DOMDocument $raw;
31
32    #endregion
33
34    public function __construct(?string $html = null)
35    {
36        $this->raw = new DOMDocument();
37        parent::__construct($this, $this->raw);
38
39        if ($html !== null) {
40            $result = Throws::wrap(ValueError::class, HtmlDocumentException::class, fn () => $this->raw->loadHTML($html));
41            if ($result == false) {
42                throw new HtmlDocumentException();
43            }
44        }
45    }
46
47    #region function
48
49    public function importNode(HtmlTagElement $node): HtmlTagElement
50    {
51        /** @var DOMElement|false */
52        $importedNode = $this->raw->importNode($node->raw, true);
53        if ($importedNode === false) {
54            throw new HtmlDocumentException();
55        }
56        return new HtmlTagElement($this, $importedNode);
57    }
58
59    /**
60     * `DOMDocument::saveHTML` ラッパー。
61     * @return string
62     * @throws HtmlDocumentException
63     * @see https://www.php.net/manual/domdocument.savehtml.php
64     */
65    public function build(): string
66    {
67        $this->raw->normalize();
68
69        $html = $this->raw->saveHTML();
70        if ($html === false) {
71            throw new HtmlDocumentException();
72        }
73
74        return $html;
75    }
76
77    /**
78     * `DOMDocument::saveHTMLFile` ラッパー。
79     * @param string $path
80     * @throws HtmlDocumentException
81     * @see https://www.php.net/manual/domdocument.savehtmlfile.php
82     */
83    public function save(string $path): void
84    {
85        $length = $this->raw->saveHTMLFile($path);
86        if ($length === false) {
87            throw new HtmlDocumentException();
88        }
89    }
90
91    #endregion
92
93    #region HtmlElementBase
94
95    final public function path(): HtmlXPath
96    {
97        return new HtmlXPath($this->document, null);
98    }
99
100    #endregion
101}