1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Majora\Framework\Inflector; |
4
|
|
|
|
5
|
|
|
/** |
6
|
|
|
* Inflector class which build replacements format |
7
|
|
|
* from given vars. |
8
|
|
|
*/ |
9
|
|
|
class Inflector |
10
|
|
|
{ |
11
|
|
|
protected $replacements; |
12
|
|
|
|
13
|
|
|
/** |
14
|
|
|
* construct. |
15
|
|
|
* |
16
|
|
|
* @param array $patterns |
17
|
|
|
*/ |
18
|
2 |
|
public function __construct(array $patterns = array()) |
19
|
|
|
{ |
20
|
2 |
|
$this->replacements = array(); |
21
|
2 |
|
foreach ($patterns as $pattern => $replacement) { |
22
|
|
|
$this->replacements[$this->camelize($pattern)] = $this->camelize($replacement); |
23
|
|
|
$this->replacements[$this->pascalize($pattern)] = $this->pascalize($replacement); |
24
|
|
|
$this->replacements[$this->snakelize($pattern)] = $this->snakelize($replacement); |
25
|
|
|
$this->replacements[$this->spinalize($pattern)] = $this->spinalize($replacement); |
26
|
|
|
$this->replacements[$this->uppercase($pattern)] = $this->uppercase($replacement); |
27
|
1 |
|
} |
28
|
2 |
|
} |
29
|
|
|
|
30
|
|
|
/** |
31
|
|
|
* return all replacements. |
32
|
|
|
* |
33
|
|
|
* @return array |
34
|
|
|
*/ |
35
|
|
|
public function all() |
36
|
|
|
{ |
37
|
|
|
return $this->replacements; |
38
|
|
|
} |
39
|
|
|
|
40
|
|
|
/** |
41
|
|
|
* translate given source string with setted replacement patterns. |
42
|
|
|
* |
43
|
|
|
* @param string $source |
44
|
|
|
* |
45
|
|
|
* @return string |
46
|
|
|
*/ |
47
|
|
|
public function translate($source) |
48
|
|
|
{ |
49
|
|
|
return strtr($source, $this->replacements); |
50
|
|
|
} |
51
|
|
|
|
52
|
|
|
/** |
53
|
|
|
* format camelCase. |
54
|
|
|
* |
55
|
|
|
* @param string $string |
56
|
|
|
* |
57
|
|
|
* @return string |
58
|
|
|
*/ |
59
|
|
|
public function camelize($string) |
60
|
|
|
{ |
61
|
|
|
return lcfirst($this->pascalize($string)); |
62
|
|
|
} |
63
|
|
|
|
64
|
|
|
/** |
65
|
|
|
* format PascalCase. |
66
|
|
|
* |
67
|
|
|
* @param string $string |
68
|
|
|
* |
69
|
|
|
* @return string |
70
|
|
|
* |
71
|
|
|
* @see for inspiration https://github.com/symfony/dependency-injection/blob/master/Container.php#L342 |
72
|
|
|
*/ |
73
|
|
|
public function pascalize($string) |
74
|
|
|
{ |
75
|
|
|
return ucfirst(strtr( |
76
|
|
|
ucwords(strtr($string, array('_' => ' ', '.' => '_ ', '\\' => '_ '))), |
77
|
|
|
array(' ' => '') |
78
|
|
|
)); |
79
|
|
|
} |
80
|
|
|
|
81
|
|
|
/** |
82
|
|
|
* format snake_case. |
83
|
|
|
* |
84
|
|
|
* @param string $string |
85
|
|
|
* |
86
|
|
|
* @return string |
87
|
|
|
* |
88
|
|
|
* @see for inspiration https://github.com/symfony/dependency-injection/blob/master/Container.php#L354 |
89
|
|
|
*/ |
90
|
2 |
|
public function snakelize($string) |
91
|
|
|
{ |
92
|
2 |
|
return strtolower(preg_replace( |
93
|
2 |
|
array('/([A-Z]+)([A-Z][a-z])/', '/([a-z\d])([A-Z])/'), |
94
|
2 |
|
array('\\1_\\2', '\\1_\\2'), |
95
|
|
|
$string |
96
|
1 |
|
)); |
97
|
|
|
} |
98
|
|
|
|
99
|
|
|
/** |
100
|
|
|
* format spinal-case. |
101
|
|
|
* |
102
|
|
|
* @param string $string |
103
|
|
|
* |
104
|
|
|
* @return string |
105
|
|
|
*/ |
106
|
|
|
public function spinalize($string) |
107
|
|
|
{ |
108
|
|
|
return str_replace('_', '-', $this->snakelize($string)); |
109
|
|
|
} |
110
|
|
|
|
111
|
|
|
/** |
112
|
|
|
* format UPPER_CASE. |
113
|
|
|
* |
114
|
|
|
* @param string $string |
115
|
|
|
* |
116
|
|
|
* @return string |
117
|
|
|
*/ |
118
|
|
|
public function uppercase($string) |
119
|
|
|
{ |
120
|
|
|
return strtoupper($this->snakelize($string)); |
121
|
|
|
} |
122
|
|
|
|
123
|
|
|
/** |
124
|
|
|
* Replace every "non-word" "non-ascii" characters in $string by $replacement. |
125
|
|
|
* |
126
|
|
|
* @param string $string |
127
|
|
|
* @param string $replacement Default value is '-'. |
128
|
|
|
* |
129
|
|
|
* @return string |
130
|
|
|
*/ |
131
|
|
|
public function slugify($string, $replacement = '-') |
132
|
|
|
{ |
133
|
|
|
// special replacement map |
134
|
|
|
$slug = strtr($string, array( |
135
|
|
|
'Š'=>'S', 'š'=>'s', 'Ž'=>'Z', 'ž'=>'z', 'À'=>'A', 'Á'=>'A', 'Â'=>'A', 'Ã'=>'A', 'Ä'=>'A', 'Å'=>'A', 'Æ'=>'A', 'Ç'=>'C', 'È'=>'E', 'É'=>'E', |
136
|
|
|
'Ê'=>'E', 'Ë'=>'E', 'Ì'=>'I', 'Í'=>'I', 'Î'=>'I', 'Ï'=>'I', 'Ñ'=>'N', 'Ò'=>'O', 'Ó'=>'O', 'Ô'=>'O', 'Õ'=>'O', 'Ö'=>'O', 'Ø'=>'O', 'Ù'=>'U', |
137
|
|
|
'Ú'=>'U', 'Û'=>'U', 'Ü'=>'U', 'Ý'=>'Y', 'Þ'=>'B', 'ß'=>'Ss', 'à'=>'a', 'á'=>'a', 'â'=>'a', 'ã'=>'a', 'ä'=>'a', 'å'=>'a', 'æ'=>'a', 'ç'=>'c', |
138
|
|
|
'è'=>'e', 'é'=>'e', 'ê'=>'e', 'ë'=>'e', 'ì'=>'i', 'í'=>'i', 'î'=>'i', 'ï'=>'i', 'ð'=>'o', 'ñ'=>'n', 'ò'=>'o', 'ó'=>'o', 'ô'=>'o', 'õ'=>'o', |
139
|
|
|
'ö'=>'o', 'ø'=>'o', 'ù'=>'u', 'ú'=>'u', 'û'=>'u', 'ý'=>'y', 'ý'=>'y', 'þ'=>'b', 'ÿ'=>'y' |
140
|
|
|
)); |
141
|
|
|
|
142
|
|
|
return trim( // clear extra replacement chars |
143
|
|
|
preg_replace( // replace "non letter" and "digits" |
|
|
|
|
144
|
|
|
'/\W+/', |
145
|
|
|
$replacement, |
146
|
|
|
strtolower($slug) |
147
|
|
|
), |
148
|
|
|
$replacement |
149
|
|
|
); |
150
|
|
|
} |
151
|
|
|
|
152
|
|
|
/** |
153
|
|
|
* Normalize given data |
154
|
|
|
* If an array is given, normalize keys, according to given method |
155
|
|
|
* |
156
|
|
|
* @param string|array &$data |
157
|
|
|
* @param string $format |
158
|
|
|
* |
159
|
|
|
* @return string|array |
160
|
|
|
* |
161
|
|
|
* @see for inspiration https://github.com/FriendsOfSymfony/FOSRestBundle/blob/master/Normalizer/CamelKeysNormalizer.php |
162
|
|
|
*/ |
163
|
|
|
public function normalize(&$data, $format) |
164
|
|
|
{ |
165
|
|
|
if (!is_array($data)) { |
166
|
|
|
return $this->$format($data); |
167
|
|
|
} |
168
|
|
|
foreach ($data as $key => $value) { |
169
|
|
|
|
170
|
|
|
// already formatted ? |
171
|
|
|
if ($key != ($normalizedKey = $this->$format($key))) { |
172
|
|
|
if (array_key_exists($normalizedKey, $data)) { |
173
|
|
|
throw new \InvalidArgumentException(sprintf( |
174
|
|
|
'Both "%s" and %s("%s") keys exists, abord normalizing.', |
175
|
|
|
$key, $format, $normalizedKey |
176
|
|
|
)); |
177
|
|
|
} |
178
|
|
|
unset($data[$key]); |
179
|
|
|
$data[$normalizedKey] = $value; |
180
|
|
|
$key = $normalizedKey; |
181
|
|
|
} |
182
|
|
|
|
183
|
|
|
// iterate over child keys |
184
|
|
|
if (is_array($value)) { |
185
|
|
|
$this->normalize($data[$key], $format); |
186
|
|
|
} |
187
|
|
|
} |
188
|
|
|
|
189
|
|
|
return $data; |
190
|
|
|
} |
191
|
|
|
|
192
|
|
|
/** |
193
|
|
|
* Replace '/' and '\' by current OS directory separator. |
194
|
|
|
* |
195
|
|
|
* This won't return the full path from the system root to a file, use realpath() or SplFileInfo::getRealPath() instead. |
196
|
|
|
* |
197
|
|
|
* @param string $string |
198
|
|
|
* |
199
|
|
|
* @return string |
200
|
|
|
* |
201
|
|
|
* @see http://php.net/php_uname |
202
|
|
|
*/ |
203
|
|
|
public function directorize($string) |
204
|
|
|
{ |
205
|
|
|
return str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $string); |
206
|
|
|
} |
207
|
|
|
|
208
|
|
|
/** |
209
|
|
|
* Force path to be UNIX style (i.e. '/path/to/something'). |
210
|
|
|
* |
211
|
|
|
* @param string $path |
212
|
|
|
* |
213
|
|
|
* @return string |
214
|
|
|
*/ |
215
|
|
|
public function unixizePath($path) |
216
|
|
|
{ |
217
|
|
|
// Handle system root (e.g. 'c:\home' => '/home') |
218
|
|
|
$path = preg_replace('/^[a-z]:\\\/i', '/', $path); |
219
|
|
|
// Handle directory separators |
220
|
|
|
return str_replace('\\', '/', $path); |
221
|
|
|
} |
222
|
|
|
} |
223
|
|
|
|
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.
The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.
This check looks for comments that seem to be mostly valid code and reports them.