<?php

// SPDX-FileCopyrightText: 2018-2026 Ovation S.r.l. <help@dynamic.ooo>
// SPDX-License-Identifier: GPL-3.0-or-later
namespace DynamicContentForElementor;

trait Strings
{
    /**
     * Custom Function for Remove Specific Tag in the string.
     */
    public static function strip_tag($string, $tag)
    {
        $string = \preg_replace('/<' . $tag . '[^>]*>/i', '', $string);
        $string = \preg_replace('/<\\/' . $tag . '>/i', '', $string);
        return $string;
    }
    /**
     * String to Array
     *
     * Converts a string into an array based on a specified delimiter, applies the trim function to each element,
     * removes empty elements from the array, and optionally applies a formatting function to each element.
     *
     * @param string $delimiter The delimiter used to split the string into elements. Defaults to a comma (',').
     * @param string|array<mixed> $string The input string to be split. If an array is passed, it is returned directly without modifications.
     * @param callable|null $format An optional callback function to apply to each element of the array. If null, no formatting is applied.
     * @return array An array of elements derived from the input string, with whitespace trimmed from each element and empty elements removed.
     *               If a format function is specified, each element will also be formatted accordingly.
     */
    public static function str_to_array($delimiter = ',', $string = '', $format = null)
    {
        if (\is_array($string)) {
            return $string;
        }
        $pieces = \explode($delimiter, $string);
        $pieces = \array_filter(\array_map('trim', $pieces), function ($value) {
            return $value !== '';
        });
        if ($format) {
            $pieces = \array_map($format, $pieces);
        }
        return $pieces;
    }
    /**
     * Convert a value to a readable string
     *
     * @param mixed $avalue
     * @param boolean $listed
     * @return string
     */
    public static function to_readable_string($avalue, $listed = \false)
    {
        if (!\is_array($avalue) && !\is_object($avalue)) {
            return (string) $avalue;
        }
        if ($avalue instanceof \WP_Term) {
            return esc_html($avalue->name);
        }
        if ($avalue instanceof \WP_Post) {
            return esc_html($avalue->post_title);
        }
        if ($avalue instanceof \WP_User) {
            return esc_html($avalue->display_name);
        }
        if (\is_object($avalue)) {
            $avalue = (array) $avalue;
        }
        if (isset($avalue['post_title'])) {
            return esc_html($avalue['post_title']);
        }
        if (isset($avalue['display_name'])) {
            return esc_html($avalue['display_name']);
        }
        if (isset($avalue['name'])) {
            return esc_html($avalue['name']);
        }
        if (\count($avalue) == 1) {
            $first = \reset($avalue);
            return self::to_readable_string($first);
        }
        return self::implode_recursive(', ', $avalue, $listed);
    }
    public static function vc_strip_shortcodes($content)
    {
        $tmp = $content;
        $tags = array('[/vc_', '[vc_', '[dt_', '[interactive_banner_2');
        foreach ($tags as $atag) {
            $parts = \explode($atag, $tmp);
            if (\count($parts) > 1) {
                $content_mod = '';
                foreach ($parts as $key => $value) {
                    $altro = \explode(']', $value, 2);
                    $content_mod .= \end($altro);
                }
                $tmp = $content_mod;
            }
        }
        return $tmp;
    }
    public static function text_reduce($text, $length, $length_type, $finish)
    {
        $tokens = array();
        $out = '';
        $w = 0;
        // (<[^>]+>|[^<>\s]+\s*)
        \preg_match_all('/(<[^>]+>|[^<>\\s]+)\\s*/u', $text, $tokens);
        foreach ($tokens[0] as $t) {
            // Parse each token
            if ($w >= $length && 'sentence' != $finish) {
                // Limit reached
                break;
            }
            if ($t[0] != '<') {
                // Token is not a tag
                if ($w >= $length && 'sentence' == $finish && \preg_match('/[\\?\\.\\!]\\s*$/uS', $t) == 1) {
                    // Limit reached, continue until ? . or ! occur at the end
                    $out .= \trim($t);
                    break;
                }
                if ('words' == $length_type) {
                    // Count words
                    ++$w;
                } else {
                    // Count/trim characters
                    if ($finish == 'exact_w_spaces') {
                        $chars = $t;
                    } else {
                        $chars = \trim($t);
                    }
                    $c = \mb_strlen($chars);
                    if ($c + $w > $length && 'sentence' != $finish) {
                        // Token is too long
                        $c = 'word' == $finish ? $c : $length - $w;
                        // Keep token to finish word
                        $t = \substr($t, 0, $c);
                    }
                    $w += $c;
                }
            }
            // Append what's left of the token
            $out .= $t;
        }
        return \trim(force_balance_tags($out));
    }
    //+exclude_start
    public static function tablefy($html = '')
    {
        $dom = new \DynamicOOOS\PHPHtmlParser\Dom();
        $dom->loadStr($html);
        // A helper that, given a Tag instance and a new tag name, uses reflection
        // to override its protected $name property.
        $setTagName = function ($node, $newName) {
            $reflector = new \ReflectionClass($node);
            $prop = $reflector->getProperty('name');
            $prop->setAccessible(\true);
            $prop->setValue($node, $newName);
        };
        // Replace container ➔ table
        foreach ($dom->find('.elementor-container') as $wrapper) {
            $setTagName($wrapper->tag, 'table');
        }
        // Replace row ➔ tr
        foreach ($dom->find('.elementor-row') as $row) {
            $setTagName($row->tag, 'tr');
        }
        // Replace column ➔ td
        foreach ($dom->find('.elementor-column') as $col) {
            $setTagName($col->tag, 'td');
        }
        return (string) $dom;
    }
    //+exclude_end
    /**
     * Get Array Value by Keys
     *
     * Retrieves a value from a multidimensional array using a sequence of keys.
     *
     * This function iterates through a given array using a set of keys to find a specific value.
     * If any key in the sequence does not exist at the current level of the array, the function
     * returns false. This method avoids recursion for improved efficiency and simplicity.
     *
     * @param array $array The array from which to retrieve the value. It can be a multidimensional array.
     * @param array $keys An array of keys representing the path to the desired value within the array.
     *                     Each key in sequence should correspond to the next level in the array structure.
     * @return mixed The value found at the end of the keys path within the array, or false if any key
     *               in the path does not exist.
     */
    public static function get_array_value_by_keys($array = array(), $keys = array())
    {
        foreach ($keys as $key) {
            if (isset($array[$key])) {
                $array = $array[$key];
            } else {
                return \false;
            }
        }
        return $array;
    }
    /**
     * Set Array Value by Keys
     *
     * Sets a value in a multidimensional array based on a specified path of keys.
     *
     * This function navigates through a given array using a series of keys and sets
     * a specified value at the end of this path. If any part of the path does not exist,
     * it is automatically created as a new array. This method avoids recursion by using
     * references to modify the original array directly, improving efficiency.
     *
     * @param array $array The array to modify. It can be modified in place if passed by reference.
     * @param array $keys An array of keys that define the path to the target location within the array.
     *                    Each key in sequence represents a level in the array structure.
     * @param mixed $value The value to set at the target location defined by the keys path. If the path
     *                     is empty, the function will simply return this value.
     * @return array The modified array with the new value set at the target location. If the initial
     *               array parameter is passed by reference, this will reflect the modifications.
     */
    public static function set_array_value_by_keys(array $array, $keys, $value)
    {
        if (!empty($keys)) {
            $key = \array_shift($keys);
            if (!isset($array[$key]) || !\is_array($array[$key])) {
                $array[$key] = array();
            }
            $array[$key] = self::set_array_value_by_keys($array[$key], $keys, $value);
            if (\is_null($array[$key]) && \is_null($value)) {
                unset($array[$key]);
            }
        } else {
            $array = $value;
        }
        return $array;
    }
    public static function implode_recursive($separator = ', ', $arrayvar = array(), $listed = \false)
    {
        $output = '';
        if (!empty($arrayvar) && \is_array($arrayvar)) {
            if ($listed) {
                $output .= '<ul>';
            }
            $i = 0;
            foreach ($arrayvar as $av) {
                if ($listed) {
                    $output .= '<li>';
                }
                if (\is_object($av)) {
                    $av = self::to_readable_string($av);
                }
                if (\is_array($av)) {
                    $output .= self::implode_recursive($separator, $av, $listed);
                    // Recursive Use of the Array
                } elseif ($i) {
                    $output .= $separator . $av;
                } else {
                    $output .= $av;
                }
                if ($listed) {
                    $output .= '</li>';
                }
                ++$i;
            }
            if ($listed) {
                $output .= '</ul>';
            }
        }
        return $output;
    }
}
