Completed
Push — master ( 18bbe5...4b1809 )
by f
01:51
created

S   A

Complexity

Total Complexity 36

Size/Duplication

Total Lines 223
Duplicated Lines 7.17 %

Coupling/Cohesion

Components 1
Dependencies 0

Test Coverage

Coverage 54.93%

Importance

Changes 0
Metric Value
dl 16
loc 223
ccs 39
cts 71
cp 0.5493
rs 9.52
c 0
b 0
f 0
wmc 36
lcom 1
cbo 0

13 Methods

Rating   Name   Duplication   Size   Complexity  
A setEncoding() 0 4 1
A getEncoding() 0 4 2
A length() 0 12 3
A slice() 0 16 5
A lower() 8 8 2
A upper() 8 8 2
A name() 0 8 2
A countChars() 0 12 3
A findFirstPosition() 0 8 2
A findLastPosition() 0 8 2
A indexOf() 0 10 3
A replaceByMap() 0 13 3
A findLastPositionForOneOfChars() 0 19 6

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

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 1754
    public static function getEncoding()
32
    {
33 1754
        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 1490
    public static function slice($string, $start, $end = null)
62
    {
63 1490
        if ($end !== null) {
64 622
            $end -= $start;
65
        }
66
67 1490
        if (function_exists('mb_substr')) {
68 1490
            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 1746 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 1746
        if (function_exists('mb_strtolower')) {
86 1746
            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 static::upper(static::slice($string, 0, 1)).static::lower(static::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 65
    public static function findLastPositionForOneOfChars($string, array $chars)
173
    {
174 65
        if (function_exists('mb_strrpos')) {
175 65
            $last_position = false;
176 65
            foreach ($chars as $char) {
177 65
                if (($pos = mb_strrpos($string, $char, 0, static::getEncoding())) !== false) {
178 65
                    if ($pos > $last_position) {
179 65
                        $last_position = $pos;
180
                    }
181
                }
182
            }
183 65
            if ($last_position !== false) {
184 65
                return mb_substr($string, $last_position, null, static::getEncoding());
185
            }
186 10
            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 83
    public static function indexOf($string, $substring, $caseSensetive = false, $startOffset = 0)
200
    {
201 83
        if (function_exists('mb_stripos')) {
202 83
            return $caseSensetive
203
                ? mb_strpos($string, $substring, $startOffset, static::getEncoding())
204 83
                : 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