S   A
last analyzed

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 1739
    public static function getEncoding()
32
    {
33 1739
        return static::$encoding ?: 'utf-8';
34
    }
35
36
    /**
37
     * Calculates count of characters in string.
38
     * @param $string
39
     * @return bool|int
40
     */
41 41
    public static function length($string)
42
    {
43 41
        if (function_exists('mb_strlen')) {
44 41
            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 1475
    public static function slice($string, $start, $end = null)
62
    {
63 1475
        if ($end !== null) {
64 643
            $end -= $start;
65
        }
66
67 1475
        if (function_exists('mb_substr')) {
68 1475
            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 1730 View Code Duplication
    public static function lower($string)
0 ignored issues
show
Duplication introduced by wapmorgan
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 1730
        if (function_exists('mb_strtolower')) {
86 1730
            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 wapmorgan
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 214 View Code Duplication
    public static function upper($string)
0 ignored issues
show
Duplication introduced by wapmorgan
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 214
        if (function_exists('mb_strtoupper')) {
100 214
            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 wapmorgan
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 212
    public static function name($string)
112
    {
113 212
        if (strpos($string, '-') !== false) {
114
            return implode('-', array_map([__CLASS__, __FUNCTION__], explode('-', $string)));
115
        }
116
117 212
        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 73
    public static function findLastPositionForOneOfChars($string, array $chars)
173
    {
174 73
        if (function_exists('mb_strrpos')) {
175 73
            $last_position = false;
176 73
            foreach ($chars as $char) {
177 73
                if (($pos = mb_strrpos($string, $char, 0, static::getEncoding())) !== false) {
178 73
                    if ($pos > $last_position) {
179 73
                        $last_position = $pos;
180
                    }
181
                }
182
            }
183 73
            if ($last_position !== false) {
184 73
                return mb_substr($string, $last_position, null, static::getEncoding());
185
            }
186 13
            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 90
    public static function indexOf($string, $substring, $caseSensetive = false, $startOffset = 0)
200
    {
201 90
        if (function_exists('mb_stripos')) {
202 90
            return $caseSensetive
203
                ? mb_strpos($string, $substring, $startOffset, static::getEncoding())
204 90
                : 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