Completed
Push — master ( 9ebf95...bdef40 )
by Maxence
02:13
created

SearchRequest::cleanSearch()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 15
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 15
rs 9.4285
cc 3
eloc 9
nc 3
nop 0
1
<?php
2
/**
3
 * FullTextSearch - Full text search framework for Nextcloud
4
 *
5
 * This file is licensed under the Affero General Public License version 3 or
6
 * later. See the COPYING file.
7
 *
8
 * @author Maxence Lange <[email protected]>
9
 * @copyright 2018
10
 * @license GNU AGPL version 3 or any later version
11
 *
12
 * This program is free software: you can redistribute it and/or modify
13
 * it under the terms of the GNU Affero General Public License as
14
 * published by the Free Software Foundation, either version 3 of the
15
 * License, or (at your option) any later version.
16
 *
17
 * This program is distributed in the hope that it will be useful,
18
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
 * GNU Affero General Public License for more details.
21
 *
22
 * You should have received a copy of the GNU Affero General Public License
23
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
24
 *
25
 */
26
27
namespace OCA\FullTextSearch\Model;
28
29
use OCA\FullTextSearch\Service\MiscService;
30
31
class SearchRequest implements \JsonSerializable {
32
33
	/** @var array */
34
	private $providers;
35
36
	/** @var string */
37
	private $search;
38
39
	/** @var int */
40
	private $page = 1;
41
42
	/** @var int */
43
	private $size = 10;
44
45
	/** @var string */
46
	private $author;
47
48
	/** @var array */
49
	private $tags;
50
51
	/** @var array */
52
	private $options;
53
54
	/** @var array */
55
	private $parts = [];
56
57
	/** @var array */
58
	private $fields = [];
59
60
	/** @var array */
61
	private $limitFields = [];
62
63
	/** @var array */
64
	private $wildcardFields = [];
65
66
	/** @var array */
67
	private $wildcardQueries = [];
68
69
	/** @var array */
70
	private $wildcardFilters = [];
71
72
	/** @var array */
73
	private $regexFilters = [];
74
75
76
	/**
77
	 * SearchRequest constructor.
78
	 */
79
	public function __construct() {
80
	}
81
82
83
	/**
84
	 * @return array
85
	 */
86
	public function getProviders() {
87
		return $this->providers;
88
	}
89
90
	/**
91
	 * @param string|array $providers
92
	 */
93
	public function setProviders($providers) {
94
		if (!is_array($providers)) {
95
			$providers = [$providers];
96
		}
97
98
		$this->providers = $providers;
99
	}
100
101
102
	/**
103
	 * @return string
104
	 */
105
	public function getAuthor() {
106
		return $this->author;
107
	}
108
109
	/**
110
	 * @param string $author
111
	 */
112
	public function setAuthor($author) {
113
		$this->author = $author;
114
	}
115
116
117
	/**
118
	 * @return string
119
	 */
120
	public function getSearch() {
121
		return $this->search;
122
	}
123
124
	/**
125
	 * @param string $search
126
	 */
127
	public function setSearch($search) {
128
		$this->search = $search;
129
	}
130
131
132
	/**
133
	 *
134
	 */
135
	public function cleanSearch() {
136
		$search = trim(str_replace('  ', ' ', $this->getSearch()));
137
138
		preg_match_all('/[^?]"(?:\\\\.|[^\\\\"])*"|\S+/', " $search ", $words);
139
		$searchItems = [];
140
		foreach ($words[0] as $word) {
141
			if ($this->searchQueryOptions($word)) {
142
				continue;
143
			}
144
145
			$searchItems[] = $word;
146
		}
147
148
		$this->setSearch(implode(" ", $searchItems));
149
	}
150
151
152
	/**
153
	 * @param $word
154
	 *
155
	 * @return bool
156
	 */
157
	private function searchQueryOptions($word) {
158
		if (($pos = strpos($word, ':')) === false) {
159
			return false;
160
		}
161
162
		list($kw, $value) = explode(':', $word, 2);
163
164
		$options = ['is', 'show'];
165
		if (in_array($kw, $options)) {
166
			$this->addOption($kw . '_' . $value, '1');
167
168
			return true;
169
		}
170
171
		$valuedOptions = ['in'];
172
		if (in_array($kw, $valuedOptions)) {
173
			$this->addMultipleOption($kw, $value);
174
175
			return true;
176
		}
177
178
		return false;
179
	}
180
181
182
	/**
183
	 * @return int
184
	 */
185
	public function getPage() {
186
		return $this->page;
187
	}
188
189
	/**
190
	 * @param int $page
191
	 */
192
	public function setPage($page) {
193
		if ($page < 1) {
194
			$page = 1;
195
		}
196
197
		$this->page = $page;
198
	}
199
200
201
	/**
202
	 * @return int
203
	 */
204
	public function getSize() {
205
		return $this->size;
206
	}
207
208
	/**
209
	 * @param int $size
210
	 */
211
	public function setSize($size) {
212
		$this->size = $size;
213
	}
214
215
216
	/**
217
	 * @return array
218
	 */
219
	public function getOptions() {
220
		return $this->options;
221
	}
222
223
	/**
224
	 * @param array $options
225
	 */
226
	public function setOptions($options) {
227
		$this->options = $options;
228
	}
229
230
	/**
231
	 * @param $key
232
	 * @param $value
233
	 *
234
	 * @return $this
235
	 */
236
	public function addOption($key, $value) {
237
		$this->options[$key] = $value;
238
239
		return $this;
240
	}
241
242
	/**
243
	 * @param $key
244
	 * @param $value
245
	 *
246
	 * @return $this
247
	 */
248
	public function addMultipleOption($key, $value) {
249
		if (!array_key_exists($key, $this->options)) {
250
			$this->options[$key] = [];
251
		}
252
253
		$this->options[$key][] = $value;
254
255
		return $this;
256
	}
257
258
	/**
259
	 * @param string $option
260
	 *
261
	 * @return mixed|string
262
	 */
263
	public function getOption($option) {
264
		if (array_key_exists($option, $this->options)) {
265
			return $this->options[$option];
266
		}
267
268
		return '';
269
	}
270
271
272
	/**
273
	 * @param array $parts
274
	 *
275
	 * @return $this
276
	 */
277
	public function setParts($parts) {
278
		$this->parts = $parts;
279
280
		return $this;
281
	}
282
283
	/**
284
	 * @return array
285
	 */
286
	public function getParts() {
287
		return $this->parts;
288
	}
289
290
291
	/**
292
	 * @return array
293
	 */
294
	public function getFields() {
295
		return $this->fields;
296
	}
297
298
	/**
299
	 * @param array $fields
300
	 *
301
	 * @return $this
302
	 */
303
	public function setFields($fields) {
304
		$this->fields = $fields;
305
306
		return $this;
307
	}
308
309
310
	/**
311
	 * @param $field
312
	 *
313
	 * @return $this
314
	 */
315
	public function limitToField($field) {
316
		array_push($this->limitFields, $field);
317
318
		return $this;
319
	}
320
321
	/**
322
	 * @return array
323
	 */
324
	public function getLimitFields() {
325
		return $this->limitFields;
326
	}
327
328
329
	/**
330
	 * @param $field
331
	 *
332
	 * @return $this
333
	 */
334
	public function addField($field) {
335
		$this->fields[] = $field;
336
337
		return $this;
338
	}
339
340
341
	/**
342
	 * @param string $tag
343
	 */
344
	public function addTag($tag) {
345
		$this->tags[] = $tag;
346
	}
347
348
	/**
349
	 * @return array
350
	 */
351
	public function getTags() {
352
		return $this->tags;
353
	}
354
355
	/**
356
	 * @param array $tags
357
	 */
358
	public function setTags($tags) {
359
		$this->tags = $tags;
360
	}
361
362
363
	/**
364
	 * @param array $query
0 ignored issues
show
Bug introduced by
There is no parameter named $query. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
365
	 *
366
	 * @return $this
367
	 */
368
	public function addWildcardField($field) {
369
		$this->wildcardFields[] = $field;
370
371
		return $this;
372
	}
373
374
	/**
375
	 * @return array
376
	 */
377
	public function getWildcardFields() {
378
		return $this->wildcardFields;
379
	}
380
381
382
	/**
383
	 * @param array $query
0 ignored issues
show
Bug introduced by
There is no parameter named $query. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
384
	 *
385
	 * @return $this
386
	 */
387
	public function addWildcardQuery($field) {
0 ignored issues
show
Unused Code introduced by
The parameter $field is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
388
		$this->addWildcardQueries([$query]);
0 ignored issues
show
Bug introduced by
The variable $query does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
389
390
		return $this;
391
	}
392
393
	/**
394
	 * @param array $query
395
	 *
396
	 * @return $this
397
	 */
398
	public function addWildcardQueries($query) {
399
		array_push($this->wildcardQueries, $query);
400
401
		return $this;
402
	}
403
404
	/**
405
	 * @return array
406
	 */
407
	public function getWildcardQueries() {
408
		return $this->wildcardQueries;
409
	}
410
411
412
	/**
413
	 * @param array $filter
414
	 *
415
	 * @return $this
416
	 */
417
	public function addWildcardFilter($filter) {
418
		$this->addWildcardFilters([$filter]);
419
420
		return $this;
421
	}
422
423
	/**
424
	 * @param array $filters
425
	 *
426
	 * @return $this
427
	 */
428
	public function addWildcardFilters($filters) {
429
		array_push($this->wildcardFilters, $filters);
430
431
		return $this;
432
	}
433
434
	/**
435
	 * @return array
436
	 */
437
	public function getWildcardFilters() {
438
		return $this->wildcardFilters;
439
	}
440
441
442
	/**
443
	 * @param array $filter
444
	 *
445
	 * @return $this
446
	 */
447
	public function addRegexFilter($filter) {
448
		$this->addRegexFilters([$filter]);
449
450
		return $this;
451
	}
452
453
	/**
454
	 * @param array $filters
455
	 *
456
	 * @return $this
457
	 */
458
	public function addRegexFilters($filters) {
459
		array_push($this->regexFilters, $filters);
460
461
		return $this;
462
	}
463
464
	/**
465
	 * @return array
466
	 */
467
	public function getRegexFilters() {
468
		return $this->regexFilters;
469
	}
470
471
472
	/**
473
	 * @return array
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use array<string,array|string|integer>.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
474
	 */
475
	public function jsonSerialize() {
476
		return [
477
			'providers' => $this->getProviders(),
478
			'author'    => $this->getAuthor(),
479
			'search'    => $this->getSearch(),
480
			'page'      => $this->getPage(),
481
			'size'      => $this->getSize(),
482
			'parts'     => $this->getParts(),
483
			'options'   => $this->getOptions(),
484
			'tags'      => $this->getTags()
485
		];
486
	}
487
488
489
	/**
490
	 * @param string $json
491
	 *
492
	 * @return SearchRequest
493
	 */
494
	public static function fromJSON($json) {
495
		return self::fromArray(json_decode($json, true));
496
	}
497
498
	/**
499
	 * @param array $arr
500
	 *
501
	 * @return SearchRequest
502
	 */
503
	public static function fromArray($arr) {
504
		$request = new SearchRequest();
505
		$request->setProviders($arr['providers']);
506
		$request->setAuthor(MiscService::get($arr, 'author', ''));
507
		$request->setSearch(MiscService::get($arr, 'search', ''));
508
		$request->setPage(MiscService::get($arr, 'page', 0));
509
		$request->setParts(MiscService::get($arr, 'parts', []));
0 ignored issues
show
Documentation introduced by
array() is of type 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...
510
		$request->setSize(MiscService::get($arr, 'size', 10));
511
		$request->setOptions(MiscService::get($arr, 'options', []));
0 ignored issues
show
Documentation introduced by
array() is of type 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...
512
		$request->setTags(MiscService::get($arr, 'tags', []));
0 ignored issues
show
Documentation introduced by
array() is of type 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...
513
514
		return $request;
515
	}
516
517
518
}