shell bypass 403

UnknownSec Shell

: /home/bouloter/sms/app/Library/ [ drwxr-xr-x ]

name : SMSCounter.php
<?php

/**
 * Item Name: Ultimate SMS - Bulk SMS Application For Marketing
 * Author: Codeglen
 * Author URL: https://codecanyon.net/user/codeglen
 */

namespace App\Library;

use stdClass;

class SMSCounter
{

    /**
     * GSM 7BIT encoding name.
     *
     * @var string
     */
    const GSM_7BIT = 'GSM_7BIT';

    /**
     * GSM 7BIT Extended encoding name.
     *
     * @var string
     */
    const GSM_7BIT_EX = 'GSM_7BIT_EX';

    /**
     * UTF16 or UNICODE encoding name.
     *
     * @var string
     */
    const UTF16 = 'UTF16';

    /**
     * Message length for GSM 7 Bit charset.
     *
     * @var int
     */
    const GSM_7BIT_LEN = 160;

    /**
     * Message length for GSM 7 Bit charset with extended characters.
     *
     * @var int
     */
    const GSM_7BIT_EX_LEN = 160;

    /**
     * Message length for UTF16/Unicode charset.
     *
     * @var int
     */
    const UTF16_LEN = 70;

    /**
     * Message length for multipart message in GSM 7 Bit encoding.
     *
     * @var int
     */
    const GSM_7BIT_LEN_MULTIPART = 153;

    /**
     * Message length for multipart message in GSM 7 Bit encoding.
     *
     * @var int
     */
    const GSM_7BIT_EX_LEN_MULTIPART = 153;

    /**
     * Message length for multipart message in GSM 7 Bit encoding.
     *
     * @var int
     */
    const UTF16_LEN_MULTIPART = 67;

    /**
     * @return int[]
     */
    public function getGsm7bitMap(): array
    {
        return [
                10, 12, 13, 32, 33, 34, 35, 36,
                37, 38, 39, 40, 41, 42, 43, 44,
                45, 46, 47, 48, 49, 50, 51, 52,
                53, 54, 55, 56, 57, 58, 59, 60,
                61, 62, 63, 64, 65, 66, 67, 68,
                69, 70, 71, 72, 73, 74, 75, 76,
                77, 78, 79, 80, 81, 82, 83, 84,
                85, 86, 87, 88, 89, 90, 91, 92,
                93, 94, 95, 97, 98, 99, 100, 101,
                102, 103, 104, 105, 106, 107, 108,
                109, 110, 111, 112, 113, 114, 115,
                116, 117, 118, 119, 120, 121, 122,
                123, 124, 125, 126, 161, 163, 164,
                165, 167, 191, 196, 197, 198, 199,
                201, 209, 214, 216, 220, 223, 224,
                228, 229, 230, 232, 233, 236, 241,
                242, 246, 248, 249, 252, 915, 916,
                920, 923, 926, 928, 931, 934, 936,
                937, 8364,
        ];
    }

    /**
     * @return int[]
     */
    public function getAddedGsm7bitExMap(): array
    {
        return [12, 91, 92, 93, 94, 123, 124, 125, 126, 8364];
    }


    /**
     * @return array
     */
    public function getGsm7bitExMap(): array
    {
        return array_merge(
                $this->getGsm7bitMap(),
                $this->getAddedGsm7bitExMap()
        );
    }

