ILIAS  release_8 Revision v8.19
All Data Structures Namespaces Files Functions Variables Modules Pages
class.ilTermsOfServiceDocumentsContainsHtmlValidator.php
Go to the documentation of this file.
1 <?php
2 
19 declare(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 }
$message
Definition: xapiexit.php:32
Class ilHtmlDomNodeIterator.