Your IP : 216.73.216.229


Current Path : /var/tmp/
Upload File :
Current File : //var/tmp/php5CdSIf

home/digilove/public_html/libraries/regularlabs/src/Html.php000064400000057533152346066140020307 0ustar00<?php
/**
 * @package         Regular Labs Library
 * @version         23.7.24631
 * 
 * @author          Peter van Westen <info@regularlabs.com>
 * @link            https://regularlabs.com
 * @copyright       Copyright © 2023 Regular Labs All Rights Reserved
 * @license         GNU General Public License version 2 or later
 */

namespace RegularLabs\Library;

defined('_JEXEC') or die;

use DOMDocument;

/**
 * Class Html
 * @package RegularLabs\Library
 */
class Html
{
    /**
     * Removes complete html tag pairs from the concatenated parts
     *
     * @param array $parts
     * @param array $elements
     *
     * @return array
     */
    public static function cleanSurroundingTags($parts, $elements = ['p', 'span'])
    {
        $breaks = '(?:(?:<br ?/?>|<\!--[^>]*-->|:\|:)\s*)*';
        $keys   = array_keys($parts);

        $string = implode(':|:', $parts);
        Protect::protectHtmlCommentTags($string);

        // Remove empty tags
        $regex = '<(' . implode('|', $elements) . ')(?: [^>]*)?>\s*(' . $breaks . ')<\/\1>\s*';

        while (RegEx::match($regex, $string, $match))
        {
            $string = str_replace($match[0], $match[2], $string);
        }

        // Remove paragraphs around block elements
        $block_elements = [
            'p', 'div',
            'table', 'tr', 'td', 'thead', 'tfoot',
            'h[1-6]',
        ];
        $block_elements = '(' . implode('|', $block_elements) . ')';

        $regex = '(<p(?: [^>]*)?>)(\s*' . $breaks . ')(<' . $block_elements . '(?: [^>]*)?>)';

        while (RegEx::match($regex, $string, $match))
        {
            if ($match[4] == 'p')
            {
                $match[3] = $match[1] . $match[3];
                self::combinePTags($match[3]);
            }

            $string = str_replace($match[0], $match[2] . $match[3], $string);
        }

        $regex = '(</' . $block_elements . '>\s*' . $breaks . ')</p>';

        while (RegEx::match($regex, $string, $match))
        {
            $string = str_replace($match[0], $match[1], $string);
        }

        Protect::unprotect($string);
        $parts = explode(':|:', $string);

        $new_tags = [];

        foreach ($parts as $key => $val)
        {
            $key            = $keys[$key] ?? $key;
            $new_tags[$key] = $val;
        }

        return $new_tags;
    }

    /**
     * Combine duplicate <p> tags
     * input: <p class="aaa" a="1"><!-- ... --><p class="bbb" b="2">
     * output: <p class="aaa bbb" a="1" b="2"><!-- ... -->
     *
     * @param $string
     */
    public static function combinePTags(&$string)
    {
        if (empty($string))
        {
            return;
        }

        $p_start_tag   = '<p(?: [^>]*)?>';
        $optional_tags = '\s*(?:<\!--[^>]*-->|&nbsp;|&\#160;)*\s*';

        Protect::protectHtmlCommentTags($string);

        RegEx::matchAll('(' . $p_start_tag . ')(' . $optional_tags . ')(' . $p_start_tag . ')', $string, $tags);

        if (empty($tags))
        {

            Protect::unprotect($string);

            return;
        }

        foreach ($tags as $tag)
        {
            $string = str_replace($tag[0], $tag[2] . HtmlTag::combine($tag[1], $tag[3]), $string);
        }

        Protect::unprotect($string);
    }

    /**
     * Check if string contains block elements
     *
     * @param string $string
     *
     * @return string
     */
    public static function containsBlockElements($string)
    {
        return RegEx::match('</?(' . implode('|', self::getBlockElements()) . ')(?: [^>]*)?>', $string);
    }

