Completed
Pull Request — master (#12)
by Adam
04:47 queued 01:24
created

Search::fuzzy()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 5
ccs 3
cts 3
cp 1
rs 9.4285
cc 1
eloc 3
nc 1
nop 2
crap 1
1
<?php
2
3
namespace BestServedCold\LaravelZendSearch\Lucene;
4
5
use ZendSearch\Lucene\Index\Term;
6
use ZendSearch\Lucene\Search\Query\Fuzzy;
7
use ZendSearch\Lucene\Search\Query\MultiTerm;
8
use ZendSearch\Lucene\Search\Query\Phrase;
9
use ZendSearch\Lucene\Search\Query\Wildcard;
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
    /**
21
     * @var Index $index
22
     */
23
    protected $index;
24
25
    /**
26
     * @var Query $query
27
     */
28
    protected $query;
29
30
    /**
31
     * @var string|boolean $path
32
     */
33
    private $path;
34
35
    /**
36
     * @var int $limit
37
     */
38
    private $limit = 25;
39
40
    /**
41
     * @var int $offset
42
     */
43
    private $offset = 0;
44
45
    /**
46
     * @var Boolean
47
     */
48
    private static $boolean;
49
50
    /**
51
     * Search constructor.
52
     *
53
     * @param Index $index
54
     * @param Query $query
55
     */
56 29
    public function __construct(Index $index, Query $query)
57
    {
58 29
        $this->index = $index;
59 29
        $this->query = $query;
60 29
        QueryParser::setDefaultEncoding('UTF-8');
61 29
    }
62
63
    /**
64
     * @param  $name
65
     * @param  $arguments
66
     * @return $this
67
     * @throws \BadMethodCallException
68
     */
69 2
    public function __call($name, $arguments)
70
    {
71 2
        if (method_exists($this->query, $name)) {
72 1
            $this->query->$name($arguments);
73 1
            return $this;
74
        }
75
76 1
        throw new \BadMethodCallException;
77
    }
78
79
    /**
80
     * @param  integer $limit
81
     * @return $this
82
     */
83 1
    public function limit($limit)
84
    {
85 1
        $this->limit = $limit;
86 1
        return $this;
87
    }
88
89
    /**
90
     * @param  integer $offset
91
     * @return $this
92
     */
93 1
    public function offset($offset)
94
    {
95 1
        $this->offset = $offset;
96 1
        return $this;
97
    }
98
99
    /**
100
     * @param bool|string $path
101
     * @return $this
102
     */
103 18
    public function path($path = false)
104
    {
105 18
        $this->path = $path;
106 18
        return $this;
107
    }
108
109
    /**
110
     * @param $string
111
     * @return $this
112
     */
113 1
    public function raw($string)
114
    {
115 1
        $this->query->add(QueryParser::parse($string));
116 1
        return $this;
117
    }
118
119
    /**
120
     * @param $string
121
     * @param null|string $field
122
     * @param null        $offsets
123
     * @return $this
124
     * @return $this
125
     */
126 1
    public function phrase($string, $field = null, $offsets = null)
127
    {
128 1
        $this->query->add(new Phrase(explode(' ', $string), $offsets, $field));
129 1
        return $this;
130
    }
131
132
    /**
133
     * @param $string
134
     * @param null|string   $field
135
     * @return $this
136
     */
137 1
    public function fuzzy($string, $field = null)
138
    {
139 1
        $this->query->add(new Fuzzy($this->indexTerm($field, $string)));
140 1
        return $this;
141
    }
142
143
    /**
144
     * @param $string
145
     * @param null|string   $field
146
     * @return Term
147
     */
148 2
    protected function indexTerm($string, $field = null)
149
    {
150 2
        return new Term(strtolower($string), $field);
151
    }
152
153
    /**
154
     * @param  $string
155
     * @param  null|string $field
156
     * @return $this
157
     */
158 1
    public function wildcard($string, $field = null)
159
    {
160 1
        $this->query->add(new Wildcard($this->indexTerm($string, $field)));
161 1
        return $this;
162
    }
163
164
    /**
165
     * Where
166
     *
167
     * A helper method to access phrase or to pass multiple fields.  Phrase doesn't "match" exactly and
168
     * allows searching within the text field rather than matching the whole string.
169
     *
170
     * @param boolean|$string
171
     * @param null|string $field
172
     * @return $this|bool
173
     */
174 1
    public function where($string, $field = null)
175
    {
176 1
        is_array($field)
177 1
            ? $this->multiTerm($this->mapWhereArray($string, $field))
178 1
            : $this->phrase($string, $field);
179
180 1
        return $this;
181
    }
182
183
    /**
184
     * Match
185
     *
186
     * Provides an exact pattern match.
187
     *
188
     * @param  $string
189
     * @param  string $field
190
     * @return $this
191
     */
192
    public function match($string, $field = null)
193
    {
194
        $this->query->add($this->term($string, $field));
195
        return $this;
196
    }
197
198
    /**
199
     * @param array $terms
200
     * @return $this
201
     */
202 1
    public function multiTerm(array $terms)
203
    {
204 1
        $multiTerm = new MultiTerm;
205 1
        foreach ($terms as $field => $value) {
206 1
            $multiTerm->addTerm($this->indexTerm($value, $field), null);
207 1
        }
208
209 1
        $this->query->add($multiTerm);
210
211 1
        return $this;
212
    }
213
214
    /**
215
     * @param string $string
216
     * @param array  $array
217
     * @return mixed
218
     */
219 1
    private function mapWhereArray($string, array $array)
220
    {
221 1
        return array_map(
222
            function() use ($string) {
223 1
                return $string;
224 1
            },
225 1
            array_flip($array)
226 1
        );
227
    }
228
229
    /**
230
     * @param string         $string
231
     * @param string|null $field
232
     * @return QueryTerm
233
     */
234 1
    public function term($string, $field = null)
235
    {
236 1
        return new QueryTerm($this->indexTerm($string, $field));
237
    }
238
239
    /**
240
     * @return mixed
241
     */
242 1
    public function hits()
243
    {
244 1
        $index = $this->index->limit($this->limit + $this->offset)->open($this->path)->get();
245 1
        self::$boolean = $this->query->getBoolean();
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->query->getBoolean() of type object<ZendSearch\Lucene\Search\Query\Boolean> is incompatible with the declared type boolean of property $boolean.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
246 1
        return $this->slice($this->mapIds($index->find(self::$boolean)));
247
    }
248
249
    /**
250
     * Slice
251
     *
252
     * This may look nasty, but there really isn't another way of offsetting results Lucene, and nor would
253
     * you want to really, that's not what it's designed for.  It will be quick up to a thousand and after
254
     * that you should be asking the user to "refine their search".
255
     *
256
     * @param  mixed $hits
257
     * @return array
258
     */
259 1
    public function slice($hits)
260
    {
261 1
        return $this->offset ? array_slice($hits, $this->offset) : $hits;
262
    }
263
264
    /**
265
     * @param  array|QueryHit $array
266
     * @return mixed
267
     */
268 2
    private function mapIds($array)
269
    {
270 2
        return array_map(
271 2
            function(QueryHit $hit) {
272 2
                return isset($hit->xref_id) ? $hit->xref_id : null;
273 2
            },
274
            $array
275 2
        );
276
    }
277
278
    /**
279
     * @return boolean
280
     */
281 1
    public static function getLastQuery()
282
    {
283 1
        return self::$boolean;
284
    }
285
}
286