ExprBuilder.php 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  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. public function __construct(NodeDefinition $node)
  24. {
  25. $this->node = $node;
  26. }
  27. /**
  28. * Marks the expression as being always used.
  29. *
  30. * @return $this
  31. */
  32. public function always(\Closure $then = null)
  33. {
  34. $this->ifPart = function ($v) { return true; };
  35. if (null !== $then) {
  36. $this->thenPart = $then;
  37. }
  38. return $this;
  39. }
  40. /**
  41. * Sets a closure to use as tests.
  42. *
  43. * The default one tests if the value is true.
  44. *
  45. * @return $this
  46. */
  47. public function ifTrue(\Closure $closure = null)
  48. {
  49. if (null === $closure) {
  50. $closure = function ($v) { return true === $v; };
  51. }
  52. $this->ifPart = $closure;
  53. return $this;
  54. }
  55. /**
  56. * Tests if the value is a string.
  57. *
  58. * @return $this
  59. */
  60. public function ifString()
  61. {
  62. $this->ifPart = function ($v) { return \is_string($v); };
  63. return $this;
  64. }
  65. /**
  66. * Tests if the value is null.
  67. *
  68. * @return $this
  69. */
  70. public function ifNull()
  71. {
  72. $this->ifPart = function ($v) { return null === $v; };
  73. return $this;
  74. }
  75. /**
  76. * Tests if the value is an array.
  77. *
  78. * @return $this
  79. */
  80. public function ifArray()
  81. {
  82. $this->ifPart = function ($v) { return \is_array($v); };
  83. return $this;
  84. }
  85. /**
  86. * Tests if the value is in an array.
  87. *
  88. * @return $this
  89. */
  90. public function ifInArray(array $array)
  91. {
  92. $this->ifPart = function ($v) use ($array) { return \in_array($v, $array, true); };
  93. return $this;
  94. }
  95. /**
  96. * Tests if the value is not in an array.
  97. *
  98. * @return $this
  99. */
  100. public function ifNotInArray(array $array)
  101. {
  102. $this->ifPart = function ($v) use ($array) { return !\in_array($v, $array, true); };
  103. return $this;
  104. }
  105. /**
  106. * Sets the closure to run if the test pass.
  107. *
  108. * @return $this
  109. */
  110. public function then(\Closure $closure)
  111. {
  112. $this->thenPart = $closure;
  113. return $this;
  114. }
  115. /**
  116. * Sets a closure returning an empty array.
  117. *
  118. * @return $this
  119. */
  120. public function thenEmptyArray()
  121. {
  122. $this->thenPart = function ($v) { return array(); };
  123. return $this;
  124. }
  125. /**
  126. * Sets a closure marking the value as invalid at processing time.
  127. *
  128. * if you want to add the value of the node in your message just use a %s placeholder.
  129. *
  130. * @param string $message
  131. *
  132. * @return $this
  133. *
  134. * @throws \InvalidArgumentException
  135. */
  136. public function thenInvalid($message)
  137. {
  138. $this->thenPart = function ($v) use ($message) { throw new \InvalidArgumentException(sprintf($message, json_encode($v))); };
  139. return $this;
  140. }
  141. /**
  142. * Sets a closure unsetting this key of the array at processing time.
  143. *
  144. * @return $this
  145. *
  146. * @throws UnsetKeyException
  147. */
  148. public function thenUnset()
  149. {
  150. $this->thenPart = function ($v) { throw new UnsetKeyException('Unsetting key'); };
  151. return $this;
  152. }
  153. /**
  154. * Returns the related node.
  155. *
  156. * @return NodeDefinition|ArrayNodeDefinition|VariableNodeDefinition
  157. *
  158. * @throws \RuntimeException
  159. */
  160. public function end()
  161. {
  162. if (null === $this->ifPart) {
  163. throw new \RuntimeException('You must specify an if part.');
  164. }
  165. if (null === $this->thenPart) {
  166. throw new \RuntimeException('You must specify a then part.');
  167. }
  168. return $this->node;
  169. }
  170. /**
  171. * Builds the expressions.
  172. *
  173. * @param ExprBuilder[] $expressions An array of ExprBuilder instances to build
  174. *
  175. * @return array
  176. */
  177. public static function buildExpressions(array $expressions)
  178. {
  179. foreach ($expressions as $k => $expr) {
  180. if ($expr instanceof self) {
  181. $if = $expr->ifPart;
  182. $then = $expr->thenPart;
  183. $expressions[$k] = function ($v) use ($if, $then) {
  184. return $if($v) ? $then($v) : $v;
  185. };
  186. }
  187. }
  188. return $expressions;
  189. }
  190. }