    /**
     * @return int[]
     */
    public function getTurkishGsm7bitMap(): array
    {
        return [
                10, 12, 13, 32, 33, 34, 35, 36,
                37, 38, 39, 40, 41, 42, 43, 44,
                45, 46, 47, 48, 49, 50, 51, 52,
                53, 54, 55, 56, 57, 58, 59, 60,
                61, 62, 63, 64, 65, 66, 67, 68,
                69, 70, 71, 72, 73, 74, 75, 76,
                77, 78, 79, 80, 81, 82, 83, 84,
                85, 86, 87, 88, 89, 90, 91, 92,
                93, 94, 95, 97, 98, 99, 100, 101,
                102, 103, 104, 105, 106, 107, 108,
                109, 110, 111, 112, 113, 114, 115,
                116, 117, 118, 119, 120, 121, 122,
                123, 124, 125, 126, 163, 164, 165,
                167, 196, 197, 199, 201, 209, 214,
                220, 223, 224, 228, 229, 231, 233,
                241, 242, 246, 249, 252, 286, 287,
                304, 305, 350, 351, 915, 916, 920,
                923, 926, 928, 931, 934, 936, 937,
                8364,
        ];
    }

    /**
     * @return int[]
     */
    public function getAddedTurkishGsm7bitExMap(): array
    {
        return [12, 91, 92, 93, 94, 123, 124, 125, 126, 286, 287, 304, 305, 350, 351, 8364];
    }

    /**
     * @return int[]
     */
    public function getAddedSpanishGsm7bitExMap(): array
    {
        return [12, 91, 92, 93, 94, 123, 124, 125, 126, 193, 205, 211, 218, 225, 231, 237, 243, 250, 8364];
    }

    /**
     * @return int[]
     */
    public function getPortugueseGsm7bitMap(): array
    {
        return [
                10, 12, 13, 32, 33, 34, 35, 36,
                37, 38, 39, 40, 41, 42, 43, 44,
                45, 46, 47, 48, 49, 50, 51, 52,
                53, 54, 55, 56, 57, 58, 59, 60,
                61, 62, 63, 64, 65, 66, 67, 68,
                69, 70, 71, 72, 73, 74, 75, 76,
                77, 78, 79, 80, 81, 82, 83, 84,
                85, 86, 87, 88, 89, 90, 91, 92,
                93, 94, 95, 96, 97, 98, 99, 100,
                101, 102, 103, 104, 105, 106, 107, 108,
                109, 110, 111, 112, 113, 114, 115, 116,
                117, 118, 119, 120, 121, 122, 123, 124,
                125, 126, 163, 165, 167, 170, 186, 192,
                193, 194, 195, 199, 201, 202, 205, 211,
                212, 213, 218, 220, 224, 225, 226, 227,
                231, 233, 234, 237, 242, 243, 244, 245,
                250, 252, 915, 916, 920, 928, 931, 934,
                936, 937, 8364, 8734,
        ];
    }

    /**
     * @return int[]
     */
    public function getAddedPortugueseGsm7bitExMap(): array
    {
        return [
                12, 91, 92, 93, 94, 123, 124, 125,
                126, 193, 194, 195, 202, 205, 211, 212,
                213, 218, 225, 226, 227, 231, 234, 237,
                242, 243, 245, 250, 915, 920, 928, 931,
                934, 936, 937, 8364,
        ];
    }

    /**
     * Detects the encoding, Counts the characters, message length, remaining characters.
     *
     * @return stdClass Object with params encoding,length, per_message, remaining, messages
     */
    public function count($text): stdClass
    {
        return $this->doCount($text, false);
    }

    /**
     * Detects the encoding, Counts the characters, message length, remaining characters.
     * Supports language shift tables characters.
     *
     * @return stdClass Object with params encoding,length, per_message, remaining, messages
     */
    public function countWithShiftTables($text): stdClass
    {
        return $this->doCount($text, true);
    }

