xref: /plugin/combo/ComboStrap/StringUtility.php (revision c3437056399326d621a01da73b649707fbb0ae69)
137748cd8SNickeau<?php
237748cd8SNickeau
337748cd8SNickeaunamespace ComboStrap;
437748cd8SNickeau
537748cd8SNickeau/**
637748cd8SNickeau * Class StringUtility
737748cd8SNickeau * @package ComboStrap
837748cd8SNickeau * A class with string utility
937748cd8SNickeau */
1037748cd8SNickeauclass StringUtility
1137748cd8SNickeau{
1237748cd8SNickeau
1337748cd8SNickeau
1437748cd8SNickeau    /**
1537748cd8SNickeau     * Generate a text with a max length of $length
1637748cd8SNickeau     * and add ... if above
1737748cd8SNickeau     * @param $myString
1837748cd8SNickeau     * @param $length
1937748cd8SNickeau     * @return string
2037748cd8SNickeau     */
211fa8c418SNickeau    static function truncateString($myString, $length): string
2237748cd8SNickeau    {
2337748cd8SNickeau
2437748cd8SNickeau        if (strlen($myString) > $length) {
2537748cd8SNickeau            $suffix = ' ...';
2637748cd8SNickeau            $myString = substr($myString, 0, ($length - 1) - strlen($suffix)) . $suffix;
2737748cd8SNickeau        }
2837748cd8SNickeau        return $myString;
2937748cd8SNickeau    }
3037748cd8SNickeau
3137748cd8SNickeau    /**
3237748cd8SNickeau     * @param $string
3337748cd8SNickeau     * @return string - the string without any carriage return
3437748cd8SNickeau     * Used to compare string without worrying about carriage return
3537748cd8SNickeau     */
3637748cd8SNickeau    public static function normalized($string)
3737748cd8SNickeau    {
3837748cd8SNickeau        return str_replace("\n", "", $string);
3937748cd8SNickeau    }
4037748cd8SNickeau
4137748cd8SNickeau    /**
4237748cd8SNickeau     * @param $needle
4337748cd8SNickeau     * @param $haystack
4437748cd8SNickeau     * @return bool
4537748cd8SNickeau     */
4637748cd8SNickeau    public static function contain($needle, $haystack)
4737748cd8SNickeau    {
4837748cd8SNickeau        $pos = strpos($haystack, $needle);
4937748cd8SNickeau        if ($pos === FALSE) {
5037748cd8SNickeau            return false;
5137748cd8SNickeau        } else {
5237748cd8SNickeau            return true;
5337748cd8SNickeau        }
5437748cd8SNickeau    }
5537748cd8SNickeau
5637748cd8SNickeau    public static function toString($value)
5737748cd8SNickeau    {
5837748cd8SNickeau        /**
5937748cd8SNickeau         * No transformation if it's a string
6037748cd8SNickeau         * var_export below is not idempotent
6137748cd8SNickeau         * ie \ would become \\
6237748cd8SNickeau         */
6337748cd8SNickeau        if (is_string($value)) {
6437748cd8SNickeau            return $value;
6537748cd8SNickeau        }
6637748cd8SNickeau
67*c3437056SNickeau        if (is_array($value)) {
6837748cd8SNickeau            $string = var_export($value, true);
6937748cd8SNickeau
7037748cd8SNickeau            // An array value gets command in var_export
7137748cd8SNickeau            $lastCharacterIndex = strlen($string) - 1;
7237748cd8SNickeau            if ($string[0] === "'" && $string[$lastCharacterIndex] === "'") {
7337748cd8SNickeau                $string = substr($string, 1, strlen($string) - 2);
7437748cd8SNickeau            }
7537748cd8SNickeau            return $string;
76*c3437056SNickeau        }
77*c3437056SNickeau
78*c3437056SNickeau        if (is_object($value)) {
79*c3437056SNickeau            if (method_exists($value, "__toString")) {
80*c3437056SNickeau                return strval($value);
81*c3437056SNickeau            } else {
82*c3437056SNickeau                return get_class($value);
83*c3437056SNickeau            }
84*c3437056SNickeau        }
85*c3437056SNickeau
86*c3437056SNickeau        if (is_numeric($value)) {
87*c3437056SNickeau            return strval($value);
88*c3437056SNickeau        }
89*c3437056SNickeau
90*c3437056SNickeau        if (is_bool($value)) {
91*c3437056SNickeau            return var_export($value, true);
92*c3437056SNickeau        }
93*c3437056SNickeau
94*c3437056SNickeau        $string = var_export($value, true);
95*c3437056SNickeau        LogUtility::msg("The type of the value ($string) is unknown and could not be properly cast to string", LogUtility::LVL_MSG_WARNING);
96*c3437056SNickeau        return $string;
9737748cd8SNickeau
9837748cd8SNickeau    }
9937748cd8SNickeau
10037748cd8SNickeau    /**
10137748cd8SNickeau     * Add an EOL if not present at the end of the string
10237748cd8SNickeau     * @param $doc
10337748cd8SNickeau     */
10437748cd8SNickeau    public static function addEolCharacterIfNotPresent(&$doc)
10537748cd8SNickeau    {
10637748cd8SNickeau        if ($doc[strlen($doc) - 1] != DOKU_LF) {
10737748cd8SNickeau            $doc .= DOKU_LF;
10837748cd8SNickeau        }
10937748cd8SNickeau    }
11037748cd8SNickeau
11137748cd8SNickeau    /**
11237748cd8SNickeau     * Delete the string from the end
11337748cd8SNickeau     * This is used generally to delete the previous opening tag of an header or a blockquote
11437748cd8SNickeau     * @param $doc
11537748cd8SNickeau     * @param $string
11637748cd8SNickeau     */
11737748cd8SNickeau    public static function rtrim(&$doc, $string)
11837748cd8SNickeau    {
11937748cd8SNickeau
12037748cd8SNickeau        /**
12137748cd8SNickeau         * We trim because in the process, we may get extra {@link DOKU_LF} at the end
12237748cd8SNickeau         */
12337748cd8SNickeau        $doc = trim($doc);
12437748cd8SNickeau        $string = trim($string);
12537748cd8SNickeau        $length = strlen($doc) - strlen($string);
12637748cd8SNickeau        if (substr($doc, $length) === $string) {
12737748cd8SNickeau            $doc = substr($doc, 0, $length);
12837748cd8SNickeau        }
12937748cd8SNickeau
13037748cd8SNickeau    }
13137748cd8SNickeau
13237748cd8SNickeau    /**
13337748cd8SNickeau     * Delete the string from the beginning
13437748cd8SNickeau     * This is used to delete a tag for instance
13537748cd8SNickeau     * @param $doc
13637748cd8SNickeau     * @param $string
13737748cd8SNickeau     */
13837748cd8SNickeau    public static function ltrim(&$doc, $string)
13937748cd8SNickeau    {
14037748cd8SNickeau
14137748cd8SNickeau        $doc = trim($doc);
14237748cd8SNickeau        $string = trim($string);
14337748cd8SNickeau        $length = strlen($string);
14437748cd8SNickeau        if (substr($doc, 0, $length) === $string) {
14537748cd8SNickeau            $doc = substr($doc, $length);
14637748cd8SNickeau        }
14737748cd8SNickeau
14837748cd8SNickeau    }
14937748cd8SNickeau
15037748cd8SNickeau    /**
15137748cd8SNickeau     * The word count does not take into account
15237748cd8SNickeau     * words with non-words characters such as < =
15337748cd8SNickeau     * Therefore the node <node> and attribute name=value are not taken in the count
15437748cd8SNickeau     * @param $text
15537748cd8SNickeau     * @return int the number of words
15637748cd8SNickeau     */
15737748cd8SNickeau    public static function getWordCount($text)
15837748cd8SNickeau    {
15937748cd8SNickeau        /**
16037748cd8SNickeau         * Delete the frontmatter
16137748cd8SNickeau         */
16237748cd8SNickeau        $text = preg_replace("/^---(json)?$.*^---$/Ums", "", $text);
16337748cd8SNickeau        /**
16437748cd8SNickeau         * New line for node
16537748cd8SNickeau         */
16637748cd8SNickeau        $text = str_replace("<", "\n<", $text);
16737748cd8SNickeau        $text = str_replace(">", ">\n", $text);
16837748cd8SNickeau        // \s shorthand for whitespace
16937748cd8SNickeau        // | the table and links are separated with a |
17037748cd8SNickeau        // / to take into account expression such as and/or
17137748cd8SNickeau        // /u for unicode support (https://www.php.net/manual/en/reference.pcre.pattern.modifiers.php)
17237748cd8SNickeau        $wordSeparator = '/[\s|\/]/u';
17337748cd8SNickeau        $preg_split = preg_split($wordSeparator, $text);
17437748cd8SNickeau        $wordsWithoutEmpty = array_filter($preg_split, 'self::isWord');
17537748cd8SNickeau        return count($wordsWithoutEmpty);
17637748cd8SNickeau    }
17737748cd8SNickeau
17837748cd8SNickeau    public static function normalize($expected)
17937748cd8SNickeau    {
18037748cd8SNickeau        $expected = preg_replace("/[\s]/", " ", $expected);
18137748cd8SNickeau        $expected = str_replace("  ", " ", $expected);
18237748cd8SNickeau        $expected = str_replace("  ", " ", $expected);
18337748cd8SNickeau        $expected = str_replace("  ", " ", $expected);
18437748cd8SNickeau        $expected = str_replace("  ", " ", $expected);
18537748cd8SNickeau        return trim($expected);
18637748cd8SNickeau
18737748cd8SNickeau    }
18837748cd8SNickeau
18937748cd8SNickeau    /**
19037748cd8SNickeau     * @param $text
19137748cd8SNickeau     * @return bool
19237748cd8SNickeau     */
19337748cd8SNickeau    public static function isWord($text)
19437748cd8SNickeau    {
19537748cd8SNickeau        if (empty($text)) {
19637748cd8SNickeau            return false;
19737748cd8SNickeau        }
19837748cd8SNickeau        /**
19937748cd8SNickeau         * We also allow `-` minus
20037748cd8SNickeau         *
20137748cd8SNickeau         * And because otherwise the words are not counted:
20237748cd8SNickeau         *   * `'` (used to highlight words)
20337748cd8SNickeau         *   * `[]` used in links
20437748cd8SNickeau         *   * `,` used at the end of a sentenct
20537748cd8SNickeau         */
20637748cd8SNickeau        $preg_match = preg_match("/^[\w\-'\]\[,]*$/u", $text);
20737748cd8SNickeau        return $preg_match == 1;
20837748cd8SNickeau    }
20937748cd8SNickeau
21037748cd8SNickeau    public static function match($subject, $pattern)
21137748cd8SNickeau    {
21237748cd8SNickeau        return preg_match("/$pattern/", $subject) === 1;
21337748cd8SNickeau    }
21437748cd8SNickeau
21537748cd8SNickeau    public static function endWiths($string, $suffix)
21637748cd8SNickeau    {
21737748cd8SNickeau        $suffixStartPosition = strlen($string) - strlen($suffix);
21837748cd8SNickeau        return strrpos($string, $suffix) === $suffixStartPosition;
21937748cd8SNickeau    }
22037748cd8SNickeau
22137748cd8SNickeau    public static function explodeAndTrim($string, $delimiter = ",")
22237748cd8SNickeau    {
22337748cd8SNickeau        return array_map('trim', explode($delimiter, $string));
22437748cd8SNickeau    }
22537748cd8SNickeau
22637748cd8SNickeau    public static function lastIndexOf($haystack, $needle)
22737748cd8SNickeau    {
22837748cd8SNickeau        /**
22937748cd8SNickeau         * strRpos
23037748cd8SNickeau         * and not strpos
23137748cd8SNickeau         */
23237748cd8SNickeau        return strrpos($haystack, $needle);
23337748cd8SNickeau    }
23437748cd8SNickeau
23537748cd8SNickeau    public static function startWiths($string, $prefix)
23637748cd8SNickeau    {
23737748cd8SNickeau        return strrpos($string, $prefix) === 0;
23837748cd8SNickeau    }
23937748cd8SNickeau
24037748cd8SNickeau}
241