ExprBuilder.php 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  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 empty.
  77. *
  78. * @return ExprBuilder
  79. */
  80. public function ifEmpty()
  81. {
  82. $this->ifPart = function ($v) { return empty($v); };
  83. return $this;
  84. }
  85. /**
  86. * Tests if the value is an array.
  87. *
  88. * @return $this
  89. */
  90. public function ifArray()
  91. {
  92. $this->ifPart = function ($v) { return \is_array($v); };
  93. return $this;
  94. }
  95. /**
  96. * Tests if the value is in an array.
  97. *
  98. * @return $this
  99. */
  100. public function ifInArray(array $array)
  101. {
  102. $this->ifPart = function ($v) use ($array) { return \in_array($v, $array, true); };
  103. return $this;
  104. }
  105. /**
  106. * Tests if the value is not in an array.
  107. *
  108. * @return $this
  109. */
  110. public function ifNotInArray(array $array)
  111. {
  112. $this->ifPart = function ($v) use ($array) { return !\in_array($v, $array, true); };
  113. return $this;
  114. }
  115. /**
  116. * Transforms variables of any type into an array.
  117. *
  118. * @return $this
  119. */
  120. public function castToArray()
  121. {
  122. $this->ifPart = function ($v) { return !\is_array($v); };
  123. $this->thenPart = function ($v) { return [$v]; };
  124. return $this;
  125. }
  126. /**
  127. * Sets the closure to run if the test pass.
  128. *
  129. * @return $this
  130. */
  131. public function then(\Closure $closure)
  132. {
  133. $this->thenPart = $closure;
  134. return $this;
  135. }
  136. /**
  137. * Sets a closure returning an empty array.
  138. *
  139. * @return $this
  140. */
  141. public function thenEmptyArray()
  142. {
  143. $this->thenPart = function ($v) { return []; };
  144. return $this;
  145. }
  146. /**
  147. * Sets a closure marking the value as invalid at processing time.
  148. *
  149. * if you want to add the value of the node in your message just use a %s placeholder.
  150. *
  151. * @return $this
  152. *
  153. * @throws \InvalidArgumentException
  154. */
  155. public function thenInvalid(string $message)
  156. {
  157. $this->thenPart = function ($v) use ($message) { throw new \InvalidArgumentException(sprintf($message, json_encode($v))); };
  158. return $this;
  159. }
  160. /**
  161. * Sets a closure unsetting this key of the array at processing time.
  162. *
  163. * @return $this
  164. *
  165. * @throws UnsetKeyException
  166. */
  167. public function thenUnset()
  168. {
  169. $this->thenPart = function ($v) { throw new UnsetKeyException('Unsetting key.'); };
  170. return $this;
  171. }
  172. /**
  173. * Returns the related node.
  174. *
  175. * @return NodeDefinition|ArrayNodeDefinition|VariableNodeDefinition
  176. *
  177. * @throws \RuntimeException
  178. */
  179. public function end()
  180. {
  181. if (null === $this->ifPart) {
  182. throw new \RuntimeException('You must specify an if part.');
  183. }
  184. if (null === $this->thenPart) {
  185. throw new \RuntimeException('You must specify a then part.');
  186. }
  187. return $this->node;
  188. }
  189. /**
  190. * Builds the expressions.
  191. *
  192. * @param ExprBuilder[] $expressions An array of ExprBuilder instances to build
  193. *
  194. * @return array
  195. */
  196. public static function buildExpressions(array $expressions)
  197. {
  198. foreach ($expressions as $k => $expr) {
  199. if ($expr instanceof self) {
  200. $if = $expr->ifPart;
  201. $then = $expr->thenPart;
  202. $expressions[$k] = function ($v) use ($if, $then) {
  203. return $if($v) ? $then($v) : $v;
  204. };
  205. }
  206. }
  207. return $expressions;
  208. }
  209. }