    /**
     * @return stdClass Object with params encoding,length, per_message, remaining, messages
     */
    private function doCount($text, $supportShiftTables): stdClass
    {
        $unicodeArray = $this->utf8ToUnicode($text);

        // variable to catch if any ex chars while encoding detection.
        $exChars  = [];
        $encoding = $supportShiftTables
                ? $this->detectEncodingWithShiftTables($text, $exChars)
                : $this->detectEncoding($text, $exChars);

        $length = count($unicodeArray);

        if ($encoding === self::GSM_7BIT_EX) {
            $lengthExtrachars = count($exChars);
            // Each exchar in the GSM 7 Bit encoding takes one more space
            // Hence the length increases by one char for each of those Ex chars.
            $length += $lengthExtrachars;
        } elseif ($encoding === self::UTF16) {
            // Unicode chars over U+10000 occupy an extra byte
            $lengthExtra = array_reduce(
                    $unicodeArray,
                    function ($carry, $char) {
                        if ($char >= 65536) {
                            $carry++;
                        }

                        return $carry;
                    },
                    0
            );

            $length += $lengthExtra;
        }

        // Select the per message length according to encoding and the message length
        switch ($encoding) {
            case self::GSM_7BIT:
                $perMessage = self::GSM_7BIT_LEN;
                if ($length > self::GSM_7BIT_LEN) {
                    $perMessage = self::GSM_7BIT_LEN_MULTIPART;
                }
                break;

            case self::GSM_7BIT_EX:
                $perMessage = self::GSM_7BIT_EX_LEN;
                if ($length > self::GSM_7BIT_EX_LEN) {
                    $perMessage = self::GSM_7BIT_EX_LEN_MULTIPART;
                }
                break;

            default:
                $perMessage = self::UTF16_LEN;
                if ($length > self::UTF16_LEN) {
                    $perMessage = self::UTF16_LEN_MULTIPART;
                }

                break;
        }

        $messages = (int) ceil($length / $perMessage);

        if ($encoding === self::UTF16 && $length > $perMessage) {
            $count = 0;
            foreach ($unicodeArray as $char) {
                if ($count === $perMessage) {
                    $count = 0;
                } elseif ($count > $perMessage) {
                    $count = 2;
                }

                $count += $char >= 65536 ? 2 : 1;
            }

            $remaining = $perMessage - ($count > $perMessage ? 2 : $count);
        } else {
            $remaining = ($perMessage * $messages) - $length;
        }

        $return_set = new stdClass();

        $return_set->encoding    = $encoding;
        $return_set->length      = $length;
        $return_set->per_message = $perMessage;
        $return_set->remaining   = $remaining;
        $return_set->messages    = $messages;

        return $return_set;
    }

    /**
     * Detects the encoding of a particular text.
     *
     * @return string (GSM_7BIT|GSM_7BIT_EX|UTF16)
     */
    public function detectEncoding($text, &$exChars): string
    {
        if ( ! is_array($text)) {
            $text = $this->utf8ToUnicode($text);
        }

        $utf16Chars = array_diff($text, $this->getGsm7bitExMap());
        if (count($utf16Chars)) {
            return self::UTF16;
        }

        $exChars = array_intersect($text, $this->getAddedGsm7bitExMap());
        if (count($exChars)) {
            return self::GSM_7BIT_EX;
        }

        return self::GSM_7BIT;
    }

    /**
     * Detects the encoding of a particular text.
     * Supports language shift tables characters.
     *
     * @return string (GSM_7BIT|GSM_7BIT_EX|UTF16)
     */
    public function detectEncodingWithShiftTables($text, &$exChars): string
    {
        if ( ! is_array($text)) {
            $text = $this->utf8ToUnicode($text);
        }

        $gsmCharMap = array_merge(
                $this->getGsm7bitExMap(),
                $this->getTurkishGsm7bitMap(),
                $this->getAddedTurkishGsm7bitExMap(),
                $this->getAddedSpanishGsm7bitExMap(),
                $this->getPortugueseGsm7bitMap(),
                $this->getAddedPortugueseGsm7bitExMap()
        );

        $utf16Chars = array_diff($text, $gsmCharMap);
        if (count($utf16Chars)) {
            return self::UTF16;
        }

        $addedGsmCharMap = array_merge(
                $this->getAddedGsm7bitExMap(),
                $this->getAddedTurkishGsm7bitExMap(),
                $this->getAddedSpanishGsm7bitExMap(),
                $this->getAddedPortugueseGsm7bitExMap()
        );

        $exChars = array_intersect($text, $addedGsmCharMap);
        if (count($exChars)) {
            return self::GSM_7BIT_EX;
        }

        return self::GSM_7BIT;
    }

