ILIAS  release_9 Revision v9.13-25-g2c18ec4c24f
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 
30 class ValidHTML
31 {
32  // @see: https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlerror.html enum xmlParserErrors.
33  // The xmlParserErrors enum in the C API is not made available in PHP.
34  private const UNKNOWN_TAG = 801;
35 
36  public function isTrue(string $string): bool
37  {
38  if (!preg_match('/<[^>]+?>/', $string)) {
39  return false;
40  }
41 
42  $error_state = libxml_use_internal_errors(true);
43  libxml_clear_errors();
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  $dom = new DOMDocument();
51  $import_succeeded = $dom->loadHTML($string);
52 
53  $errors = libxml_get_errors();
54  libxml_clear_errors();
55  libxml_use_internal_errors($error_state);
56 
57  if (
58  !$import_succeeded ||
59  [] !== array_filter(
60  $errors,
61  static fn(LibXMLError $error): bool => $error->code !== self::UNKNOWN_TAG
62  )
63  ) {
64  return false;
65  }
66 
67  $iter = new RecursiveIteratorIterator(
68  new ilHtmlDomNodeIterator($dom),
69  RecursiveIteratorIterator::SELF_FIRST
70  );
71  foreach ($iter as $element) {
73  if (strtolower($element->nodeName) === 'body') {
74  continue;
75  }
76 
77  if ($element->nodeType === XML_ELEMENT_NODE) {
78  return true;
79  }
80  }
81 
82  return false;
83  } catch (Throwable $e) {
84  $errors = libxml_get_errors();
85  libxml_clear_errors();
86  libxml_use_internal_errors($error_state);
87  return false;
88  } finally {
89  restore_error_handler();
90  }
91  }
92 }
ilErrorHandling $error
Definition: class.ilias.php:55
$message
Definition: xapiexit.php:32