-
-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathCommentIni.php
83 lines (68 loc) · 1.89 KB
/
CommentIni.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
<?php
namespace Gt\DomTemplate;
use Gt\Dom\Comment;
use Gt\Dom\Document;
use Gt\Dom\Element;
use Gt\Dom\NodeFilter;
use Throwable;
class CommentIni {
/** @var array<string, array<string, string>|string>|null */
private ?array $iniData;
public function __construct(
Document|Element $context
) {
if($context instanceof Document) {
$context = $context->documentElement;
}
/** @var Element $context */
$walker = $context->ownerDocument->createTreeWalker(
$context,
NodeFilter::SHOW_COMMENT
);
$ini = null;
$commentNodeToRemove = null;
/** @var Element|Comment $commentNode */
foreach($walker as $commentNode) {
if(!$commentNode instanceof Comment) {
continue;
}
$data = trim($commentNode->data);
try {
// We know that sometimes this data will not be correct ini format, and it might actually be a textual comment.
// Therefore, we must suppress the warning that is emitted by parse_ini_string:
$ini = @parse_ini_string($data, true);
$commentNodeToRemove = $commentNode;
}
catch(Throwable) {
$ini = null;
}
if(!$ini) {
break;
}
// At this point, the ini has successfully parsed.
$context = $commentNode;
while($context = $context->previousSibling) {
if(trim($context->textContent ?? "") !== "") {
throw new CommentIniInvalidDocumentLocationException("A Comment INI must only appear as the first node of the HTML.");
}
}
}
$commentNodeToRemove?->parentNode->removeChild($commentNodeToRemove);
$this->iniData = $ini ?: null;
}
public function get(string $variable):?string {
$parts = explode(".", $variable);
$var = $this->iniData;
foreach($parts as $part) {
$var = $var[$part] ?? null;
}
return $var;
}
/** @return array<string, string> */
public function getVars():array {
return $this->iniData["vars"] ?? [];
}
public function containsIniData():bool {
return !empty($this->iniData);
}
}