1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Charcoal\Factory; |
4
|
|
|
|
5
|
|
|
use \InvalidArgumentException; |
6
|
|
|
|
7
|
|
|
// Local namespace dependencies |
8
|
|
|
use \Charcoal\Factory\AbstractFactory; |
9
|
|
|
|
10
|
|
|
/** |
11
|
|
|
* The Resolver Factory resolves the **class name** by different configurably methods applied to the **type**. |
12
|
|
|
*/ |
13
|
|
|
class ResolverFactory extends AbstractFactory |
14
|
|
|
{ |
15
|
|
|
/** |
16
|
|
|
* @var string $resolverPrefix |
17
|
|
|
*/ |
18
|
|
|
private $resolverPrefix = ''; |
19
|
|
|
|
20
|
|
|
/** |
21
|
|
|
* @var string $resolverSuffix |
22
|
|
|
*/ |
23
|
|
|
private $resolverSuffix = ''; |
24
|
|
|
|
25
|
|
|
/** |
26
|
|
|
* @var array $resolverCapitals |
27
|
|
|
*/ |
28
|
|
|
private $resolverCapitals; |
29
|
|
|
|
30
|
|
|
/** |
31
|
|
|
* @var array $resolverReplacements |
32
|
|
|
*/ |
33
|
|
|
private $resolverReplacements; |
34
|
|
|
|
35
|
|
|
public function __construct($data = null) |
36
|
|
|
{ |
37
|
|
|
parent::__construct($data); |
38
|
|
|
|
39
|
|
|
if (!isset($data['resolver_prefix'])) { |
40
|
|
|
$data['resolver_prefix'] = ''; |
41
|
|
|
} |
42
|
|
|
if (!isset($data['resolverSuffix'])) { |
43
|
|
|
$data['resolver_suffix'] = ''; |
44
|
|
|
} |
45
|
|
View Code Duplication |
if (!isset($data['resolver_capitals'])) { |
|
|
|
|
46
|
|
|
$data['resolver_capitals'] = [ |
47
|
|
|
'-', |
48
|
|
|
'\\', |
49
|
|
|
'/', |
50
|
|
|
'.', |
51
|
|
|
'_' |
52
|
|
|
]; |
53
|
|
|
} |
54
|
|
View Code Duplication |
if (!isset($data['resolver_replacements'])) { |
|
|
|
|
55
|
|
|
$data['resolver_replacements'] = [ |
56
|
|
|
'-'=>'', |
57
|
|
|
'/'=>'\\', |
58
|
|
|
'.'=>'_' |
59
|
|
|
]; |
60
|
|
|
} |
61
|
|
|
$this->setResolverPrefix($data['resolver_prefix']); |
62
|
|
|
$this->setResolverSuffix($data['resolver_suffix']); |
63
|
|
|
$this->setResolverCapitals($data['resolver_capitals']); |
64
|
|
|
$this->setResolverReplacements($data['resolver_replacements']); |
65
|
|
|
} |
66
|
|
|
|
67
|
|
|
/** |
68
|
|
|
* @param string $prefix The resolver prefix string. |
69
|
|
|
* @throws InvalidArgumentException If the prefix argument is not a string. |
70
|
|
|
* @return ResolverFactory Chainable |
71
|
|
|
*/ |
72
|
|
|
public function setResolverPrefix($prefix) |
73
|
|
|
{ |
74
|
|
|
if (!is_string($prefix)) { |
75
|
|
|
throw new InvalidArgumentException( |
76
|
|
|
'Prefix must be a string' |
77
|
|
|
); |
78
|
|
|
} |
79
|
|
|
$this->resolverPrefix = $prefix; |
80
|
|
|
return $this; |
81
|
|
|
} |
82
|
|
|
|
83
|
|
|
/** |
84
|
|
|
* @return string |
85
|
|
|
*/ |
86
|
|
|
public function resolverPrefix() |
87
|
|
|
{ |
88
|
|
|
return $this->resolverPrefix; |
89
|
|
|
} |
90
|
|
|
|
91
|
|
|
/** |
92
|
|
|
* @param string $suffix The resolver suffix string. |
93
|
|
|
* @throws InvalidArgumentException If the suffix argument is not a string. |
94
|
|
|
* @return ResolverFactory Chainable |
95
|
|
|
*/ |
96
|
|
|
public function setResolverSuffix($suffix) |
97
|
|
|
{ |
98
|
|
|
if (!is_string($suffix)) { |
99
|
|
|
throw new InvalidArgumentException( |
100
|
|
|
'Prefix must be a string' |
101
|
|
|
); |
102
|
|
|
} |
103
|
|
|
$this->resolverSuffix = $suffix; |
104
|
|
|
return $this; |
105
|
|
|
} |
106
|
|
|
|
107
|
|
|
/** |
108
|
|
|
* @return string |
109
|
|
|
*/ |
110
|
|
|
public function resolverSuffix() |
111
|
|
|
{ |
112
|
|
|
return $this->resolverSuffix; |
113
|
|
|
} |
114
|
|
|
|
115
|
|
|
/** |
116
|
|
|
* @param array $capitals The array of letter to "calitalize-next" (uppercase next letter in the string). |
117
|
|
|
* @return ResolverFactory Chainable |
118
|
|
|
*/ |
119
|
|
|
public function setResolverCapitals(array $capitals) |
120
|
|
|
{ |
121
|
|
|
$this->resolverCapitals = $capitals; |
122
|
|
|
return $this; |
123
|
|
|
} |
124
|
|
|
|
125
|
|
|
/** |
126
|
|
|
* @return array |
127
|
|
|
*/ |
128
|
|
|
public function resolverCapitals() |
129
|
|
|
{ |
130
|
|
|
return $this->resolverCapitals; |
131
|
|
|
} |
132
|
|
|
|
133
|
|
|
/** |
134
|
|
|
* @param array $replacements The array (key=>value) of replacements. |
135
|
|
|
* @return ResolverFactory Chainable |
136
|
|
|
*/ |
137
|
|
|
public function setResolverReplacements(array $replacements) |
138
|
|
|
{ |
139
|
|
|
$this->resolverReplacements = $replacements; |
140
|
|
|
return $this; |
141
|
|
|
} |
142
|
|
|
|
143
|
|
|
/** |
144
|
|
|
* @return array |
145
|
|
|
*/ |
146
|
|
|
public function resolverReplacements() |
147
|
|
|
{ |
148
|
|
|
return $this->resolverReplacements; |
149
|
|
|
} |
150
|
|
|
|
151
|
|
|
/** |
152
|
|
|
* Resolve the class name from the requested type. |
153
|
|
|
* |
154
|
|
|
* @param string $type The "type" of object to resolve (the object ident). |
155
|
|
|
* @throws InvalidArgumentException If the type parameter is not a string. |
156
|
|
|
* @return string The resolved class name (FQN). |
157
|
|
|
*/ |
158
|
|
|
public function resolve($type) |
159
|
|
|
{ |
160
|
|
|
if (!is_string($type)) { |
161
|
|
|
throw new InvalidArgumentException( |
162
|
|
|
'Can not resolve class ident: type must be a string' |
163
|
|
|
); |
164
|
|
|
} |
165
|
|
|
|
166
|
|
|
$capitalize_next = function(&$i) { |
167
|
|
|
$i = ucfirst($i); |
168
|
|
|
}; |
169
|
|
|
|
170
|
|
|
$capitals = $this->resolverCapitals(); |
171
|
|
|
foreach ($capitals as $cap) { |
172
|
|
|
$expl = explode($cap, $type); |
173
|
|
|
array_walk($expl, $capitalize_next); |
174
|
|
|
$type = implode($cap, $expl); |
175
|
|
|
} |
176
|
|
|
|
177
|
|
|
$replacements = $this->resolverReplacements(); |
178
|
|
|
foreach ($replacements as $rep => $target) { |
179
|
|
|
$type = str_replace($rep, $target, $type); |
180
|
|
|
} |
181
|
|
|
|
182
|
|
|
$class = '\\'.trim($type, '\\'); |
183
|
|
|
|
184
|
|
|
// Add prefix + suffix, if applicable |
185
|
|
|
$class = $this->resolverPrefix().$class.$this->resolverSuffix(); |
186
|
|
|
|
187
|
|
|
return $class; |
188
|
|
|
} |
189
|
|
|
|
190
|
|
|
/** |
191
|
|
|
* @param string $type The "type" of object to resolve (the object ident). |
192
|
|
|
* @throws InvalidArgumentException If the type parameter is not a string. |
193
|
|
|
* @return boolean |
194
|
|
|
*/ |
195
|
|
|
public function isResolvable($type) |
196
|
|
|
{ |
197
|
|
|
if (!is_string($type)) { |
198
|
|
|
throw new InvalidArgumentException( |
199
|
|
|
'Can not check resolvable: type must be a string' |
200
|
|
|
); |
201
|
|
|
} |
202
|
|
|
|
203
|
|
|
$class_name = $this->resolve($type); |
204
|
|
|
return class_exists($class_name); |
205
|
|
|
} |
206
|
|
|
} |
207
|
|
|
|
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.