    /**
     * Generates array of unicode points for the utf8 string.
     *
     * @param $str
     *
     * @return array
     */
    public function utf8ToUnicode($str): array
    {
        $unicode    = [];
        $values     = [];
        $lookingFor = 1;
        $len        = strlen($str);

        for ($i = 0; $i < $len; $i++) {
            $thisValue = ord($str[$i]);

            if ($thisValue < 128) {
                $unicode[] = $thisValue;
            }

            if ($thisValue >= 128) {
                if (count($values) === 0) {
                    $lookingFor = 2;

                    if ($thisValue >= 240) {
                        $lookingFor = 4;
                    } elseif ($thisValue >= 224) {
                        $lookingFor = 3;
                    }
                }

                $values[] = $thisValue;

                if (count($values) === $lookingFor) {
                    switch ($lookingFor) {
                        case 4:
                            $number = (($values[0] % 16) * 262144) + (($values[1] % 64) * 4096) + (($values[2] % 64) * 64) + ($values[3] % 64);
                            break;

                        case 3:
                            $number = (($values[0] % 16) * 4096) + (($values[1] % 64) * 64) + ($values[2] % 64);
                            break;

                        case 2:
                            $number = (($values[0] % 32) * 64) + ($values[1] % 64);
                            break;
                    }

                    /** @var TYPE_NAME $number */
                    $unicode[]  = $number;
                    $values     = [];
                    $lookingFor = 1;
                }
            }
        }

        return $unicode;
    }

    /**
     * Unicode equivalent chr() function.
     *
     * @return string characters
     */
    public function utf8Chr($unicode): string
    {
        $unicode = intval($unicode);

        $utf8char = chr(240 | ($unicode >> 18));
        $utf8char .= chr(128 | (($unicode >> 12) & 0x3F));
        $utf8char .= chr(128 | (($unicode >> 6) & 0x3F));
        $utf8char .= chr(128 | ($unicode & 0x3F));

        if ($unicode < 128) {
            $utf8char = chr($unicode);
        } elseif ($unicode >= 128 && $unicode < 2048) {
            $utf8char = chr(192 | ($unicode >> 6)).chr(128 | ($unicode & 0x3F));
        } elseif ($unicode >= 2048 && $unicode < 65536) {
            $utf8char = chr(224 | ($unicode >> 12)).chr(128 | (($unicode >> 6) & 0x3F)).chr(128 | ($unicode & 0x3F));
        }

        return $utf8char;
    }

    /**
     * Converts unicode code points array to a utf8 str.
     *
     * @param  array  $array  unicode codepoints array
     *
     * @return string utf8 encoded string
     */
    public function unicodeToUtf8($array): string
    {
        $str = '';
        foreach ($array as $a) {
            $str .= $this->utf8Chr($a);
        }

        return $str;
    }

    /**
     * Removes non GSM characters from a string.
     *
     * @return string
     */
    public function removeNonGsmChars($str)
    {
        return $this->replaceNonGsmChars($str);
    }

    /**
     * Replaces non GSM characters from a string.
     *
     * @param  string  $str  String to be replaced
     * @param  null  $replacement  String of characters to be replaced with
     *
     * @return false|string (string|false) if replacement string is more than 1 character
     *                        in length
     */
    public function replaceNonGsmChars($str, $replacement = null)
    {
        $validChars = $this->getGsm7bitExMap();
        $allChars   = $this->utf8ToUnicode($str);

        if (strlen($replacement) > 1) {
            return false;
        }

        $replacementArray   = [];
        $unicodeArray       = $this->utf8ToUnicode($replacement);
        $replacementUnicode = array_pop($unicodeArray);

        foreach ($allChars as $key => $char) {
            if ( ! in_array($char, $validChars)) {
                $replacementArray[] = $key;
            }
        }

        if ($replacement) {
            foreach ($replacementArray as $key) {
                $allChars[$key] = $replacementUnicode;
            }
        }

        if ( ! $replacement) {
            foreach ($replacementArray as $key) {
                unset($allChars[$key]);
            }
        }

        return $this->unicodeToUtf8($allChars);
    }

