Passed
Push — main ( ac46d3...40b327 )
by Diego
03:35
created

Inflect::singularize()   B

Complexity

Conditions 8
Paths 8

Size

Total Lines 24
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
eloc 10
nc 8
nop 1
dl 0
loc 24
rs 8.4444
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Blackmine\Tool;
6
7
class Inflect
8
{
9
    public const GETTER_PREFIX = "get";
10
    public const SETTER_PREFIX = "set";
11
    public const ISSER_PREFIX = "is";
12
    public const ADDER_PREFIX = "add";
13
    public const REMOVER_PREFIX = "remove";
14
15
    public static array $plural = array(
16
        '/(quiz)$/i' => "$1zes",
17
        '/^(ox)$/i' => "$1en",
18
        '/([m|l])ouse$/i' => "$1ice",
19
        '/(matr|vert|ind)ix|ex$/i' => "$1ices",
20
        '/(x|ch|ss|sh)$/i' => "$1es",
21
        '/([^aeiouy]|qu)y$/i' => "$1ies",
22
        '/(hive)$/i' => "$1s",
23
        '/(?:([^f])fe|([lr])f)$/i' => "$1$2ves",
24
        '/(shea|lea|loa|thie)f$/i' => "$1ves",
25
        '/sis$/i' => "ses",
26
        '/([ti])um$/i' => "$1a",
27
        '/(tomat|potat|ech|her|vet)o$/i' => "$1oes",
28
        '/(bu)s$/i' => "$1ses",
29
        '/(alias)$/i' => "$1es",
30
        '/(octop)us$/i' => "$1i",
31
        '/(ax|test)is$/i' => "$1es",
32
        '/(us)$/i' => "$1es",
33
        '/s$/i' => "s",
34
        '/$/' => "s"
35
    );
36
37
    public static array $singular = array(
38
        '/(quiz)zes$/i' => "$1",
39
        '/(matr)ices$/i' => "$1ix",
40
        '/(vert|ind)ices$/i' => "$1ex",
41
        '/^(ox)en$/i' => "$1",
42
        '/(alias)es$/i' => "$1",
43
        '/(octop|vir)i$/i' => "$1us",
44
        '/(cris|ax|test)es$/i' => "$1is",
45
        '/(shoe)s$/i' => "$1",
46
        '/(o)es$/i' => "$1",
47
        '/(bus)es$/i' => "$1",
48
        '/([m|l])ice$/i' => "$1ouse",
49
        '/(x|ch|ss|sh)es$/i' => "$1",
50
        '/(m)ovies$/i' => "$1ovie",
51
        '/(s)eries$/i' => "$1eries",
52
        '/([^aeiouy]|qu)ies$/i' => "$1y",
53
        '/([lr])ves$/i' => "$1f",
54
        '/(tive)s$/i' => "$1",
55
        '/(hive)s$/i' => "$1",
56
        '/(li|wi|kni)ves$/i' => "$1fe",
57
        '/(shea|loa|lea|thie)ves$/i' => "$1f",
58
        '/(^analy)ses$/i' => "$1sis",
59
        '/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i' => "$1$2sis",
60
        '/([ti])a$/i' => "$1um",
61
        '/(n)ews$/i' => "$1ews",
62
        '/(h|bl)ouses$/i' => "$1ouse",
63
        '/(corpse)s$/i' => "$1",
64
        '/(us)es$/i' => "$1",
65
        '/s$/i' => ""
66
    );
67
68
    public static array $irregular = array(
69
        'move' => 'moves',
70
        'foot' => 'feet',
71
        'goose' => 'geese',
72
        'sex' => 'sexes',
73
        'child' => 'children',
74
        'man' => 'men',
75
        'tooth' => 'teeth',
76
        'person' => 'people',
77
        'valve' => 'valves'
78
    );
79
80
    public static array $uncountable = array(
81
        'sheep',
82
        'fish',
83
        'deer',
84
        'series',
85
        'species',
86
        'money',
87
        'rice',
88
        'information',
89
        'equipment'
90
    );
91
92
    public static function pluralize($string): string
93
    {
94
        // save some time in the case that singular and plural are the same
95
        if (in_array(strtolower($string), self::$uncountable, true)) {
96
            return $string;
97
        }
98
99
100
        // check for irregular singular forms
101
        foreach (self::$irregular as $pattern => $result) {
102
            $position = stripos(strtolower($string), $pattern[0]);
103
            $pattern = '/' . $pattern . '$/i';
104
105
            if (preg_match($pattern, $string)) {
106
                return preg_replace($pattern, ctype_upper($string[$position]) ? ucfirst($result) : $result, $string);
107
            }
108
        }
109
110
        // check for matches using regular expressions
111
        foreach (self::$plural as $pattern => $result) {
112
            if (preg_match($pattern, $string)) {
113
                return preg_replace($pattern, ctype_upper($string[0]) ? ucfirst($result) : $result, $string);
114
            }
115
        }
116
117
        return $string;
118
    }
119
120
    public static function singularize($string): string
121
    {
122
        // save some time in the case that singular and plural are the same
123
        if (in_array(strtolower($string), self::$uncountable, true)) {
124
            return $string;
125
        }
126
127
        // check for irregular plural forms
128
        foreach (self::$irregular as $result => $pattern) {
129
            $pattern = '/' . $pattern . '$/i';
130
131
            if (preg_match($pattern, $string)) {
132
                return preg_replace($pattern, ctype_upper($string[0]) ? ucfirst($result) : $result, $string);
133
            }
134
        }
135
136
        // check for matches using regular expressions
137
        foreach (self::$singular as $pattern => $result) {
138
            if (preg_match($pattern, $string)) {
139
                return preg_replace($pattern, ctype_upper($string[0]) ? ucfirst($result) : $result, $string);
140
            }
141
        }
142
143
        return $string;
144
    }
145
146
    public static function pluralizeIf($count, $string): string
147
    {
148
        if ($count === 1) {
149
            return "1 $string";
150
        } else {
151
            return $count . " " . self::pluralize($string);
152
        }
153
    }
154
155
    public static function snakeize(string $input): string
156
    {
157
        $pattern = '!([A-Z][A-Z0-9]*(?=$|[A-Z][a-z0-9])|[A-Za-z][a-z0-9]+)!';
158
        preg_match_all($pattern, $input, $matches);
159
        $ret = $matches[0];
160
        foreach ($ret as &$match) {
161
            $match = $match === strtoupper($match) ? strtolower($match) : lcfirst($match);
162
        }
163
        return implode('_', $ret);
164
    }
165
166
    public static function camelize(string $input, string $delimiter = "_"): string
167
    {
168
        $exploded_str = explode($delimiter, $input);
169
        $exploded_str_camel = array_map('ucwords', $exploded_str);
170
171
        return  implode("", $exploded_str_camel);
172
    }
173
174
    public static function extractPrefix(string $method): string
175
    {
176
        preg_match('/[A-Z]/', $method, $matches, PREG_OFFSET_CAPTURE);
177
        return substr($method, 0, $matches[0][1]);
178
    }
179
}
180