Passed
Push — develop ( 22eea4...4debb7 )
by Sander
01:43
created

PosttypeBuilder::getGrammar()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Sanderdekroon\Parlant\Builder;
4
5
use InvalidArgumentException;
6
use Sanderdekroon\Parlant\Container;
7
use Sanderdekroon\Parlant\Grammar\PosttypeGrammar;
8
use Sanderdekroon\Parlant\Compiler\PosttypeCompiler;
9
use Sanderdekroon\Parlant\Configurator\ParlantConfigurator;
10
use Sanderdekroon\Parlant\Configurator\ConfiguratorInterface;
11
12
class PosttypeBuilder implements BuilderInterface
13
{
14
    use BuildsQueries, QueriesMeta, QueriesTaxonomies;
15
16
17
    protected $grammar;
18
    
19
    protected $compiler;
20
    protected $bindings;
21
22
    protected $configuration;
23
24
25 32
    public function __construct(Container $container = null)
26
    {
27 32
        $this->grammar = new PosttypeGrammar; // Replace via DI
28 32
        $this->compiler = new PosttypeCompiler($this->getGrammar()); // Replace via DI
29 32
        $this->bindings = $container ?: new Container;
30 32
    }
31
32
33
    public function configure($configuration)
34
    {
35
        // If the supplied configuration is an instance of the ConfiguratorInterface
36
        // we can add it directly to the PosttypeBuilder. This way a developer
37
        // can supply their own configurator implementation.
38
        if ($configuration instanceof ConfiguratorInterface) {
39
            return $this->configuration = $configuration;
40
        }
41
42
        // If the developer wants to add additional configuration but has not
43
        // supplied an instance of the ConfiguratorInterface, we'll create
44
        // a new instance of our own implementation of the configurator.
45
        if (is_null($this->getConfiguration())) {
46
            $this->configuration = new ParlantConfigurator;
47
        }
48
49
        return $this->configuration->add($configuration);
50
    }
51
52
53 3
    public function setConfig($key, $value)
54
    {
55 3
        if ($this->requiresConfiguration()) {
56
            $this->applyDefaultConfiguration();
57
        }
58
59 3
        return $this->updateConfiguration($key, $value);
60
    }
61
62
63 3
    protected function updateConfiguration($key, $value)
64
    {
65 3
        $this->getConfiguration()->add($key, $value);
66
67 3
        return $this;
68
    }
69
70
    /**
71
     * Determine if the builder requires additional configuration.
72
     * @return bool
73
     */
74 32
    protected function requiresConfiguration()
75
    {
76 32
        return is_null($this->getConfiguration());
77
    }
78
79
    /**
80
     * Fill the configuration property with an instance of our ParlantConfigurator.
81
     * @return ParlantConfigurator
82
     */
83 32
    protected function applyDefaultConfiguration()
84
    {
85 32
        return $this->configuration = new ParlantConfigurator;
86
    }
87
88
    /**
89
     * Set the posttype the developer is querying.
90
     * @param  string $posttype
91
     * @return $this
92
     */
93 32
    public function type($posttype)
94
    {
95
        // Since this is the entry method (for now), we'll assume the developer allready
96
        // has supplied some form of configuration. If nothing is found, we'll create a
97
        // new instance of our ParlantConfigurator which sets some default settings.
98 32
        if ($this->requiresConfiguration()) {
99 32
            $this->applyDefaultConfiguration();
100
        }
101
102 32
        $this->setBinding('post_type', $posttype);
103 32
        return $this;
104
    }
105
106
107 4
    public function where($column, $operator = null, $value = null, $boolean = 'and')
108
    {
109
        // If the column is an array, we will assume it is an array of key-value pairs
110
        // and can add them each as a where clause. We will maintain the boolean we
111
        // received when the method was called and pass it into the nested where.
112 4
        if (is_array($column)) {
113
            return $this->addArrayOfWheres($column, $boolean);
0 ignored issues
show
Unused Code introduced by
The call to Sanderdekroon\Parlant\Bu...der::addArrayOfWheres() has too many arguments starting with $boolean. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

113
            return $this->/** @scrutinizer ignore-call */ addArrayOfWheres($column, $boolean);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
114
        }
115
116
        // Here we will make some assumptions about the operator. If only 2 values are
117
        // passed to the method, we will assume that the operator is an equals sign
118
        // and keep going. Otherwise, we'll require the operator to be passed in.
119 4
        list($value, $operator) = $this->prepareValueAndOperator(
120 4
            $value,
121 4
            $operator,
122 4
            (func_num_args() == 2 || is_null($value)) //Is this the best solution?
123
        );
124
125
        // If the given operator is not found in the list of valid operators we will
126
        // assume that the developer is just short-cutting the '=' operators and
127
        // we will set the operators to '=' and set the values appropriately.
128 3
        if ($this->invalidOperator($operator)) {
129
            list($value, $operator) = [$operator, '='];
130
        }
131
132
133
        // If the value is "null", we will just assume the developer wants to add a
134
        // where null clause to the query. So, we will allow a short-cut here to
135
        // that method for convenience so the developer doesn't have to check.
136
        // if (is_null($value)) {
137
        //     return $this->whereNull($column, $boolean, $operator != '=');
138
        // }
139
140
        // Now that we are working with just a simple query we can put the elements
141
        // in our array and add the query binding to our array of bindings that
142
        // will be bound to each SQL statements when it is finally executed.
143 3
        $type = 'Basic';
144
145 3
        $this->appendBinding('wheres', compact(
146 3
            'type',
147 3
            'column',
148 3
            'operator',
149 3
            'value',
150 3
            'boolean'
151
        ));
152
153 3
        return $this;
154
    }
155
156
    /**
157
     * Add an array of where statements. The array should contain a numeric array
158
     * where the values can be used as arguments for the where() method.
159
     * @param array $wheres
160
     */
161
    protected function addArrayOfWheres($wheres)
162
    {
163
        foreach ($wheres as $where) {
164
            $this->where(...$where);
0 ignored issues
show
Bug introduced by
$where is expanded, but the parameter $column of Sanderdekroon\Parlant\Bu...osttypeBuilder::where() does not expect variable arguments. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

164
            $this->where(/** @scrutinizer ignore-type */ ...$where);
Loading history...
165
        }
166
167
        return $this;
168
    }
169
170
    /**
171
     * Limit the number of posts to return to the $number
172
     * @param  int $number
173
     * @return $this
174
     */
175 1
    public function limit($number)
176
    {
177 1
        $this->setBinding('limit', (int)$number);
178 1
        return $this;
179
    }
180
181
    /**
182
     * Set the post offset.
183
     * @param  int $number
184
     * @return $this
185
     */
186 1
    public function offset($number)
187
    {
188 1
        $this->setBinding('offset', (int)$number);
189 1
        return $this;
190
    }
191
192
    /**
193
     * Prepare the value and operator. If $useDefault is true, return the default operator (=)
194
     * Throws an exception if the operator is not supported with the current grammer.
195
     * @param  mixed        $value
196
     * @param  string       $operator
197
     * @param  boolean      $useDefault
198
     * @throws InvalidArgumentException
199
     * @return array
200
     */
201 16
    protected function prepareValueAndOperator($value, $operator, $useDefault = false, $termDefault = false)
202
    {
203 16
        if ($useDefault) {
204 8
            return [$operator, $termDefault ? 'IN' : '='];
205
        }
206
207 9
        if ($this->invalidOperator($operator) && !is_null($value)) {
208 2
            throw new InvalidArgumentException('Illegal operator and value combination.');
209
        }
210
211 7
        return [$value, $operator];
212
    }
213
214 32
    protected function getGrammar()
215
    {
216 32
        return $this->grammar;
217
    }
218
219 25
    protected function getCompiler()
220
    {
221 25
        return $this->compiler;
222
    }
223
224 32
    protected function getBindings()
225
    {
226 32
        return $this->bindings;
227
    }
228
229 32
    protected function getConfiguration()
230
    {
231 32
        return $this->configuration;
232
    }
233
234
    /**
235
     * Determine if an operator is invalid or unsupported
236
     * @param  string $operator
237
     * @return bool
238
     */
239 16
    private function invalidOperator($operator)
240
    {
241 16
        return !in_array($operator, $this->getGrammar()->getOperators());
242
    }
243
244
    /**
245
     * Set an query binding
246
     * @param  string    $key   @todo validate if the $key is valid with the grammar
247
     * @param  mixed     $data
248
     * @return bool
249
     */
250 32
    private function setBinding($key, $data)
251
    {
252 32
        return $this->getBindings()->bind($key, $data);
253
    }
254
255
    /**
256
     * Append an query binding
257
     * @param  string   $key  @todo validate if the $key is valid with the grammar
258
     * @param  mixed    $data
259
     * @return bool
260
     */
261 14
    private function appendBinding($key, $data)
262
    {
263 14
        return $this->getBindings()->append($key, $data);
264
    }
265
266
267 2
    private function getBinding($key)
0 ignored issues
show
Unused Code introduced by
The method getBinding() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
268
    {
269 2
        return $this->getBindings()->get($key);
270
    }
271
}
272