Completed
Push — master ( b5bb9d...38f7c0 )
by f
02:02
created

src/S.php (2 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
namespace morphos;
3
4
/**
5
 * Multibyte string helper
6
 */
7
class S
8
{
9
    /** @var string Encoding used for string manipulations */
10
    static protected $encoding;
11
12
    static protected $cyrillicAlphabet = [
13
        ['Ё', 'Й', 'Ц', 'У', 'К', 'Е', 'Н', 'Г', 'Ш', 'Щ', 'З', 'Х', 'Ъ', 'Ф', 'Ы', 'В', 'А', 'П', 'Р', 'О', 'Л', 'Д', 'Ж', 'Э', 'Я', 'Ч', 'С', 'М', 'И', 'Т', 'Ь', 'Б', 'Ю'],
14
        ['ё', 'й', 'ц', 'у', 'к', 'е', 'н', 'г', 'ш', 'щ', 'з', 'х', 'ъ', 'ф', 'ы', 'в', 'а', 'п', 'р', 'о', 'л', 'д', 'ж', 'э', 'я', 'ч', 'с', 'м', 'и', 'т', 'ь', 'б', 'ю'],
15
    ];
16
17
    /**
18
     * Sets encoding for all operations
19
     * @param string $encoding
20
     * @return bool
21
     */
22
    public static function setEncoding($encoding)
23
    {
24
        static::$encoding = $encoding;
25
    }
26
27
    /**
28
     * Returns encoding used for all operations
29
     * @return string
30
     */
31 1679
    public static function getEncoding()
32
    {
33 1679
        return static::$encoding ?: 'utf-8';
34
    }
35
36
    /**
37
     * Calculates count of characters in string.
38
     * @param $string
39
     * @return bool|int
40
     */
41 38
    public static function length($string)
42
    {
43 38
        if (function_exists('mb_strlen')) {
44 38
            return mb_strlen($string, static::getEncoding());
45
        }
46
47
        if (function_exists('iconv_strlen')) {
48
            return iconv_strlen($string, static::getEncoding());
49
        }
50
51
        return false;
52
    }
53
54
    /**
55
     * Slices string like python.
56
     * @param string $string
57
     * @param int $start
58
     * @param int|null $end
59
     * @return bool|string
60
     */
61 1416
    public static function slice($string, $start, $end = null)
62
    {
63 1416
        if ($end !== null) {
64 595
            $end -= $start;
65
        }
66
67 1416
        if (function_exists('mb_substr')) {
68 1416
            return mb_substr($string, $start, $end, static::getEncoding());
69
        }
70
71
        if (function_exists('iconv_substr')) {
72
            return iconv_substr($string, $start, $end ?: iconv_strlen($string), static::getEncoding());
73
        }
74
75
        return false;
76
    }
77
78
    /**
79
     * Lower case.
80
     * @param $string
81
     * @return bool|string
82
     */
83 1669 View Code Duplication
    public static function lower($string)
84
    {
85 1669
        if (function_exists('mb_strtolower')) {
86 1669
            return mb_strtolower($string, static::getEncoding());
87
        }
88
89
        return static::replaceByMap($string, static::$cyrillicAlphabet[0], static::$cyrillicAlphabet[1]);
0 ignored issues
show
Since replaceByMap() is declared private, calling it with static will lead to errors in possible sub-classes. You can either use self, or increase the visibility of replaceByMap() to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
}

public static function getSomeVariable()
{
    return static::getTemperature();
}

}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass {
      private static function getTemperature() {
        return "-182 °C";
    }
}

print YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
    }

    public static function getSomeVariable()
    {
        return self::getTemperature();
    }
}
Loading history...
90
    }
91
92
    /**
93
     * Upper case.
94
     * @param $string
95
     * @return bool|string
96
     */
97 208 View Code Duplication
    public static function upper($string)
98
    {
99 208
        if (function_exists('mb_strtoupper')) {
100 208
            return mb_strtoupper($string, static::getEncoding());
101
        }
102
103
        return static::replaceByMap($string, static::$cyrillicAlphabet[1], static::$cyrillicAlphabet[0]);
0 ignored issues
show
Since replaceByMap() is declared private, calling it with static will lead to errors in possible sub-classes. You can either use self, or increase the visibility of replaceByMap() to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
}

