Заменяет поля ввода полями-приманками

@param string $html   HTML-разметка формы
@param array  $names  Массив имён полей

@return string  HTML

@since 0.3.0
965688
protected function createHoneypots($html, array $names)
    {
        $honeypots = '';
        $this->meta->aliases = array();
        foreach ($names as $name)
        {
            $p = strpos($html, 'name="' . $name . '"');
            if ($p === false)
            {
                continue;
            }

            $honeypots .= $this->createInput('text', $name);

            $alias = '';
            $length = mt_rand(8, 15);
            for ($i = 0; $i < $length; $i++)
            {
                $alias .= chr(mt_rand(ord('a'), ord('z')));
            }

            $this->meta->aliases[$alias] = $name;

            $html = substr_replace($html, $alias, $p + 6, strlen($name));
        }

        if ($honeypots != '')
        {
            $html = preg_replace('/(<form[^>]*>)/si',
                '$1<div style="display: none;">' . $honeypots . '</div>', $html);
        }

        return $html;
    }
1049997
public function setHtml($html)
    {
        if (!\is_string($html)) {
            throw new \InvalidArgumentException('The provided HTML must be a string.', 1540403913);
        }
        if ($html === '') {
            throw new \InvalidArgumentException('The provided HTML must not be empty.', 1540403910);
        }

        $this->createUnifiedDomDocument($html);
    }
185374
public function purify($html, $allowedTags = null, $allowedAttributes = null)
    {
        $html = (string)preg_replace('@<script.*>.*</script>@isU', '', $html);
        if ($html === '') {
            return '';
        }

        if (strpos($html, '<body>') === false) {
            $html = '<!doctype html><html><body>' . $html . '</body></html>';
        }

        $doc = new \DOMDocument();
        try {
            @$doc->loadHTML($html);
        } catch (\Exception $e) {
            return '';
        }

        $body = $doc->getElementsByTagName('body');
        if ($allowedTags !== null) {
            $tags = ',' . implode(',', $allowedTags) . ',';
        } else {
            $tags = $this->_allowedTags;
        }

        if ($allowedAttributes !== null) {
            $attributes = ',' . implode(',', $allowedAttributes) . ',';
        } else {
            $attributes = $this->_allowedAttributes;
        }

        $this->_purify(iterator_to_array($body->item(0)->childNodes), $tags, $attributes);
        $body = $doc->getElementsByTagName('body');
        return substr($doc->saveHTML($body->item(0)), 6, -7);
    }
