Completed
Push — master ( 0f5459...b9fce4 )
by Max
01:22
created

StrHelper::key2Title()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 7
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
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
        foreach($prefixes as $prefix) {
114
            if(static::start($str, $prefix, false)) {
115
                return [$prefix, static::removePrefix($str, $prefix)];
116
            }
117
        }
118
        return [$default, $str];
119
    }
120
    
121
    /**
122
     * Convert string to int
123
     * Can be used for short nicknames etc
124
     * return null if too big number
125
     * 
126
     * @param string $str
127
     * @return int|null
128
     */
129
    public static function str2int(string $str) : ?int {
130
        $low = strtolower($str);
131
        if(preg_match('/^[a-z0-1]+$/', $low) != 1) {
132
            return null;
133
        }
134
        $hex = base_convert($low, 36, 16);
135
        $i = hexdec($hex);
136
        if($i > PHP_INT_MAX) {
137
            return null;
138
        }
139
        return $i;
140
    }
141
142
    /**
143
     * Convert integer to string
144
     * @see str2int
145
     * 
146
     * @param int $i
147
     * @return string
148
     */
149
    public static function int2str(int $i) : string {
150
        return base_convert(dechex($i), 16, 36);
151
    }
152
    
153
    /**
154
     * Transform string from camel case format to underscore
155
     * @param string $key
156
     * @return string
157
     */
158
    public static function camelCase2underscore(string $key) : string {
159
        $str = lcfirst($key);
160
        return strtr($str, [
161
            'A' => '_a', 'B' => '_b', 'C' => '_c', 'D' => '_d',
162
            'E' => '_e', 'F' => '_f', 'G' => '_g', 'H' => '_h',
163
            'I' => '_i', 'J' => '_j', 'K' => '_k', 'L' => '_l',
164
            'M' => '_m', 'N' => '_n', 'O' => '_o', 'P' => '_p',
165
            'Q' => '_q', 'R' => '_r', 'S' => '_s', 'T' => '_t',
166
            'U' => '_u', 'V' => '_v', 'W' => '_w', 'X' => '_x',
167
            'Y' => '_y', 'Z' => '_z',
168
        ]);
169
    }
170
    
171
    /**
172
     * Transform underscore format, to camel case
173
     * @param string $key
174
     * @return string
175
     */
176
    public static function underscore2camelCase(string $key) : string {
177
        return strtr($key, array_flip([
178
            'A' => '_a', 'B' => '_b', 'C' => '_c', 'D' => '_d',
179
            'E' => '_e', 'F' => '_f', 'G' => '_g', 'H' => '_h',
180
            'I' => '_i', 'J' => '_j', 'K' => '_k', 'L' => '_l',
181
            'M' => '_m', 'N' => '_n', 'O' => '_o', 'P' => '_p',
182
            'Q' => '_q', 'R' => '_r', 'S' => '_s', 'T' => '_t',
183
            'U' => '_u', 'V' => '_v', 'W' => '_w', 'X' => '_x',
184
            'Y' => '_y', 'Z' => '_z',
185
        ]));
186
    }
187
    
188
    /**
189
     * Simple prettyfyer for keys
190
     * Make readable names from key
191
     * @param string $key
192
     * @return string
193
     */
194
    public static function key2Label(string $key) : string {
195
        $str = static::camelCase2underscore($key);
196
        $prepared = ucfirst(strtolower(
197
            strtr($str, ['_'=>' ', '.'=>' ','()'=>''])
198
        ));
199
            return preg_replace('/\s+/', ' ',$prepared);
200
    }
201
    
202
    /**
203
     * Parse doc comment string and get array of trimmed strings
204
     * @param string $doc
205
     * @return array
206
     */
207
    public static function parseDocComment(string $doc) : array {
208
        // Split to lines
209
        $parts = explode(\PHP_EOL, $doc);
210
        // First and last lines not contain data
211
        if(count($parts) < 3) {
212
            return [];
213
        }
214
        array_pop($parts); // take last element and not use it, so just delete
215
        array_shift($parts); // take first, and not use it, so just delete
216
        // delete multispaces and delete spaces and star at start/end
217
        return array_map(function(string $line) {
218
            return preg_replace('/\s+/', ' ',trim($line,' *'));
219
        }, $parts);        
220
    }
221
    
222
    /**
223
     * Make string from template
224
     * @param string $template
225
     * @param type $data
226
     * @return string
227
     */
228
    public static function templateToString(string $template, $data = []) : string {
229
        $wrapper = new DataWrapper($data);
230
        $replace = [];
231
        foreach (static::templateKeys($template) as $key) {
232
            $replace['{' . $key . '}'] = $wrapper->get($key);
233
        }
234
        return strtr($template, $replace);
235
    }
236
237
    /**
238
     * Take data from string using template
239
     * if not correct template - return null
240
     * Dont support nested keys, return it at doted format
241
     * 
242
     * @param string $template
243
     * @param string $data
244
     * @return array|null
245
     */
246
    public static function templateFromString(string $template, string $data) : ?array {
247
        $keys = static::templateKeys($template);
248
        $pattern = static::makeTemplatePattern($template, $keys);
249
        if(preg_match($pattern,$data, $array)) {
250
            array_shift($array);
251
            return array_combine($keys, $array);
252
        } else {
253
            return null;
254
        }
255
    }
256
257
    /**
258
     * Return list of keys at template
259
     * @param string $template
260
     * @return array
261
     */
262
    public static function templateKeys(string $template): array {
263
        preg_match_all('/{([^}]+)}/i', $template, $data);
264
        return $data[1];
265
    }
266
    
267
    /**
268
     * Make pattern for parsing string
269
     * @see templateFromString
270
     * @param string $template
271
     * @param array $keys
272
     * @return string
273
     */
274
    protected static function makeTemplatePattern(string $template, array $keys) : string {
275
        $replace = [];
276
        foreach ($keys as $key) {
277
            $replace['{' . $key . '}'] = '%';
278
        }
279
        $pattern = strtr($template, $replace);
280
        return '/^'.str_replace('%', '(.*)', preg_quote($pattern, '/')).'$/i';
281
    }
282
}
283