StrHelper   A
last analyzed

Complexity

Total Complexity 30

Size/Duplication

Total Lines 269
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 0
Metric Value
wmc 30
lcom 1
cbo 1
dl 0
loc 269
rs 10
c 0
b 0
f 0

16 Methods

Rating   Name   Duplication   Size   Complexity  
A contain() 0 8 2
A start() 0 9 2
A end() 0 9 3
A like() 0 9 2
A removePrefix() 0 9 2
A findPrefix() 0 10 3
A str2int() 0 12 3
A int2str() 0 3 1
A camelCase2underscore() 0 12 1
A underscore2camelCase() 0 11 1
A key2Label() 0 7 1
A parseDocComment() 0 14 2
A templateToString() 0 8 2
A templateFromString() 0 10 2
A templateKeys() 0 4 1
A makeTemplatePattern() 0 8 2
1
<?php
2
3
/*
4
 *  @copyright (c) 2019 Mendel <[email protected]>
5
 *  @license see license.txt
6
 */
7
8
namespace drycart\data;
9
10
/**
11
 * Popular string helpers
12
 *
13
 * @author mendel
14
 */
15
class StrHelper
16
{    
17
    /**
18
     * Check if string contain $needle
19
     * Old name: haveStr
20
     * 
21
     * @param string $haystack
22
     * @param string $needle
23
     * @param bool $caseSensitivity
24
     * @return bool
25
     */
26
    public static function contain(string $haystack, string $needle, bool $caseSensitivity = true) : bool
27
    {
28
        if(!$caseSensitivity) {
29
            $haystack = strtolower($haystack);
30
            $needle = strtolower($needle);
31
        }
32
        return (strpos($haystack, $needle) !== false);
33
    }
34
35
    /**
36
     * Check if string start from $needle
37
     * @param string $haystack
38
     * @param string $needle
39
     * @param bool $caseSensitivity
40
     * @return bool
41
     */
42
    public static function start(string $haystack, string $needle, bool $caseSensitivity = true) : bool
43
    {
44
        if(!$caseSensitivity) {
45
            $haystack = strtolower($haystack);
46
            $needle = strtolower($needle);
47
        }
48
        $length = strlen($needle);
49
        return (substr($haystack, 0, $length) === $needle);
50
    }
51
52
    /**
53
     * Check if string end by $needle
54
     * @param string $haystack
55
     * @param string $needle
56
     * @param bool $caseSensitivity
57
     * @return bool
58
     */
59
    public static function end(string $haystack, string $needle, bool $caseSensitivity = true) : bool
60
    {
61
        if(!$caseSensitivity) {
62
            $haystack = strtolower($haystack);
63
            $needle = strtolower($needle);
64
        }
65
        $length = strlen($needle);
66
        return ($length === 0) || (substr($haystack, -$length) === $needle);
67
    }
68
69
    /**
70
     * SQL Like operator in PHP.
71
     * Returns TRUE if match else FALSE.
72
     * @param string $subject
73
     * @param string $pattern
74
     * @param bool $caseSensitivity
75
     * @return bool
76
     */
77
    public static function like(string $subject, string $pattern, bool $caseSensitivity = true) : bool
78
    {
79
        if(!$caseSensitivity) {
80
            $subject = strtolower($subject);
81
            $pattern = strtolower($pattern);
82
        }
83
        $preparedPattern = str_replace('%', '.*', preg_quote($pattern, '/'));
84
        return (bool) preg_match("/^{$preparedPattern}$/", $subject);
85
    }
86
    
87
    /**
88
     * Remove prefix from string if string start from prefix
89
     * @param string $str
90
     * @param string $prefix
91
     * @return string
92
     */
93
    public static function removePrefix(string $str, string $prefix) : string
94
    {
95
        $length = strlen($prefix);
96
        if(substr($str, 0, $length) === $prefix) { // if start from prefix
97
            return substr($str, $length);
98
        } else {
99
            return $str;
100
        }
101
    }
102
    
103
    /**
104
     * Find prefix if exist. If no - return default.
105
     * Return array - first value is prefix, second == after prefix
106
     * @param string $str
107
     * @param array $prefixes
108
     * @param string|null $default
109
     * @return array
110
     */
111
    public static function findPrefix(string $str, array $prefixes, ?string $default = null) : array
112
    {
113
        // @2DO: sort prefixes list by lenght and refactor constants at compare helper
114
        foreach($prefixes as $prefix) {
115
            if(static::start($str, $prefix, false)) {
116
                return [$prefix, static::removePrefix($str, $prefix)];
117
            }
118
        }
119
        return [$default, $str];
120
    }
121
    
122
    /**
123
     * Convert string to int
124
     * Can be used for short nicknames etc
125
     * return null if too big number
126
     * 
127
     * @param string $str
128
     * @return int|null
129
     */
130
    public static function str2int(string $str) : ?int {
131
        $low = strtolower($str);
132
        if(preg_match('/^[a-z0-1]+$/', $low) != 1) {
133
            return null;
134
        }
135
        $hex = base_convert($low, 36, 16);
136
        $i = hexdec($hex);
137
        if($i > PHP_INT_MAX) {
138
            return null;
139
        }
140
        return $i;
141
    }
142
143
    /**
144
     * Convert integer to string
145
     * @see str2int
146
     * 
147
     * @param int $i
148
     * @return string
149
     */
150
    public static function int2str(int $i) : string {
151
        return base_convert(dechex($i), 16, 36);
152
    }
153
    
154
    /**
155
     * Transform string from camel case format to underscore
156
     * @param string $key
157
     * @return string
158
     */
159
    public static function camelCase2underscore(string $key) : string {
160
        $str = lcfirst($key);
161
        return strtr($str, [
162
            'A' => '_a', 'B' => '_b', 'C' => '_c', 'D' => '_d',
163
            'E' => '_e', 'F' => '_f', 'G' => '_g', 'H' => '_h',
164
            'I' => '_i', 'J' => '_j', 'K' => '_k', 'L' => '_l',
165
            'M' => '_m', 'N' => '_n', 'O' => '_o', 'P' => '_p',
166
            'Q' => '_q', 'R' => '_r', 'S' => '_s', 'T' => '_t',
167
            'U' => '_u', 'V' => '_v', 'W' => '_w', 'X' => '_x',
168
            'Y' => '_y', 'Z' => '_z',
169
        ]);
170
    }
171
    
172
    /**
173
     * Transform underscore format, to camel case
174
     * @param string $key
175
     * @return string
176
     */
177
    public static function underscore2camelCase(string $key) : string {
178
        return strtr($key, array_flip([
179
            'A' => '_a', 'B' => '_b', 'C' => '_c', 'D' => '_d',
180
            'E' => '_e', 'F' => '_f', 'G' => '_g', 'H' => '_h',
181
            'I' => '_i', 'J' => '_j', 'K' => '_k', 'L' => '_l',
182
            'M' => '_m', 'N' => '_n', 'O' => '_o', 'P' => '_p',
183
            'Q' => '_q', 'R' => '_r', 'S' => '_s', 'T' => '_t',
184
            'U' => '_u', 'V' => '_v', 'W' => '_w', 'X' => '_x',
185
            'Y' => '_y', 'Z' => '_z',
186
        ]));
187
    }
188
    
189
    /**
190
     * Simple prettyfyer for keys
191
     * Make readable names from key
192
     * @param string $key
193
     * @return string
194
     */
195
    public static function key2Label(string $key) : string {
196
        $str = static::camelCase2underscore($key);
197
        $prepared = ucfirst(strtolower(
198
            strtr($str, ['_'=>' ', '.'=>' ','()'=>''])
199
        ));
200
            return preg_replace('/\s+/', ' ',$prepared);
201
    }
202
    
203
    /**
204
     * Parse doc comment string and get array of trimmed strings
205
     * @param string $doc
206
     * @return array
207
     */
208
    public static function parseDocComment(string $doc) : array {
209
        // Split to lines
210
        $parts = explode(\PHP_EOL, $doc);
211
        // First and last lines not contain data
212
        if(count($parts) < 3) {
213
            return [];
214
        }
215
        array_pop($parts); // take last element and not use it, so just delete
216
        array_shift($parts); // take first, and not use it, so just delete
217
        // delete multispaces and delete spaces and star at start/end
218
        return array_map(function(string $line) {
219
            return preg_replace('/\s+/', ' ',trim($line,' *'));
220
        }, $parts);        
221
    }
222
    
223
    /**
224
     * Make string from template
225
     * @param string $template
226
     * @param type $data
227
     * @return string
228
     */
229
    public static function templateToString(string $template, $data = []) : string {
230
        $wrapper = new DataWrapper($data);
231
        $replace = [];
232
        foreach (static::templateKeys($template) as $key) {
233
            $replace['{' . $key . '}'] = $wrapper[$key];
234
        }
235
        return strtr($template, $replace);
236
    }
237
238
    /**
239
     * Take data from string using template
240
     * if not correct template - return null
241
     * Dont support nested keys, return it at doted format
242
     * 
243
     * @param string $template
244
     * @param string $data
245
     * @return array|null
246
     */
247
    public static function templateFromString(string $template, string $data) : ?array {
248
        $keys = static::templateKeys($template);
249
        $pattern = static::makeTemplatePattern($template, $keys);
250
        if(preg_match($pattern,$data, $array)) {
251
            array_shift($array);
252
            return array_combine($keys, $array);
253
        } else {
254
            return null;
255
        }
256
    }
257
258
    /**
259
     * Return list of keys at template
260
     * @param string $template
261
     * @return array
262
     */
263
    public static function templateKeys(string $template): array {
264
        preg_match_all('/{([^}]+)}/i', $template, $data);
265
        return $data[1];
266
    }
267
    
268
    /**
269
     * Make pattern for parsing string
270
     * @see templateFromString
271
     * @param string $template
272
     * @param array $keys
273
     * @return string
274
     */
275
    protected static function makeTemplatePattern(string $template, array $keys) : string {
276
        $replace = [];
277
        foreach ($keys as $key) {
278
            $replace['{' . $key . '}'] = '%';
279
        }
280
        $pattern = strtr($template, $replace);
281
        return '/^'.str_replace('%', '(.*)', preg_quote($pattern, '/')).'$/i';
282
    }
283
}
284