CompositeExpression.php 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. <?php
  2. namespace Doctrine\DBAL\Query\Expression;
  3. use Countable;
  4. use Doctrine\Deprecations\Deprecation;
  5. use function array_merge;
  6. use function count;
  7. use function implode;
  8. /**
  9. * Composite expression is responsible to build a group of similar expression.
  10. */
  11. class CompositeExpression implements Countable
  12. {
  13. /**
  14. * Constant that represents an AND composite expression.
  15. */
  16. public const TYPE_AND = 'AND';
  17. /**
  18. * Constant that represents an OR composite expression.
  19. */
  20. public const TYPE_OR = 'OR';
  21. /**
  22. * The instance type of composite expression.
  23. *
  24. * @var string
  25. */
  26. private $type;
  27. /**
  28. * Each expression part of the composite expression.
  29. *
  30. * @var self[]|string[]
  31. */
  32. private $parts = [];
  33. /**
  34. * @internal Use the and() / or() factory methods.
  35. *
  36. * @param string $type Instance type of composite expression.
  37. * @param self[]|string[] $parts Composition of expressions to be joined on composite expression.
  38. */
  39. public function __construct($type, array $parts = [])
  40. {
  41. $this->type = $type;
  42. $this->addMultiple($parts);
  43. Deprecation::triggerIfCalledFromOutside(
  44. 'doctrine/dbal',
  45. 'https://github.com/doctrine/dbal/pull/3864',
  46. 'Do not use CompositeExpression constructor directly, use static and() and or() factory methods.'
  47. );
  48. }
  49. /**
  50. * @param self|string $part
  51. * @param self|string ...$parts
  52. */
  53. public static function and($part, ...$parts): self
  54. {
  55. return new self(self::TYPE_AND, array_merge([$part], $parts));
  56. }
  57. /**
  58. * @param self|string $part
  59. * @param self|string ...$parts
  60. */
  61. public static function or($part, ...$parts): self
  62. {
  63. return new self(self::TYPE_OR, array_merge([$part], $parts));
  64. }
  65. /**
  66. * Adds multiple parts to composite expression.
  67. *
  68. * @deprecated This class will be made immutable. Use with() instead.
  69. *
  70. * @param self[]|string[] $parts
  71. *
  72. * @return CompositeExpression
  73. */
  74. public function addMultiple(array $parts = [])
  75. {
  76. Deprecation::triggerIfCalledFromOutside(
  77. 'doctrine/dbal',
  78. 'https://github.com/doctrine/dbal/issues/3844',
  79. 'CompositeExpression::addMultiple() is deprecated, use CompositeExpression::with() instead.'
  80. );
  81. foreach ($parts as $part) {
  82. $this->add($part);
  83. }
  84. return $this;
  85. }
  86. /**
  87. * Adds an expression to composite expression.
  88. *
  89. * @deprecated This class will be made immutable. Use with() instead.
  90. *
  91. * @param mixed $part
  92. *
  93. * @return CompositeExpression
  94. */
  95. public function add($part)
  96. {
  97. Deprecation::triggerIfCalledFromOutside(
  98. 'doctrine/dbal',
  99. 'https://github.com/doctrine/dbal/issues/3844',
  100. 'CompositeExpression::add() is deprecated, use CompositeExpression::with() instead.'
  101. );
  102. if (empty($part)) {
  103. return $this;
  104. }
  105. if ($part instanceof self && count($part) === 0) {
  106. return $this;
  107. }
  108. $this->parts[] = $part;
  109. return $this;
  110. }
  111. /**
  112. * Returns a new CompositeExpression with the given parts added.
  113. *
  114. * @param self|string $part
  115. * @param self|string ...$parts
  116. */
  117. public function with($part, ...$parts): self
  118. {
  119. $that = clone $this;
  120. $that->parts[] = $part;
  121. foreach ($parts as $part) {
  122. $that->parts[] = $part;
  123. }
  124. return $that;
  125. }
  126. /**
  127. * Retrieves the amount of expressions on composite expression.
  128. *
  129. * @return int
  130. */
  131. public function count()
  132. {
  133. return count($this->parts);
  134. }
  135. /**
  136. * Retrieves the string representation of this composite expression.
  137. *
  138. * @return string
  139. */
  140. public function __toString()
  141. {
  142. if ($this->count() === 1) {
  143. return (string) $this->parts[0];
  144. }
  145. return '(' . implode(') ' . $this->type . ' (', $this->parts) . ')';
  146. }
  147. /**
  148. * Returns the type of this composite expression (AND/OR).
  149. *
  150. * @return string
  151. */
  152. public function getType()
  153. {
  154. return $this->type;
  155. }
  156. }