    /**
     * @param $str
     *
     * @return false|string
     */
    public function sanitizeToGSM($str)
    {
        $str = $this->removeAccents($str);

        return $this->removeNonGsmChars($str);
    }

    /**
     * @param  string  $str  Message text
     *
     * @return string Sanitized message text
     */
    public function removeAccents($str): string
    {
        if ( ! preg_match('/[\x80-\xff]/', $str)) {
            return $str;
        }

        $chars = [
            // Decompositions for Latin-1 Supplement
                'ª' => 'a', 'º' => 'o',
                'À' => 'A', 'Á' => 'A',
                'Â' => 'A', 'Ã' => 'A',
                'È' => 'E',
                'Ê' => 'E', 'Ë' => 'E',
                'Ì' => 'I', 'Í' => 'I',
                'Î' => 'I', 'Ï' => 'I',
                'Ð' => 'D',
                'Ò' => 'O', 'Ó' => 'O',
                'Ô' => 'O', 'Õ' => 'O',
                'Ù' => 'U',
                'Ú' => 'U', 'Û' => 'U',
                'Ý' => 'Y',
                'Þ' => 'TH',
                'á' => 'a',
                'â' => 'a', 'ã' => 'a',
                'ç' => 'c',
                'ê' => 'e', 'ë' => 'e',
                'í' => 'i',
                'î' => 'i', 'ï' => 'i',
                'ð' => 'd',
                'ó' => 'o',
                'ô' => 'o', 'õ' => 'o',
                'ú' => 'u',
                'û' => 'u',
                'ý' => 'y', 'þ' => 'th',
                'ÿ' => 'y',
            // Decompositions for Latin Extended-A
                'Ā' => 'A', 'ā' => 'a',
                'Ă' => 'A', 'ă' => 'a',
                'Ą' => 'A', 'ą' => 'a',
                'Ć' => 'C', 'ć' => 'c',
                'Ĉ' => 'C', 'ĉ' => 'c',
                'Ċ' => 'C', 'ċ' => 'c',
                'Č' => 'C', 'č' => 'c',
                'Ď' => 'D', 'ď' => 'd',
                'Đ' => 'D', 'đ' => 'd',
                'Ē' => 'E', 'ē' => 'e',
                'Ĕ' => 'E', 'ĕ' => 'e',
                'Ė' => 'E', 'ė' => 'e',
                'Ę' => 'E', 'ę' => 'e',
                'Ě' => 'E', 'ě' => 'e',
                'Ĝ' => 'G', 'ĝ' => 'g',
                'Ğ' => 'G', 'ğ' => 'g',
                'Ġ' => 'G', 'ġ' => 'g',
                'Ģ' => 'G', 'ģ' => 'g',
                'Ĥ' => 'H', 'ĥ' => 'h',
                'Ħ' => 'H', 'ħ' => 'h',
                'Ĩ' => 'I', 'ĩ' => 'i',
                'Ī' => 'I', 'ī' => 'i',
                'Ĭ' => 'I', 'ĭ' => 'i',
                'Į' => 'I', 'į' => 'i',
                'İ' => 'I', 'ı' => 'i',
                'IJ' => 'IJ', 'ij' => 'ij',
                'Ĵ' => 'J', 'ĵ' => 'j',
                'Ķ' => 'K', 'ķ' => 'k',
                'ĸ' => 'k', 'Ĺ' => 'L',
                'ĺ' => 'l', 'Ļ' => 'L',
                'ļ' => 'l', 'Ľ' => 'L',
                'ľ' => 'l', 'Ŀ' => 'L',
                'ŀ' => 'l', 'Ł' => 'L',
                'ł' => 'l', 'Ń' => 'N',
                'ń' => 'n', 'Ņ' => 'N',
                'ņ' => 'n', 'Ň' => 'N',
                'ň' => 'n', 'ʼn' => 'n',
                'Ŋ' => 'N', 'ŋ' => 'n',
                'Ō' => 'O', 'ō' => 'o',
                'Ŏ' => 'O', 'ŏ' => 'o',
                'Ő' => 'O', 'ő' => 'o',
                'Œ' => 'OE', 'œ' => 'oe',
                'Ŕ' => 'R', 'ŕ' => 'r',
                'Ŗ' => 'R', 'ŗ' => 'r',
                'Ř' => 'R', 'ř' => 'r',
                'Ś' => 'S', 'ś' => 's',
                'Ŝ' => 'S', 'ŝ' => 's',
                'Ş' => 'S', 'ş' => 's',
                'Š' => 'S', 'š' => 's',
                'Ţ' => 'T', 'ţ' => 't',
                'Ť' => 'T', 'ť' => 't',
                'Ŧ' => 'T', 'ŧ' => 't',
                'Ũ' => 'U', 'ũ' => 'u',
                'Ū' => 'U', 'ū' => 'u',
                'Ŭ' => 'U', 'ŭ' => 'u',
                'Ů' => 'U', 'ů' => 'u',
                'Ű' => 'U', 'ű' => 'u',
                'Ų' => 'U', 'ų' => 'u',
                'Ŵ' => 'W', 'ŵ' => 'w',
                'Ŷ' => 'Y', 'ŷ' => 'y',
                'Ÿ' => 'Y', 'Ź' => 'Z',
                'ź' => 'z', 'Ż' => 'Z',
                'ż' => 'z', 'Ž' => 'Z',
                'ž' => 'z', 'ſ' => 's',
            // Decompositions for Latin Extended-B
                'Ș' => 'S', 'ș' => 's',
                'Ț' => 'T', 'ț' => 't',
            // Vowels with diacritic (Vietnamese)
            // unmarked
                'Ơ' => 'O', 'ơ' => 'o',
                'Ư' => 'U', 'ư' => 'u',
            // grave accent
                'Ầ' => 'A', 'ầ' => 'a',
                'Ằ' => 'A', 'ằ' => 'a',
                'Ề' => 'E', 'ề' => 'e',
                'Ồ' => 'O', 'ồ' => 'o',
                'Ờ' => 'O', 'ờ' => 'o',
                'Ừ' => 'U', 'ừ' => 'u',
                'Ỳ' => 'Y', 'ỳ' => 'y',
            // hook
                'Ả' => 'A', 'ả' => 'a',
                'Ẩ' => 'A', 'ẩ' => 'a',
                'Ẳ' => 'A', 'ẳ' => 'a',
                'Ẻ' => 'E', 'ẻ' => 'e',
                'Ể' => 'E', 'ể' => 'e',
                'Ỉ' => 'I', 'ỉ' => 'i',
                'Ỏ' => 'O', 'ỏ' => 'o',
                'Ổ' => 'O', 'ổ' => 'o',
                'Ở' => 'O', 'ở' => 'o',
                'Ủ' => 'U', 'ủ' => 'u',
                'Ử' => 'U', 'ử' => 'u',
                'Ỷ' => 'Y', 'ỷ' => 'y',
            // tilde
                'Ẫ' => 'A', 'ẫ' => 'a',
                'Ẵ' => 'A', 'ẵ' => 'a',
                'Ẽ' => 'E', 'ẽ' => 'e',
                'Ễ' => 'E', 'ễ' => 'e',
                'Ỗ' => 'O', 'ỗ' => 'o',
                'Ỡ' => 'O', 'ỡ' => 'o',
                'Ữ' => 'U', 'ữ' => 'u',
                'Ỹ' => 'Y', 'ỹ' => 'y',
            // acute accent
                'Ấ' => 'A', 'ấ' => 'a',
                'Ắ' => 'A', 'ắ' => 'a',
                'Ế' => 'E', 'ế' => 'e',
                'Ố' => 'O', 'ố' => 'o',
                'Ớ' => 'O', 'ớ' => 'o',
                'Ứ' => 'U', 'ứ' => 'u',
            // dot below
                'Ạ' => 'A', 'ạ' => 'a',
                'Ậ' => 'A', 'ậ' => 'a',
                'Ặ' => 'A', 'ặ' => 'a',
                'Ẹ' => 'E', 'ẹ' => 'e',
                'Ệ' => 'E', 'ệ' => 'e',
                'Ị' => 'I', 'ị' => 'i',
                'Ọ' => 'O', 'ọ' => 'o',
                'Ộ' => 'O', 'ộ' => 'o',
                'Ợ' => 'O', 'ợ' => 'o',
                'Ụ' => 'U', 'ụ' => 'u',
                'Ự' => 'U', 'ự' => 'u',
                'Ỵ' => 'Y', 'ỵ' => 'y',
            // Vowels with diacritic (Chinese, Hanyu Pinyin)
                'ɑ' => 'a',
            // macron
                'Ǖ' => 'U', 'ǖ' => 'u',
            // acute accent
                'Ǘ' => 'U', 'ǘ' => 'u',
            // caron
                'Ǎ' => 'A', 'ǎ' => 'a',
                'Ǐ' => 'I', 'ǐ' => 'i',
                'Ǒ' => 'O', 'ǒ' => 'o',
                'Ǔ' => 'U', 'ǔ' => 'u',
                'Ǚ' => 'U', 'ǚ' => 'u',
            // grave accent
                'Ǜ' => 'U', 'ǜ' => 'u',
            // spaces
                ' ' => ' ', ' ' => ' ',
        ];

        return strtr($str, $chars);
    }