    /**
     * Convert content saved in a WYSIWYG editor to plain text (like removing html tags)
     *
     * @param $string
     *
     * @return string
     */
    public static function convertWysiwygToPlainText($string)
    {
        // replace chr style enters with normal enters
        $string = str_replace([chr(194) . chr(160), '&#160;', '&nbsp;'], ' ', $string);

        // replace linebreak tags with normal linebreaks (paragraphs, enters, etc).
        $enter_tags = ['p', 'br'];
        $regex      = '</?((' . implode(')|(', $enter_tags) . '))+[^>]*?>\n?';
        $string     = RegEx::replace($regex, " \n", $string);

        // replace indent characters with spaces
        $string = RegEx::replace('<img [^>]*/sourcerer/images/tab\.png[^>]*>', '    ', $string);

        // strip all other tags
        $regex  = '<(/?\w+((\s+\w+(\s*=\s*(?:".*?"|\'.*?\'|[^\'">\s]+))?)+\s*|\s*)/?)>';
        $string = RegEx::replace($regex, '', $string);

        // reset htmlentities
        $string = StringHelper::html_entity_decoder($string);

        // convert protected html entities &_...; -> &...;
        $string = RegEx::replace('&_([a-z0-9\#]+?);', '&\1;', $string);

        return $string;
    }

    /**
     * Fix broken/invalid html syntax in a string
     *
     * @param string $string
     *
     * @return string
     */
    public static function fix($string)
    {
        if ( ! self::containsBlockElements($string))
        {
            return $string;
        }

        // Convert utf8 characters to html entities
        if (function_exists('mb_convert_encoding'))
        {
            $string = mb_convert_encoding($string, 'html-entities', 'utf-8');
        }

        $string = self::protectSpecialCode($string);

        $string = self::convertDivsInsideInlineElementsToSpans($string);
        $string = self::removeParagraphsAroundBlockElements($string);
        $string = self::removeInlineElementsAroundBlockElements($string);
        $string = self::fixParagraphsAroundParagraphElements($string);

        $string = class_exists('DOMDocument')
            ? self::fixUsingDOMDocument($string)
            : self::fixUsingCustomFixer($string);

        $string = self::unprotectSpecialCode($string);

        // Convert html entities back to utf8 characters
        if (function_exists('mb_convert_encoding'))
        {
            // Make sure &lt; and &gt; don't get converted
            $string = str_replace(['&lt;', '&gt;'], ['&amp;lt;', '&amp;gt;'], $string);

            $string = mb_convert_encoding($string, 'utf-8', 'html-entities');
        }

        $string = self::removeParagraphsAroundComments($string);

        return $string;
    }

    /**
     * Fix broken/invalid html syntax in an array of strings
     *
     * @param array $array
     *
     * @return array
     */
    public static function fixArray($array)
    {
        $splitter = ':|:';

        $string = self::fix(implode($splitter, $array));

        $parts = self::removeEmptyTags(explode($splitter, $string));

        // use original keys but new values
        return array_combine(array_keys($array), $parts);
    }

    /**
     * Return an array of block element names, optionally without any of the names given $exclude
     *
     * @param array $exclude
     *
     * @return array
     */
    public static function getBlockElements($exclude = [])
    {
        if ( ! is_array($exclude))
        {
            $exclude = [$exclude];
        }

        $elements = [
            'div', 'p', 'pre',
            'h1', 'h2', 'h3', 'h4', 'h5', 'h6',
        ];

        $elements = array_diff($elements, $exclude);

        $elements = implode(',', $elements);
        $elements = str_replace('h1,h2,h3,h4,h5,h6', 'h[1-6]', $elements);
        $elements = explode(',', $elements);

        return $elements;
    }

    /**
     * Return an array of block element names, without divs and any of the names given $exclude
     *
     * @param array $exclude
     *
     * @return array
     */
    public static function getBlockElementsNoDiv($exclude = [])
    {
        return array_diff(self::getBlockElements($exclude), ['div']);
    }

    /**
     * Extract the <body>...</body> part from an entire html output string
     *
     * @param string $html
     *
     * @return array
     */
    public static function getBody($html, $include_body_tag = true)
    {
        if (strpos($html, '<body') === false || strpos($html, '</body>') === false)
        {
            return ['', $html, ''];
        }

        // Force string to UTF-8
        $html = StringHelper::co