protected function entityDecode($str)
{
static $entities;
if (strpos($str, '&') === false) {
return $str;
}
$flags = ENT_COMPAT | ENT_HTML5;
do {
$str_compare = $str;
if (preg_match_all('/&[a-z]{2,}(?![a-z;])/i', $str, $matches)) {
if (!isset($entities)) {
$entities = array_map('strtolower', get_html_translation_table(HTML_ENTITIES, $flags));
}
$replace = [];
$matches = array_unique(array_map('strtolower', $matches[0]));
for ($i = 0, $c = count($matches); $i < $c; ++$i) {
if (($char = array_search(array_get($matches, $i) . ';', $entities, true)) !== false) {
$replace[array_get($matches, $i)] = $char;
}
}
$str = str_ireplace(array_keys($replace), array_values($replace), $str);
}
$str = html_entity_decode(preg_replace('/(&#(?:x0*[0-9a-f]{2,5}(?![0-9a-f;])|(?:0*\\d{2,4}(?![0-9;]))))/iS', '$1;', $str), $flags);
} while ($str_compare !== $str);
return $str;
}