CompositeExpression.php 2.41 KB
Newer Older
1 2 3 4
<?php

namespace Doctrine\DBAL\Query\Expression;

5
use Countable;
6 7 8
use function count;
use function implode;

9 10 11
/**
 * Composite expression is responsible to build a group of similar expression.
 */
12
class CompositeExpression implements Countable
13 14
{
    /**
Benjamin Morel's avatar
Benjamin Morel committed
15
     * Constant that represents an AND composite expression.
16
     */
17
    public const TYPE_AND = 'AND';
18

19
    /**
Benjamin Morel's avatar
Benjamin Morel committed
20
     * Constant that represents an OR composite expression.
21
     */
22
    public const TYPE_OR = 'OR';
23

24
    /**
Benjamin Morel's avatar
Benjamin Morel committed
25 26 27
     * The instance type of composite expression.
     *
     * @var string
28 29
     */
    private $type;
30

31
    /**
Benjamin Morel's avatar
Benjamin Morel committed
32 33
     * Each expression part of the composite expression.
     *
34
     * @var self[]|string[]
35
     */
36
    private $parts = [];
37

38
    /**
39 40
     * @param string          $type  Instance type of composite expression.
     * @param self[]|string[] $parts Composition of expressions to be joined on composite expression.
41
     */
42
    public function __construct($type, array $parts = [])
43 44
    {
        $this->type = $type;
45

46 47
        $this->addMultiple($parts);
    }
48

49 50
    /**
     * Adds multiple parts to composite expression.
51
     *
52
     * @param self[]|string[] $parts
53
     *
Grégoire Paris's avatar
Grégoire Paris committed
54
     * @return CompositeExpression
55
     */
56
    public function addMultiple(array $parts = [])
57
    {
58
        foreach ($parts as $part) {
59 60
            $this->add($part);
        }
61

62 63
        return $this;
    }
64

65 66
    /**
     * Adds an expression to composite expression.
67
     *
68
     * @param mixed $part
Benjamin Morel's avatar
Benjamin Morel committed
69
     *
Grégoire Paris's avatar
Grégoire Paris committed
70
     * @return CompositeExpression
71 72 73
     */
    public function add($part)
    {
74 75
        if (empty($part)) {
            return $this;
76
        }
77

78
        if ($part instanceof self && count($part) === 0) {
79 80 81 82 83
            return $this;
        }

        $this->parts[] = $part;

84 85
        return $this;
    }
86

87 88
    /**
     * Retrieves the amount of expressions on composite expression.
89
     *
90
     * @return int
91 92 93 94 95
     */
    public function count()
    {
        return count($this->parts);
    }
96

97
    /**
Benjamin Morel's avatar
Benjamin Morel committed
98
     * Retrieves the string representation of this composite expression.
99
     *
100 101 102 103
     * @return string
     */
    public function __toString()
    {
104
        if ($this->count() === 1) {
105 106
            return (string) $this->parts[0];
        }
107

108 109
        return '(' . implode(') ' . $this->type . ' (', $this->parts) . ')';
    }
110

111
    /**
Benjamin Morel's avatar
Benjamin Morel committed
112
     * Returns the type of this composite expression (AND/OR).
113
     *
114 115 116 117 118 119
     * @return string
     */
    public function getType()
    {
        return $this->type;
    }
Benjamin Eberlei's avatar
Benjamin Eberlei committed
120
}