Completed
Push — master ( 349e4b...b55968 )
by Dominik
02:17
created

QueryBuilder::add()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 2
Bugs 0 Features 1
Metric Value
c 2
b 0
f 1
dl 0
loc 8
ccs 4
cts 4
cp 1
rs 9.4285
cc 2
eloc 4
nc 2
nop 1
crap 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Saxulum\ElasticSearchQueryBuilder;
6
7
use Saxulum\ElasticSearchQueryBuilder\Node\AbstractNode;
8
use Saxulum\ElasticSearchQueryBuilder\Node\ArrayNode;
9
use Saxulum\ElasticSearchQueryBuilder\Node\BoolNode;
10
use Saxulum\ElasticSearchQueryBuilder\Node\FloatNode;
11
use Saxulum\ElasticSearchQueryBuilder\Node\IntNode;
12
use Saxulum\ElasticSearchQueryBuilder\Node\ObjectNode;
13
use Saxulum\ElasticSearchQueryBuilder\Node\ScalarNode;
14
use Saxulum\ElasticSearchQueryBuilder\Node\StringNode;
15
16
final class QueryBuilder implements QueryBuilderInterface
17
{
18
    /**
19
     * @var ObjectNode
20
     */
21
    private $rootNode;
22
23
    /**
24
     * @var AbstractNode
25
     */
26
    private $node;
27
28 19
    public function __construct()
29
    {
30 19
        $this->rootNode = new ObjectNode();
31 19
        $this->node = $this->rootNode;
32 19
    }
33
34
    /**
35
     * @param array ...$arguments
36
     * @return QueryBuilderInterface
37
     * @throws \Exception
38
     */
39 16
    public function add(...$arguments): QueryBuilderInterface
40
    {
41 16
        if ($this->node instanceof ObjectNode) {
42 16
            return $this->addToObjectNode(...$arguments);
0 ignored issues
show
Bug introduced by
The call to addToObjectNode() misses a required argument $node.

This check looks for function calls that miss required arguments.

Loading history...
Documentation introduced by
$arguments is of type array<integer,array>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
43
        }
44
45 4
        return $this->addToArrayNode(...$arguments);
0 ignored issues
show
Documentation introduced by
$arguments is of type array<integer,array>, but the function expects a object<Saxulum\ElasticSe...lder\Node\AbstractNode>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
46
    }
47
48
    /**
49
     * @param AbstractNode $node
50
     * @param bool         $allowDefault
51
     *
52
     * @return QueryBuilderInterface
53
     *
54
     * @throws \Exception
55
     */
56 5 View Code Duplication
    public function addToArrayNode(AbstractNode $node, bool $allowDefault = false): QueryBuilderInterface
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
57
    {
58 5
        if (!$this->node instanceof ArrayNode) {
59 1
            throw new \Exception(sprintf('You cannot call %s on node type: %s', __FUNCTION__, get_class($this->node)));
60
        }
61
62 4
        $this->node->add($node, $allowDefault);
63 4
        $this->reassignParent($node);
64
65 4
        return $this;
66
    }
67
68
    /**
69
     * @param string       $key
70
     * @param AbstractNode $node
71
     * @param bool         $allowDefault
72
     *
73
     * @return QueryBuilderInterface
74
     *
75
     * @throws \Exception
76
     */
77 17 View Code Duplication
    public function addToObjectNode(string $key, AbstractNode $node, bool $allowDefault = false): QueryBuilderInterface
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
78
    {
79 17
        if (!$this->node instanceof ObjectNode) {
80 1
            throw new \Exception(sprintf('You cannot call %s on node type: %s', __FUNCTION__, get_class($this->node)));
81
        }
82
83 17
        $this->node->add($key, $node, $allowDefault);
84 17
        $this->reassignParent($node);
85
86 17
        return $this;
87
    }
88
89
    /**
90
     * @param AbstractNode $node
91
     */
92 17
    private function reassignParent(AbstractNode $node)
93
    {
94 17
        if ($node instanceof ArrayNode || $node instanceof ObjectNode) {
95 17
            $this->node = $node;
96
        }
97 17
    }
98
99
    /**
100
     * @return QueryBuilderInterface
101
     *
102
     * @throws \Exception
103
     */
104 2
    public function end(): QueryBuilderInterface
105
    {
106 2
        if (null === $this->node = $this->node->getParent()) {
107 1
            throw new \Exception(sprintf('You cannot call %s on main node', __FUNCTION__));
108
        }
109
110 1
        return $this;
111
    }
112
113
    /**
114
     * @return ArrayNode
115
     */
116 5
    public function arrayNode(): ArrayNode
117
    {
118 5
        return new ArrayNode();
119
    }
120
121
        /**
122
     * @param bool|null
123
     * @return BoolNode
124
     */
125 1
    public function boolNode($value = null): BoolNode
126
    {
127 1
        return new BoolNode($value);
128
    }
129
130
    /**
131
     * @param float|null
132
     * @return FloatNode
133
     */
134 1
    public function floatNode($value = null): FloatNode
135
    {
136 1
        return new FloatNode($value);
137
    }
138
139
    /**
140
     * @param int|null
141
     * @return IntNode
142
     */
143 4
    public function intNode($value = null): IntNode
144
    {
145 4
        return new IntNode($value);
146
    }
147
148
    /**
149
     * @return ObjectNode
150
     */
151 16
    public function objectNode(): ObjectNode
152
    {
153 16
        return new ObjectNode();
154
    }
155
156
    /**
157
     * @deprecated use boolNode|floatNode|intNode|stringNode
158
     * @param string|float|int|bool|null $value
159
     * @return ScalarNode
160
     */
161 1
    public function scalarNode($value = null): ScalarNode
162
    {
163 1
        return new ScalarNode($value);
0 ignored issues
show
Deprecated Code introduced by
The class Saxulum\ElasticSearchQueryBuilder\Node\ScalarNode has been deprecated with message: use BoolNode|FloatNode|IntNode|StringNode

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
164
    }
165
166
    /**
167
     * @param string|null
168
     * @return StringNode
169
     */
170 13
    public function stringNode($value = null): StringNode
171
    {
172 13
        return new StringNode($value);
173
    }
174
175
    /**
176
     * @return \stdClass|null
177
     */
178 16
    public function serialize()
179
    {
180 16
        return $this->rootNode->serialize();
181
    }
182
183
    /**
184
     * @param boolean $beautify
185
     * @return string
186
     */
187 16
    public function json(bool $beautify = false): string
188
    {
189 16
        if (null === $serialized = $this->serialize()) {
190 2
            return '';
191
        }
192
193 14
        if ($beautify) {
194 1
            return json_encode($serialized, JSON_PRETTY_PRINT);
195
        }
196
197 13
        return json_encode($serialized);
198
    }
199
}
200