ILIAS  trunk Revision v11.0_alpha-2645-g16283d3b3f8
ValidHTML.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
21 namespace ILIAS\LegalDocuments;
22 
24 use DOMDocument;
25 use ErrorException;
27 use LibXMLError;
28 use Throwable;
29 use DOMNode;
30 
31 class ValidHTML
32 {
33  // @see: https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlerror.html enum xmlParserErrors.
34  // The xmlParserErrors enum in the C API is not made available in PHP.
35  private const UNKNOWN_TAG = 801;
36 
37  public function isTrue(string $string): bool
38  {
39  if (!preg_match('/<[^>]+?>/', $string)) {
40  return false;
41  }
42 
43  $error_state = libxml_use_internal_errors(true);
44  libxml_clear_errors();
45 
46  try {
47  set_error_handler(static function (int $severity, string $message, string $file, int $line): void {
48  throw new ErrorException($message, $severity, $severity, $file, $line);
49  });
50 
51  $dom = new DOMDocument();
52  $import_succeeded = $dom->loadHTML($string);
53 
54  $errors = libxml_get_errors();
55  libxml_clear_errors();
56  libxml_use_internal_errors($error_state);
57 
58  if (
59  !$import_succeeded ||
60  [] !== array_filter(
61  $errors,
62  static fn(LibXMLError $error): bool => $error->code !== self::UNKNOWN_TAG
63  )
64  ) {
65  return false;
66  }
67 
68  $iter = new RecursiveIteratorIterator(
69  new ilHtmlDomNodeIterator($dom),
70  RecursiveIteratorIterator::SELF_FIRST
71  );
72  foreach ($iter as $element) {
74  if (strtolower($element->nodeName) === 'body') {
75  continue;
76  }
77 
78  if ($element->nodeType === XML_ELEMENT_NODE) {
79  return true;
80  }
81  }
82 
83  return false;
84  } catch (Throwable) {
85  $errors = libxml_get_errors();
86  libxml_clear_errors();
87  libxml_use_internal_errors($error_state);
88  return false;
89  } finally {
90  restore_error_handler();
91  }
92  }
93 }
ilErrorHandling $error
Definition: class.ilias.php:69
$message
Definition: xapiexit.php:31