<?php namespace Doctrine\DBAL\Query\Expression; use Countable; use function count; use function implode; /** * Composite expression is responsible to build a group of similar expression. */ class CompositeExpression implements Countable { /** * Constant that represents an AND composite expression. */ public const TYPE_AND = 'AND'; /** * Constant that represents an OR composite expression. */ public const TYPE_OR = 'OR'; /** * The instance type of composite expression. * * @var string */ private $type; /** * Each expression part of the composite expression. * * @var self[]|string[] */ private $parts = []; /** * @param string $type Instance type of composite expression. * @param self[]|string[] $parts Composition of expressions to be joined on composite expression. */ public function __construct($type, array $parts = []) { $this->type = $type; $this->addMultiple($parts); } /** * Adds multiple parts to composite expression. * * @param self[]|string[] $parts * * @return \Doctrine\DBAL\Query\Expression\CompositeExpression */ public function addMultiple(array $parts = []) { foreach ($parts as $part) { $this->add($part); } return $this; } /** * Adds an expression to composite expression. * * @param mixed $part * * @return \Doctrine\DBAL\Query\Expression\CompositeExpression */ public function add($part) { if (empty($part)) { return $this; } if ($part instanceof self && count($part) === 0) { return $this; } $this->parts[] = $part; return $this; } /** * Retrieves the amount of expressions on composite expression. * * @return int */ public function count() { return count($this->parts); } /** * Retrieves the string representation of this composite expression. * * @return string */ public function __toString() { if ($this->count() === 1) { return (string) $this->parts[0]; } return '(' . implode(') ' . $this->type . ' (', $this->parts) . ')'; } /** * Returns the type of this composite expression (AND/OR). * * @return string */ public function getType() { return $this->type; } }