1072611
protected function createDomDocumentFromHtml($html)
    {
        $document = new \DOMDocument('1.0', 'UTF-8');
        $internalErrors = libxml_use_internal_errors(true);
        if (!empty($html)) {
            $document->loadHTML(mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8'));
        }
        libxml_use_internal_errors($internalErrors);
        $document->formatOutput = true;

        return $document;
    }
286854
public function html($html = null)
    {
        if ($html === null) {
            return $this->_html;
        }
        $this->_html = $html;

        return $this;
    }
728157
static public function htmlClassTr($html, $css_tr) {
    $html = preg_replace_callback('@<(?<tag>[a-z]+)(?<other>\s+[^>]*)class="(?<class>[^"]+)"@s', function ($attrs) use ($css_tr) {
      $class = ' '
        . strtr($attrs['class'], array(
          "\n" => ' ',
          "\r" => ' ',
          "\t" => ' ',
        )) . ' ';
      $class = strtr($class, $css_tr['*']);
      if (isset($css_tr[$attrs['tag']])) {
        $class = strtr($class, $css_tr[$attrs['tag']]);
      }
      $class = trim($class);
      if ($class !== '') {
        $class = 'class="' . $class . '"';
      }
      return '<' . $attrs['tag'] . $attrs['other'] . $class;
    }, $html);
    return $html;
  }
1005335
private function eliminateUselessTags(string $html): string
    {
        // eliminate useless symbols
        $html = preg_replace('/[\342\200\230-\342\200\235]|[\342\206\220-\342\206\223]|[\342\226\240-\342\226\275]|[\342\227\206-\342\227\257]|\342\230\205|\342\230\206/u', '', $html);

        // eliminate useless html tags
        $html = preg_replace('/<(script|style|select|noscript)[^>]*>.*?<\/\1\s*>/isu', '', $html);
        $html = preg_replace('/<!--.*?-->/su', '', $html);
        $html = preg_replace('/<![A-Za-z].*?>/u', '', $html);
        $html = preg_replace('/<div\s[^>]*class\s*=\s*[\'"]?alpslab-slide["\']?[^>]*>.*?<\/div\s*>/su', '', $html);
        $html = preg_replace('/<div\s[^>]*(id|class)\s*=\s*[\'"]?\S*more\S*["\']?[^>]*>/iu', '', $html);

        return $html;
    }
1042922
protected function _renderBlocks($name, $attribs = array())
    {
        $html   = '';
        $count  = 1;
        $blocks = $this->getBlocks($name);

        foreach($blocks as $block)
        {
            //Set the block attributes
            if($count == 1) {
                $attribs['rel']['first'] = 'first';
            }

            if($count == count($blocks)) {
                $attribs['rel']['last'] = 'last';
            }

            if(isset($block['attribs'])) {
                $block['attribs'] = array_merge((array) $block['attribs'], $attribs);
            } else {
                $block['attribs'] = $attribs;
            }

            //Render the block
            $content = $this->_renderBlock($block);

            //Prepend or append the block
            if($block['extend'] == 'prepend') {
                $html = $content.$html;
            } else {
                $html = $html.$content;
            }

            $count++;
        }

        return $html;
    }
1314969
protected function renderHtml($name = null, $data = []) {
        if (is_array($name)) {
            $data = $name;
            $name = null;
        }
        return $this->renderFile($this->getViewFile($name), $data);
    }
812897
public function loadHTML($html)
    {
        $dom = new \DOMDocument();

        libxml_use_internal_errors(true);
        $dom->loadHTML($html, LIBXML_NOWARNING);
        $errors = libxml_get_errors();
        libxml_use_internal_errors(false);

        // Run through all errors
        /** @var \LibXMLError $error */
        foreach ($errors as $error) {
            throw new InvalidArgumentException(
                sprintf(InvalidArgumentException::INVALID_HTML_STR, trim($error->message)),
                InvalidArgumentException::INVALID_HTML
            );
        }

        return $dom;
    }
1361113
protected function makeAttribute($name, array $values)
    {
        $attr = $name . '="';

        switch (true)
        {
            case $values === [true]:
                $attr = $name;
                return $attr;
                break;
            case $name === 'style':
            case strpos($name, 'on') === 0:
                $attr .= htmlspecialchars(join(';', $values));
                break;
            default:
                $attr .= htmlspecialchars(join(' ', $values));
                break;
        }

        $attr .= '"';
        return $attr;
    }
1252196
protected function buildText(string $html): string
    {
        $text = Strings::replace($html, [
            '#<(style|script|head).*</\\1>#Uis' => '',
            '#<t[dh][ >]#i' => ' $0',
            '#<a\s[^>]*href=(?|"([^"]+)"|\'([^\']+)\')[^>]*>(.*?)</a>#is' => '$2 &lt;$1&gt;',
            '#[\r\n]+#' => ' ',
            '#<(/?p|/?h\d|li|br|/tr)[ >/]#i' => "\n$0",
        ]);
        $text = \html_entity_decode(\strip_tags($text), ENT_QUOTES, 'UTF-8');
        $text = Strings::replace($text, '#[ \t]+#', ' ');

        return \trim($text);
    }
1289858
public function getHtml(array $attributes = []): string
    {
        if ($this->minimumValue !== null) {
            $attributes['min'] = $this->minimumValue;
        }

        if ($this->maximumValue !== null) {
            $attributes['max'] = $this->maximumValue;
        }

        return parent::getHtml($attributes);
    }
490279
protected function parseHtml($html)
    {
        $data = [
            'image' => '',
            'title' => '',
            'description' => '',
            'pictures' => [],
        ];

        libxml_use_internal_errors(true);
        $doc = new \DOMDocument();
        $doc->loadHTML($html);

        /** @var \DOMElement $meta */
        foreach ($doc->getElementsByTagName('meta') as $meta) {
            if ($meta->getAttribute('itemprop') === 'image') {
                $data['image'] = $meta->getAttribute('content');
            } elseif ($meta->getAttribute('property') === 'og:image') {
                $data['image'] = $meta->getAttribute('content');
            } elseif ($meta->getAttribute('property') === 'twitter:image') {
                $data['image'] = $meta->getAttribute('value');
            }

            if ($meta->getAttribute('itemprop') === 'name') {
                $data['title'] = $meta->getAttribute('content');
            } elseif ($meta->getAttribute('property') === 'og:title') {
                $data['title'] = $meta->getAttribute('content');
            } elseif ($meta->getAttribute('property') === 'twitter:title') {
                $data['title'] = $meta->getAttribute('value');
            }

            if ($meta->getAttribute('itemprop') === 'description') {
                $data['title'] = $meta->getAttribute('content');
            }
            if ($meta->getAttribute('property') === 'og:description') {
                $data['description'] = $meta->getAttribute('content');
            }
        }

        if (empty($data['title'])) {
            /** @var \DOMElement $title */
            foreach ($doc->getElementsByTagName('title') as $title) {
                $data['title'] = $title->nodeValue;
            }
        }

        if (empty($data['description'])) {
            foreach ($doc->getElementsByTagName('meta') as $meta) {
                if ($meta->getAttribute('name') === 'description') {
                    $data['description'] = $meta->getAttribute('content');
                }
            }
        }

        foreach ($doc->getElementsByTagName('img') as $img) {
            $data['pictures'][] = $img->getAttribute('src');
        }

        return $data;
    }
99493
public function buildEmbedHtml(array $attributes = [], array $parameters = [])
    {
        // <iframe width="560" height="315" src="https://www.youtube.com/embed/5qanlirrRWs" frameborder="0" allowfullscreen></iframe>
        $attributes = array_merge($this->attributes, $attributes, [
            'src' => $this->buildEmbedUrl($parameters), // required attribute
        ]);

        $attributeStrings = [''];
        foreach ($attributes as $name => $value) {
            $attributeString = (string)$name;
            if (null !== $value) {
                $attributeString .= '="'.htmlspecialchars($value).'"';
            }
            $attributeStrings[] = $attributeString;
        }

        return '<iframe'.implode(' ', $attributeStrings).'></iframe>';
    }
430454
private static function buildHtmlAttribute($attributes)
    {
        $html = '';
        foreach ($attributes as $name => $value) {
            $html .= ' '.$name.'="'.$value.'"';
            $class_list = explode(' ', $value);
            foreach ($class_list as $class_name) {
                switch ($class_name) {
                    case 'class':
                        if (function_exists('hookAddClassHtmlTag')) {
                            hookAddClassHtmlTag($class_name);
                        }
                }
            }
        }

        return $html;
    }
1231699
public static function renderAttributes($attributes)
    {
        $attributes = self::mergeAttributes($attributes);

        $html = '';
        foreach ($attributes as $key => $value) {
            $html .= " {$key}=\"{$value}\"";
        }

        return new HtmlString(trim($html));
    }