|
1 <?php |
|
2 |
|
3 /* |
|
4 * This file is part of the Symfony package. |
|
5 * |
|
6 * (c) Fabien Potencier <fabien@symfony.com> |
|
7 * |
|
8 * For the full copyright and license information, please view the LICENSE |
|
9 * file that was distributed with this source code. |
|
10 */ |
|
11 |
|
12 namespace Symfony\Component\Config\Definition\Builder; |
|
13 use Symfony\Component\Config\Definition\Exception\UnsetKeyException; |
|
14 |
|
15 /** |
|
16 * This class builds an if expression. |
|
17 * |
|
18 * @author Johannes M. Schmitt <schmittjoh@gmail.com> |
|
19 * @author Christophe Coevoet <stof@notk.org> |
|
20 */ |
|
21 class ExprBuilder |
|
22 { |
|
23 protected $node; |
|
24 public $ifPart; |
|
25 public $thenPart; |
|
26 |
|
27 /** |
|
28 * Constructor |
|
29 * |
|
30 * @param NodeDefinition $node The related node |
|
31 */ |
|
32 public function __construct(NodeDefinition $node) |
|
33 { |
|
34 $this->node = $node; |
|
35 } |
|
36 |
|
37 /** |
|
38 * Mark the expression as being always used. |
|
39 * |
|
40 * @return ExprBuilder |
|
41 */ |
|
42 public function always(\Closure $then = null) |
|
43 { |
|
44 $this->ifPart = function($v) { return true; }; |
|
45 |
|
46 if (null !== $then) { |
|
47 $this->thenPart = $then; |
|
48 } |
|
49 |
|
50 return $this; |
|
51 } |
|
52 |
|
53 /** |
|
54 * Sets a closure to use as tests. |
|
55 * |
|
56 * The default one tests if the value is true. |
|
57 * |
|
58 * @param \Closure $closure |
|
59 * @return ExprBuilder |
|
60 */ |
|
61 public function ifTrue(\Closure $closure = null) |
|
62 { |
|
63 if (null === $closure) { |
|
64 $closure = function($v) { return true === $v; }; |
|
65 } |
|
66 |
|
67 $this->ifPart = $closure; |
|
68 |
|
69 return $this; |
|
70 } |
|
71 |
|
72 /** |
|
73 * Tests if the value is a string. |
|
74 * |
|
75 * @return ExprBuilder |
|
76 */ |
|
77 public function ifString() |
|
78 { |
|
79 $this->ifPart = function($v) { return is_string($v); }; |
|
80 |
|
81 return $this; |
|
82 } |
|
83 |
|
84 /** |
|
85 * Tests if the value is null. |
|
86 * |
|
87 * @return ExprBuilder |
|
88 */ |
|
89 public function ifNull() |
|
90 { |
|
91 $this->ifPart = function($v) { return null === $v; }; |
|
92 |
|
93 return $this; |
|
94 } |
|
95 |
|
96 /** |
|
97 * Tests if the value is an array. |
|
98 * |
|
99 * @return ExprBuilder |
|
100 */ |
|
101 public function ifArray() |
|
102 { |
|
103 $this->ifPart = function($v) { return is_array($v); }; |
|
104 |
|
105 return $this; |
|
106 } |
|
107 |
|
108 /** |
|
109 * Tests if the value is in an array. |
|
110 * |
|
111 * @param array $array |
|
112 * |
|
113 * @return ExprBuilder |
|
114 */ |
|
115 public function ifInArray(array $array) |
|
116 { |
|
117 $this->ifPart = function($v) use ($array) { return in_array($v, $array, true); }; |
|
118 |
|
119 return $this; |
|
120 } |
|
121 |
|
122 /** |
|
123 * Tests if the value is not in an array. |
|
124 * |
|
125 * @param array $array |
|
126 * |
|
127 * @return ExprBuilder |
|
128 */ |
|
129 public function ifNotInArray(array $array) |
|
130 { |
|
131 $this->ifPart = function($v) use ($array) { return !in_array($v, $array, true); }; |
|
132 |
|
133 return $this; |
|
134 } |
|
135 |
|
136 /** |
|
137 * Sets the closure to run if the test pass. |
|
138 * |
|
139 * @param \Closure $closure |
|
140 * |
|
141 * @return ExprBuilder |
|
142 */ |
|
143 public function then(\Closure $closure) |
|
144 { |
|
145 $this->thenPart = $closure; |
|
146 |
|
147 return $this; |
|
148 } |
|
149 |
|
150 /** |
|
151 * Sets a closure returning an empty array. |
|
152 * |
|
153 * @return ExprBuilder |
|
154 */ |
|
155 public function thenEmptyArray() |
|
156 { |
|
157 $this->thenPart = function($v) { return array(); }; |
|
158 |
|
159 return $this; |
|
160 } |
|
161 |
|
162 /** |
|
163 * Sets a closure marking the value as invalid at validation time. |
|
164 * |
|
165 * if you want to add the value of the node in your message just use a %s placeholder. |
|
166 * |
|
167 * @param string $message |
|
168 * |
|
169 * @return ExprBuilder |
|
170 */ |
|
171 public function thenInvalid($message) |
|
172 { |
|
173 $this->thenPart = function ($v) use ($message) {throw new \InvalidArgumentException(sprintf($message, json_encode($v))); }; |
|
174 |
|
175 return $this; |
|
176 } |
|
177 |
|
178 /** |
|
179 * Sets a closure unsetting this key of the array at validation time. |
|
180 * |
|
181 * @return ExprBuilder |
|
182 */ |
|
183 public function thenUnset() |
|
184 { |
|
185 $this->thenPart = function ($v) { throw new UnsetKeyException('Unsetting key'); }; |
|
186 |
|
187 return $this; |
|
188 } |
|
189 |
|
190 /** |
|
191 * Returns the related node |
|
192 * |
|
193 * @return NodeDefinition |
|
194 */ |
|
195 public function end() |
|
196 { |
|
197 if (null === $this->ifPart) { |
|
198 throw new \RuntimeException('You must specify an if part.'); |
|
199 } |
|
200 if (null === $this->thenPart) { |
|
201 throw new \RuntimeException('You must specify a then part.'); |
|
202 } |
|
203 |
|
204 return $this->node; |
|
205 } |
|
206 |
|
207 /** |
|
208 * Builds the expressions. |
|
209 * |
|
210 * @param array $expressions An array of ExprBuilder instances to build |
|
211 * |
|
212 * @return array |
|
213 */ |
|
214 static public function buildExpressions(array $expressions) |
|
215 { |
|
216 foreach ($expressions as $k => $expr) { |
|
217 if ($expr instanceof ExprBuilder) { |
|
218 $expressions[$k] = function($v) use($expr) { |
|
219 return call_user_func($expr->ifPart, $v) ? call_user_func($expr->thenPart, $v) : $v; |
|
220 }; |
|
221 } |
|
222 } |
|
223 |
|
224 return $expressions; |
|
225 } |
|
226 } |