ILIAS  release_8 Revision v8.24
class.ilTermsOfServiceDocumentsContainsHtmlValidator.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
26{
27 private const LIBXML_CODE_HTML_UNKNOWN_TAG = 801;
28
29 private string $text;
30 private bool $xmlErrorState = false;
32 private array $xmlErrors = [];
33
34 public function __construct(string $text)
35 {
36 $this->text = $text;
37 }
38
39 public function isValid(): bool
40 {
41 if (!preg_match('/<[^>]+?>/', $this->text)) {
42 return false;
43 }
44
45 try {
46 set_error_handler(static function (int $severity, string $message, string $file, int $line): void {
47 throw new ErrorException($message, $severity, $severity, $file, $line);
48 });
49
50 $this->beginXmlLogging();
51
52 $dom = new DOMDocument();
53 $import_succeeded = $dom->loadHTML($this->text);
54
55 $this->endXmlLogging();
56
57 if (!$import_succeeded || $this->xmlErrorsOccurred()) {
58 return false;
59 }
60
61 $iter = new RecursiveIteratorIterator(
62 new ilHtmlDomNodeIterator($dom),
63 RecursiveIteratorIterator::SELF_FIRST
64 );
65 foreach ($iter as $element) {
67 if (strtolower($element->nodeName) === 'body') {
68 continue;
69 }
70
71 if ($element->nodeType === XML_ELEMENT_NODE) {
72 return true;
73 }
74 }
75
76 return false;
77 } catch (Throwable $e) {
78 $this->endXmlLogging();
79 return false;
80 } finally {
81 restore_error_handler();
82 }
83 }
84
85 private function beginXmlLogging(): void
86 {
87 $this->xmlErrorState = libxml_use_internal_errors(true);
88 libxml_clear_errors();
89 }
90
91 private function addErrors(): void
92 {
93 $currentErrors = libxml_get_errors();
94 libxml_clear_errors();
95
96 $this->xmlErrors = $currentErrors;
97 }
98
99 private function endXmlLogging(): void
100 {
101 $this->addErrors();
102
103 libxml_use_internal_errors($this->xmlErrorState);
104 }
105
109 private function relevantXmlErrors(): array
110 {
111 return array_filter($this->xmlErrors, static function (LibXMLError $error): bool {
112 return $error->code !== self::LIBXML_CODE_HTML_UNKNOWN_TAG;
113 });
114 }
115
116 private function xmlErrorsOccurred(): bool
117 {
118 return $this->relevantXmlErrors() !== [];
119 }
120}
Class ilHtmlDomNodeIterator.
$message
Definition: xapiexit.php:32