ExprBuilder.php 5.0 KB

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