Completed
Push — master ( e76f82...f8c9ff )
by Adam
03:03
created

Search::hits()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 6
ccs 0
cts 4
cp 0
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 0
crap 2
1
<?php
2
3
namespace BestServedCold\LaravelZendSearch\Lucene;
4
5
use BestServedCold\LaravelZendSearch\Search\Wildcard;
6
use ZendSearch\Lucene\Index\Term;
7
use ZendSearch\Lucene\Search\Query\Fuzzy;
8
use ZendSearch\Lucene\Search\Query\MultiTerm;
9
use ZendSearch\Lucene\Search\Query\Phrase;
10
use ZendSearch\Lucene\Search\Query\Term as QueryTerm;
11
use ZendSearch\Lucene\Search\QueryHit;
12
use ZendSearch\Lucene\Search\QueryParser;
13
14
/**
15
 * Class Search
16
 * @package BestServedCold\LaravelZendSearch\Lucene
17
 */
18
class Search
19
{
20
    protected $index;
21
    protected $query;
22
    private $path;
23
    private $limit = 25;
24
25
    /**
26
     * Search constructor.
27
     *
28
     * @param Index $index
29
     * @param Query $query
30
     */
31 3
    public function __construct(Index $index, Query $query)
32
    {
33 3
        $this->index = $index;
34 3
        $this->query = $query;
35 3
    }
36
37
    /**
38
     * @param  $name
39
     * @param  $arguments
40
     * @return $this
41
     * @throws \BadMethodCallException
42
     */
43
    public function __call($name, $arguments)
44
    {
45
        if (method_exists($this, $name)) {
46
            return $this->$name($arguments);
47
        }
48
49
        if (method_exists($this->query, $name)) {
50
            $this->query->$name($arguments);
51
            return $this;
52
        }
53
54
        throw new \BadMethodCallException;
55
    }
56
57
    /**
58
     * @param $limit
59
     * @return $this
60
     */
61 1
    public function limit($limit)
62
    {
63 1
        $this->limit = $limit;
64 1
        return $this;
65
    }
66
67
    /**
68
     * @param bool $path
69
     * @return $this
70
     */
71 1
    public function path($path = false)
72
    {
73 1
        $this->path = $path;
74 1
        return $this;
75
    }
76
77
    /**
78
     * @param $string
79
     * @return $this
80
     */
81 1
    public function raw($string)
82
    {
83 1
        $this->query->add(QueryParser::parse($string));
84 1
        return $this;
85
    }
86
87
    /**
88
     * @param $string
89
     * @param bool   $field
90
     * @param null   $offsets
91
     * @return $this
92
     * @return $this
93
     */
94
    public function phrase($string, $field = false, $offsets = null)
95
    {
96
        $this->query->add(new Phrase(explode(' ', $string), $offsets, $field));
0 ignored issues
show
Documentation introduced by
$field is of type boolean, but the function expects a string|null.

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...
97
        return $this;
98
99
    }
100
101
    /**
102
     * @param $string
103
     * @param bool   $field
104
     * @return $this
105
     */
106
    public function fuzzy($string, $field = false)
107
    {
108
        $this->query->add(new Fuzzy($this->term($field, $string)));
109
        return $this;
110
    }
111
112
    /**
113
     * @param $string
114
     * @param bool   $field
115
     * @return Term
116
     */
117
    protected function term($string, $field = false)
118
    {
119
        return new Term(strtoupper($string), $field);
120
    }
121
122
    /**
123
     * @param $string
124
     * @param bool   $field
125
     * @param array  $options
126
     */
127
    public function wildcard($string, $field = false, $options = [ ])
128
    {
129
        $this->query->add((new Wildcard($field, $string, $options))->get());
130
    }
131
132
    /**
133
     * @param $string
134
     * @param bool|string $field
135
     * @return $this|bool
136
     * @todo  Work out why the search only works if the string is uppercase...
137
     */
138
    public function where($string, $field = false)
139
    {
140
        is_array($field)
141
            ? $this->multiTerm($this->mapWhereArray($string, $field))
142
            : $this->query->add($this->singleTerm($string, $field));
0 ignored issues
show
Bug introduced by
It seems like $field defined by parameter $field on line 138 can also be of type string; however, BestServedCold\LaravelZe...ne\Search::singleTerm() does only seem to accept boolean, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
143
144
        return $this;
145
    }
146
147
    /**
148
     * @param array $terms
149
     * @return $this
150
     */
151
    public function multiTerm(array $terms)
152
    {
153
        $multiTerm = new MultiTerm;
154
        foreach ($terms as $field => $value) {
155
            $multiTerm->addTerm($this->term($value, $field), $this->query->getSign());
0 ignored issues
show
Documentation introduced by
$field is of type integer|string, but the function expects a boolean.

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...
156
        }
157
158
        $this->query->add($multiTerm);
159
160
        return $this;
161
    }
162
163
    /**
164
     * @param $string
165
     * @param array  $array
166
     * @return mixed
167
     * @todo abstract this out
168
     */
169
    private function mapWhereArray($string, array $array)
170
    {
171
        return array_map(
172
            function() use ($string) {
173
                return $string;
174
            }, array_flip($array)
175
        );
176
    }
177
178
    /**
179
     * @param $string
180
     * @param $field
181
     * @return QueryTerm
182
     */
183
    public function singleTerm($string, $field = false)
184
    {
185
        return new QueryTerm($this->term($string, $field));
186
    }
187
188
    /**
189
     * @return mixed
190
     */
191
    public function hits()
192
    {
193
        return $this->mapIds(
194
            $this->index->limit($this->limit)->open($this->path)->get()->find($this->query->getBoolean())
0 ignored issues
show
Bug introduced by
It seems like $this->index->limit($thi...s->query->getBoolean()) targeting ZendSearch\Lucene\Index::find() can also be of type object<ZendSearch\Lucene\Search\QueryHit>; however, BestServedCold\LaravelZe...Lucene\Search::mapIds() does only seem to accept array, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
195
        );
196
    }
197
198
    /**
199
     * @param array $array
200
     * @return mixed
201
     * @todo abstract this out
202
     */
203
    private function mapIds(array $array)
204
    {
205
        return array_map(
206
            function(QueryHit $hit) {
207
                return $hit->id;
208
            }, $array
209
        );
210
    }
211
}
212