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

S::lower()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8

Duplication

Lines 8
Ratio 100 %

Code Coverage

Tests 3
CRAP Score 2.0625

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 1
dl 8
loc 8
ccs 3
cts 4
cp 0.75
crap 2.0625
rs 10
c 0
b 0
f 0
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)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
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
Bug introduced by
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)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
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
Bug introduced by
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