public static function getSomeVariable()
{
    return static::getTemperature();
}

}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass {
      private static function getTemperature() {
        return "-182 °C";
    }
}

print YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
    }

    public static function getSomeVariable()
    {
        return self::getTemperature();
    }
}
Loading history...
104
    }
105
106
    /**
107
     * Name case. (ex: Thomas, Lewis). Works properly with separated by '-' words
108
     * @param $string
109
     * @return bool|string
110
     */
111 206
    public static function name($string)
112
    {
113 206
        if (strpos($string, '-') !== false) {
114
            return implode('-', array_map([__CLASS__, __FUNCTION__], explode('-', $string)));
115
        }
116
117 206
        return self::upper(self::slice($string, 0, 1)).self::lower(self::slice($string, 1));
118
    }
119
120
    /**
121
     * multiple substr_count().
122
     * @param $string
123
     * @param array $chars
124
     * @return bool|int
125
     */
126
    public static function countChars($string, array $chars)
127
    {
128
        if (function_exists('mb_split')) {
129
            return count(mb_split('('.implode('|', $chars).')', $string)) - 1;
130
        }
131
132
        $counter = 0;
133
        foreach ($chars as $char) {
134
            $counter += substr_count($string, $char);
135
        }
136
        return $counter;
137
    }
138
139
    /**
140
     * @param string $string
141
     * @param string $char
142
     * @return bool|string
143
     */
144 9
    public static function findFirstPosition($string, $char)
145
    {
146 9
        if (function_exists('mb_strpos')) {
147 9
            return mb_strpos($string, $char, 0, static::getEncoding());
148
        }
149
150
        return strpos($string, $char);
151
    }
152
153
    /**
154
     * @param string $string
155
     * @param string $char
156
     * @return bool|string
157
     */
158 6
    public static function findLastPosition($string, $char)
159
    {
160 6
        if (function_exists('mb_strrpos')) {
161 6
            return mb_strrpos($string, $char, 0, static::getEncoding());
162
        }
163
164
        return strrpos($string, $char);
165
    }
166
167
    /**
168
     * @param $string
169
     * @param array $chars
170
     * @return bool|string
171
     */
172 46
    public static function findLastPositionForOneOfChars($string, array $chars)
173
    {
174 46
        if (function_exists('mb_strrpos')) {
175 46
            $last_position = false;
176 46
            foreach ($chars as $char) {
177 46
                if (($pos = mb_strrpos($string, $char, 0, static::getEncoding())) !== false) {
178 46
                    if ($pos > $last_position) {
179 46
                        $last_position = $pos;
180
                    }
181
                }
182
            }
183 46
            if ($last_position !== false) {
184 46
                return mb_substr($string, $last_position, null, static::getEncoding());
185
            }
186
            return false;
187
        }
188
189
        return false;
190
    }
191
192
    /**
193
     * @param $string
194
     * @param $substring
195
     * @param bool $caseSensetive
196
     * @param int $startOffset
197
     * @return string|false
198
     */
199 78
    public static function indexOf($string, $substring, $caseSensetive = false, $startOffset = 0)
200
    {
201 78
        if (function_exists('mb_stripos')) {
202 78
            return $caseSensetive
203
                ? mb_strpos($string, $substring, $startOffset, static::getEncoding())
204 78
                : mb_stripos($string, $substring, $startOffset, static::getEncoding());
205
        }
206
207
        return false;
208
    }
209
210
    /**
211
     * @param $string
212
     * @param $fromMap
213
     * @param $toMap
214
     * @return string
215
     */
216
    private static function replaceByMap($string, $fromMap, $toMap)
217
    {
218
        $encoding = static::getEncoding();
219
        if ($encoding !== 'utf-8')
220
            $string = iconv($encoding, 'utf-8', $string);
221
222
        $string = strtr($string, array_combine($fromMap, $toMap));
223
224
        if ($encoding !== 'utf-8')
225
            $string = iconv('utf-8', $encoding, $string);
226
227
        return $string;
228
    }
229
}
230