Passed
Push — master ( 099c87...4cfe3e )
by Christopher
07:03 queued 01:40
created

AbstractQuery::overwriteType()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 4
ccs 3
cts 3
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
namespace Triadev\Leopard\Business\Dsl;
3
4
use Illuminate\Database\Eloquent\Model;
5
use ONGR\ElasticsearchDSL\BuilderInterface;
6
use ONGR\ElasticsearchDSL\Query\Compound\BoolQuery;
7
use ONGR\ElasticsearchDSL\Search as OngrSearch;
8
use Triadev\Leopard\Busines\Dsl\Query\Specialized;
9
use Triadev\Leopard\Business\Dsl\Query\Compound;
10
use Triadev\Leopard\Business\Dsl\Query\TermLevel;
11
use Triadev\Leopard\Business\Dsl\Query\Fulltext;
12
use Triadev\Leopard\Business\Dsl\Query\Geo;
13
use Triadev\Leopard\Business\Dsl\Query\Joining;
14
use Triadev\Leopard\Business\Dsl\Query\InnerHit;
15
use Triadev\Leopard\Business\Dsl\Search as SearchDsl;
16
use Triadev\Leopard\Business\Filler\EloquentFiller;
17
use Triadev\Leopard\Business\Helper\IsModelSearchable;
18
use Triadev\Leopard\Contract\ElasticsearchManagerContract;
19
use Triadev\Leopard\Contract\FillerContract;
20
use Triadev\Leopard\Facade\Leopard;
21
use Triadev\Leopard\Model\SearchResult;
22
use Triadev\Leopard\Searchable;
23
24
/**
25
 * Class AbstractQuery
26
 * @package Triadev\Leopard\Business\Dsl
27
 *
28
 * @method TermLevel termLevel()
29
 * @method Fulltext fulltext()
30
 * @method Geo geo()
31
 * @method Compound compound()
32
 * @method Joining joining()
33
 * @method Specialized specialized()
34
 * @method InnerHit innerHit()
35
 */