    /**
     * Truncated to the limit of chars allowed by number of SMS. It will detect
     * the encoding an multipart limits to apply the truncate.
     *
     * @param  string  $str  Message text
     * @param  int  $limitSms  Number of SMS allowed
     *
     * @return string Truncated message
     */
    public function truncate($str, $limitSms): string
    {
        return $this->doTruncate($str, $limitSms, false);
    }

    /**
     * Truncated to the limit of chars allowed by number of SMS. It will detect
     * the encoding an multipart limits to apply the truncate.
     * Supports language shift tables characters.
     *
     * @param  string  $str  Message text
     * @param  int  $limitSms  Number of SMS allowed
     *
     * @return string Truncated message
     */
    public function truncateWithShiftTables($str, $limitSms): string
    {
        return $this->doTruncate($str, $limitSms, true);
    }

    /**
     * @return string Truncated message
     */
    private function doTruncate($str, $limitSms, $supportShiftTables): string
    {
        $count = $supportShiftTables
                ? $this->countWithShiftTables($str)
                : $this->count($str);

        if ($count->messages <= $limitSms) {
            return $str;
        }

        if ($count->encoding === 'UTF16') {
            $limit = self::UTF16_LEN;

            if ($limitSms > 2) {
                $limit = self::UTF16_LEN_MULTIPART;
            }
        } else {
            $limit = self::GSM_7BIT_LEN;

            if ($limitSms > 2) {
                $limit = self::GSM_7BIT_LEN_MULTIPART;
            }
        }

        do {
            $str   = mb_substr($str, 0, $limit * $limitSms);
            $count = $supportShiftTables
                    ? $this->countWithShiftTables($str)
                    : $this->count($str);

            $limit = $limit - 1;
        } while ($count->messages > $limitSms);

        return $str;
    }
}

© 2025 UnknownSec
afwwrfwafr45458465
Password