36
abstract class AbstractQuery
37
{
38
    use IsModelSearchable;
39
    
40
    /** @var OngrSearch */
41
    public $search;
42
    
43
    /** @var string */
44
    public $boolState = BoolQuery::MUST;
45
    
46
    /** @var string|null */
47
    private $index;
48
    
49
    /** @var string|null */
50
    private $type;
51
    
52
    /** @var Model|null */
53
    public $model;
54
    
55
    /** @var ElasticsearchManagerContract */
56
    private $manager;
57
    
58
    /**
59
     * BoolQuery constructor.
60
     * @param OngrSearch|null $search
61
     * @param Model|null $model
62
     */
63 36
    public function __construct(?OngrSearch $search = null, ?Model $model = null)
64
    {
65 36
        $this->search = $search ?: new OngrSearch();
66 36
        $this->model = $model;
67
    
68 36
        $this->manager = app()->make(ElasticsearchManagerContract::class);
69 36
    }
70
    
71
    /**
72
     * Overwrite default index
73
     *
74
     * @param string $index
75
     * @return AbstractQuery|Search
76
     */
77 3
    public function overwriteIndex(string $index) : AbstractQuery
78
    {
79 3
        $this->index = $index;
80 3
        return $this;
81
    }
82
    
83
    /**
84
     * Get index
85
     *
86
     * @return string
87
     */
88 1
    public function getIndex() : string
89
    {
90 1
        return $this->index ?: config('leopard.index');
91
    }
92
    
93
    /**
94
     * Overwrite default type
95
     *
96
     * @param string $type
97
     * @return AbstractQuery|Search
98
     */
99 3
    public function overwriteType(string $type) : AbstractQuery
100
    {
101 3
        $this->type = $type;
102 3
        return $this;
103
    }
104
    
105
    /**
106
     * Get type
107
     *
108
     * @return string|null
109
     */
110 1
    public function getType() : ?string
111
    {
112 1
        return $this->type;
113
    }
114
    
115
    /**
116
     * Add model
117
     *
118
     * @param Model|Searchable $model
119
     * @return AbstractQuery|Search
120
     *
121
     * @throws \InvalidArgumentException
122
     */
123 3
    public function model(Model $model) : AbstractQuery
124
    {
125 3
        $this->isModelSearchable($model);
126
        
127 2
        $this->model = $model;
128
        
129 2
        if (is_string($index = $model->getDocumentIndex())) {
130 2
            $this->overwriteIndex($index);
131
        }
132
        
133 2
        $this->overwriteType($model->getDocumentType());
0 ignored issues
show
Bug introduced by
It seems like $model->getDocumentType() can also be of type Illuminate\Database\Eloquent\Builder; however, parameter $type of Triadev\Leopard\Business...tQuery::overwriteType() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

133
        $this->overwriteType(/** @scrutinizer ignore-type */ $model->getDocumentType());
Loading history...
134
        
135 2
        return $this;
136
    }
137
    
138
    /**
139
     * To dsl
140
     *
141
     * @return array
142
     */
143 33
    public function toDsl() : array
144
    {
145 33
        return $this->search->toArray();
146
    }
147
    
148
    /**
149
     * Get search
150
     *
151
     * @return OngrSearch
152
     */
153 4
    public function getSearch() : OngrSearch
154
    {
155 4
        return $this->search;
156
    }
157
    
158
    /**
159
     * Get query
160
     *
161
     * @return BuilderInterface
162
     */
163 12
    public function getQuery() : BuilderInterface
164
    {
165 12
        return $this->search->getQueries();
166
    }
167
    
168
    /**
169
     * Get
170
     *
171
     * @param FillerContract|null $filler
172
     * @return SearchResult
173
     */
174 2
    public function get(?FillerContract $filler = null) : SearchResult
175
    {
176 2
        $searchResult = new SearchResult($this->getRaw());
177
        
178 2
        if ($this->model) {
179 1
            $filler = $filler ?: new EloquentFiller();
180 1
            $filler->fill($this->model, $searchResult);
181
        }
182
        
183 2
        return $searchResult;
184
    }
185
    
186
    /**
187
     * Get raw search result
188
     *
189
     * @return array
190
     */
191 2
    public function getRaw() : array
192
    {
193
        $params = [
194 2
            'index' => $this->index,
195 2
            'body' => $this->toDsl()
196
        ];
197
        
198 2
        if ($this->type) {
199
            $params['type'] = $this->type;
200
        }
201
        
202 2
        return $this->manager->searchStatement($params);
203
    }
204
    
205
    /**
206
     * Append
207
     *
208
     * @param BuilderInterface $query
209
     * @return AbstractQuery|TermLevel|Fulltext|Geo|SearchDsl|Joining|Specialized|InnerHit
210
     */
211 32
    public function append(BuilderInterface $query) : AbstractQuery
212
    {
213 32
        $this->search->addQuery($query, $this->boolState);
214 32
        return $this;
215
    }
216
    
217
    /**
218
     * Bool state: must
219
     *
220
     * @return AbstractQuery|TermLevel|Fulltext|Geo|SearchDsl|Joining|Specialized|InnerHit
221
     */
222 2
    public function must(): AbstractQuery
223
    {
224 2
        $this->boolState = BoolQuery::MUST;
225 2
        return $this;
226
    }
227
    
228
    /**
229
     * Bool state: must not
230
     *
231
     * @return AbstractQuery|TermLevel|Fulltext|Geo|SearchDsl|Joining|Specialized|InnerHit
232
     */
233 1
    public function mustNot(): AbstractQuery
234
    {
235 1
        $this->boolState = BoolQuery::MUST_NOT;
236 1
        return $this;
237
    }
238
    
239
    /**
240
     * Bool state: should
241
     *
242
     * @return AbstractQuery|TermLevel|Fulltext|Geo|SearchDsl|Joining|Specialized|InnerHit
243
     */
244 1
    public function should(): AbstractQuery
245
    {
246 1
        $this->boolState = BoolQuery::SHOULD;
247 1
        return $this;
248
    }
249
    
250
    /**
251
     * Bool state: filter
252
     *
253
     * @return AbstractQuery|TermLevel|Fulltext|Geo|SearchDsl|Joining|Specialized|InnerHit
254
     */
255 8
    public function filter(): AbstractQuery
256
    {
257 8
        $this->boolState = BoolQuery::FILTER;
258 8
        return $this;
259
    }
260
    
261
    /**
262
     * Search
263
     *
264
     * @param \Closure $search
265
     * @return AbstractQuery|TermLevel|Fulltext|Geo|Compound|Joining|Specialized|InnerHit
266
     */
267 1
    public function bool(\Closure $search) : AbstractQuery
268
    {
269 1
        $searchBuilder = new Search();
270 1
        $search($searchBuilder);
271
        
272 1
        $this->append($searchBuilder->getQuery());
273
        
274 1
        return $this;
275
    }
276
    
277
    /**
278
     * Call
279
     *
280
     * @param string $name
281
     * @param array $arguments
282
     *
283
     * @return AbstractQuery|null
284
     */
285
    public function __call(string $name, array $arguments)
286
    {
287
        $validFunctions = [
288
            'termLevel',
289
            'fulltext',
290
            'geo',
291
            'compound',
292
            'joining',
293
            'specialized',
294
            'innerHit'
295
        ];
296
        
297
        if (in_array($name, $validFunctions)) {
298
            return Leopard::search($this->search, $this->model)->$name();
299
        }
300
        
301
        return null;
302
    }
303
}
304