Completed
Push — master ( 4541a4...2fe9dd )
by Maxence
01:49
created

SearchRequest::addRegexFilter()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 5
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
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
	public $metaTags = [];
53
54
	/** @var array */
55
	public $subTags = [];
56
57
	/** @var array */
58
	private $options;
59
60
	/** @var array */
61
	private $parts = [];
62
63
	/** @var array */
64
	private $fields = [];
65
66
	/** @var array */
67
	private $limitFields = [];
68
69
	/** @var array */
70
	private $wildcardFields = [];
71
72
//	/** @var array */
73
//	private $wildcardQueries = [];
74
75
	/** @var array */
76
	private $wildcardFilters = [];
77
78
	/** @var array */
79
	private $regexFilters = [];
80
81
82
	/**
83
	 * SearchRequest constructor.
84
	 */
85
	public function __construct() {
86
	}
87
88
89
	/**
90
	 * @return array
91
	 */
92
	public function getProviders() {
93
		return $this->providers;
94
	}
95
96
	/**
97
	 * @param array $providers
98
	 */
99
	public function setProviders($providers) {
100
		$this->providers = $providers;
101
	}
102
103
104
	/**
105
	 * @return string
106
	 */
107
	public function getAuthor() {
108
		return $this->author;
109
	}
110
111
	/**
112
	 * @param string $author
113
	 */
114
	public function setAuthor($author) {
115
		$this->author = $author;
116
	}
117
118
119
	/**
120
	 * @return string
121
	 */
122
	public function getSearch() {
123
		return $this->search;
124
	}
125
126
	/**
127
	 * @param string $search
128
	 */
129
	public function setSearch($search) {
130
		$this->search = $search;
131
	}
132
133
134
	/**
135
	 *
136
	 */
137
	public function cleanSearch() {
138
		$search = trim(str_replace('  ', ' ', $this->getSearch()));
139
140
		preg_match_all('/[^?]"(?:\\\\.|[^\\\\"])*"|\S+/', " $search ", $words);
141
		$searchItems = [];
142
		foreach ($words[0] as $word) {
143
			if ($this->searchQueryOptions($word)) {
144
				continue;
145
			}
146
147
			$searchItems[] = $word;
148
		}
149
150
		$this->setSearch(implode(" ", $searchItems));
151
	}
152
153
154
	/**
155
	 * @param $word
156
	 *
157
	 * @return bool
158
	 */
159
	private function searchQueryOptions($word) {
160
		if (($pos = strpos($word, ':')) === false) {
161
			return false;
162
		}
163
164
		list($kw, $value) = explode(':', $word, 2);
165
166
		$options = ['is', 'show'];
167
		if (in_array($kw, $options)) {
168
			$this->addOption($kw . '_' . $value, '1');
169
170
			return true;
171
		}
172
173
		$valuedOptions = ['in', 'meta'];
174
		if (in_array($kw, $valuedOptions)) {
175
			$this->addMultipleOption($kw, $value);
176
177
			return true;
178
		}
179
180
		return false;
181
	}
182
183
184
	/**
185
	 * @return int
186
	 */
187
	public function getPage() {
188
		return $this->page;
189
	}
190
191
	/**
192
	 * @param int $page
193
	 */
194
	public function setPage($page) {
195
		if ($page < 1) {
196
			$page = 1;
197
		}
198
199
		$this->page = $page;
200
	}
201
202
203
	/**
204
	 * @return int
205
	 */
206
	public function getSize() {
207
		return $this->size;
208
	}
209
210
	/**
211
	 * @param int $size
212
	 */
213
	public function setSize($size) {
214
		$this->size = $size;
215
	}
216
217
218
	/**
219
	 * @return array
220
	 */
221
	public function getOptions() {
222
		return $this->options;
223
	}
224
225
	/**
226
	 * @param array $options
227
	 */
228
	public function setOptions($options) {
229
		$this->options = $options;
230
	}
231
232
	/**
233
	 * @param $key
234
	 * @param $value
235
	 *
236
	 * @return $this
237
	 */
238
	public function addOption($key, $value) {
239
		$this->options[$key] = $value;
240
241
		return $this;
242
	}
243
244
	/**
245
	 * @param string $k
246
	 * @param array $array
247
	 *
248
	 * @return SearchRequest
249
	 */
250
	public function addOptionArray($k, $array) {
251
		$this->options[$k] = $array;
252
253
		return $this;
254
	}
255
256
	/**
257
	 * @param string $k
258
	 * @param bool $bool
259
	 *
260
	 * @return SearchRequest
261
	 */
262
	public function addOptionBool($k, $bool) {
263
		$this->options[$k] = $bool;
264
265
		return $this;
266
	}
267
268
	/**
269
	 * @param $key
270
	 * @param $value
271
	 *
272
	 * @return $this
273
	 */
274
	public function addMultipleOption($key, $value) {
275
		if (!array_key_exists($key, $this->options)) {
276
			$this->options[$key] = [];
277
		}
278
279
		$this->options[$key][] = $value;
280
281
		return $this;
282
	}
283
284
	/**
285
	 * @param string $option
286
	 * @param string $default
287
	 *
288
	 * @return string
289
	 */
290
	public function getOption($option, $default = '') {
291
		if (array_key_exists($option, $this->options)) {
292
			return $this->options[$option];
293
		}
294
295
		return $default;
296
	}
297
298
299
	/**
300
	 * @param string $option
301
	 * @param array $default
302
	 *
303
	 * @return array
304
	 */
305 View Code Duplication
	public function getOptionArray($option, $default = []) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
306
		if (array_key_exists($option, $this->options)) {
307
			$options = $this->options[$option];
308
			if (is_array($options)) {
309
				return $this->options[$option];
310
			}
311
		}
312
313
		return $default;
314
	}
315
316
317
	/**
318
	 * @param array $parts
319
	 *
320
	 * @return $this
321
	 */
322
	public function setParts($parts) {
323
		$this->parts = $parts;
324
325
		return $this;
326
	}
327
328
	/**
329
	 * @return array
330
	 */
331
	public function getParts() {
332
		return $this->parts;
333
	}
334
335
336
	/**
337
	 * @return array
338
	 */
339
	public function getFields() {
340
		return $this->fields;
341
	}
342
343
	/**
344
	 * @param array $fields
345
	 *
346
	 * @return $this
347
	 */
348
	public function setFields($fields) {
349
		$this->fields = $fields;
350
351
		return $this;
352
	}
353
354
355
	/**
356
	 * @param $field
357
	 *
358
	 * @return $this
359
	 */
360
	public function limitToField($field) {
361
		array_push($this->limitFields, $field);
362
363
		return $this;
364
	}
365
366
	/**
367
	 * @return array
368
	 */
369
	public function getLimitFields() {
370
		return $this->limitFields;
371
	}
372
373
374
	/**
375
	 * @param $field
376
	 *
377
	 * @return $this
378
	 */
379
	public function addField($field) {
380
		$this->fields[] = $field;
381
382
		return $this;
383
	}
384
385
386
	/**
387
	 * @param string $tag
388
	 */
389
	public function addTag($tag) {
390
		$this->tags[] = $tag;
391
	}
392
393
	/**
394
	 * @return array
395
	 */
396
	public function getTags() {
397
		return $this->tags;
398
	}
399
400
	/**
401
	 * @param array $tags
402
	 */
403
	public function setTags($tags) {
404
		$this->tags = $tags;
405
	}
406
407
408
	/**
409
	 * @param array $tags
410
	 *
411
	 * @return $this
412
	 */
413
	public function setMetaTags($tags) {
414
		$this->metaTags = $tags;
415
416
		return $this;
417
	}
418
419
	/**
420
	 * @return array
421
	 */
422
	public function getMetaTags() {
423
		return $this->metaTags;
424
	}
425
426
	/**
427
	 * @param string $tags
428
	 *
429
	 * @return $this
430
	 */
431
	public function addMetaTag($tags) {
432
		$this->metaTags[] = $tags;
433
434
		return $this;
435
	}
436
437
438
	/**
439
	 * @param array $tags
440
	 *
441
	 * @return $this
442
	 */
443
	public function setSubTags($tags) {
444
		$this->subTags = $tags;
445
446
		return $this;
447
	}
448
449
	/**
450
	 * @param bool $formatted
451
	 *
452
	 * @return array
453
	 */
454 View Code Duplication
	public function getSubTags($formatted = false) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
455
		if ($formatted === false) {
456
			return $this->subTags;
457
		}
458
459
		$subTags = [];
460
		$ak = array_keys($this->subTags);
461
		foreach ($ak as $source) {
462
			$tags = $this->subTags[$source];
463
			foreach ($tags as $tag) {
464
				$subTags[] = $source . '_' . $tag;
465
			}
466
		}
467
468
		return $subTags;
469
	}
470
471
	/**
472
	 * @param string $source
473
	 * @param string $tag
474
	 *
475
	 * @return $this
476
	 */
477
	public function addSubTag($source, $tag) {
478
		if (!array_key_exists($source, $this->subTags)) {
479
			$this->subTags[$source] = [];
480
		}
481
482
		$this->subTags[$source][] = $tag;
483
484
		return $this;
485
	}
486
487
488
	/**
489
	 * @param string $field
490
	 *
491
	 * @return $this
492
	 */
493
	public function addWildcardField($field) {
494
		$this->wildcardFields[] = $field;
495
496
		return $this;
497
	}
498
499
500
	/**
501
	 * @return array
502
	 */
503
	public function getWildcardFields() {
504
		return $this->wildcardFields;
505
	}
506
507
//
508
//	/**
509
//	 * @param array $query
510
//	 *
511
//	 * @return $this
512
//	 */
513
//	public function addWildcardQuery($query) {
514
//		$this->addWildcardQueries([$query]);
515
//
516
//		return $this;
517
//	}
518
//
519
//	/**
520
//	 * @param array $query
521
//	 *
522
//	 * @return $this
523
//	 */
524
//	public function addWildcardQueries($query) {
525
//		array_push($this->wildcardQueries, $query);
526
//
527
//		return $this;
528
//	}
529
//
530
//	/**
531
//	 * @return array
532
//	 */
533
//	public function getWildcardQueries() {
534
//		return $this->wildcardQueries;
535
//	}
536
537
538
	/**
539
	 * @param array $filter
540
	 *
541
	 * @return $this
542
	 */
543
	public function addWildcardFilter($filter) {
544
		$this->addWildcardFilters([$filter]);
545
546
		return $this;
547
	}
548
549
	/**
550
	 * @param array $filters
551
	 *
552
	 * @return $this
553
	 */
554
	public function addWildcardFilters($filters) {
555
		array_push($this->wildcardFilters, $filters);
556
557
		return $this;
558
	}
559
560
	/**
561
	 * @return array
562
	 */
563
	public function getWildcardFilters() {
564
		return $this->wildcardFilters;
565
	}
566
567
568
	/**
569
	 * @param array $filter
570
	 *
571
	 * @return $this
572
	 */
573
	public function addRegexFilter($filter) {
574
		$this->addRegexFilters([$filter]);
575
576
		return $this;
577
	}
578
579
	/**
580
	 * @param array $filters
581
	 *
582
	 * @return $this
583
	 */
584
	public function addRegexFilters($filters) {
585
		array_push($this->regexFilters, $filters);
586
587
		return $this;
588
	}
589
590
	/**
591
	 * @return array
592
	 */
593
	public function getRegexFilters() {
594
		return $this->regexFilters;
595
	}
596
597
598
	/**
599
	 * @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...
600
	 */
601
	public function jsonSerialize() {
602
		return [
603
			'providers' => $this->getProviders(),
604
			'author'    => $this->getAuthor(),
605
			'search'    => $this->getSearch(),
606
			'page'      => $this->getPage(),
607
			'size'      => $this->getSize(),
608
			'parts'     => $this->getParts(),
609
			'options'   => $this->getOptions(),
610
			'metatags'  => $this->getMetaTags(),
611
			'subtags'   => $this->getSubTags(),
612
			'tags'      => $this->getTags()
613
		];
614
	}
615
616
617
	/**
618
	 * @param string $json
619
	 *
620
	 * @return SearchRequest
621
	 */
622
	public static function fromJSON($json) {
623
		return self::fromArray(json_decode($json, true));
624
	}
625
626
	/**
627
	 * @param array $arr
628
	 *
629
	 * @return SearchRequest
630
	 */
631
	public static function fromArray($arr) {
632
		$providers = $arr['providers'];
633
		if (!is_array($providers)) {
634
			$providers = [$providers];
635
		}
636
637
		$request = new SearchRequest();
638
		$request->setProviders($providers);
639
		$request->setAuthor(MiscService::get('author', $arr, ''));
640
		$request->setSearch(MiscService::get('search', $arr, ''));
641
		$request->setPage(MiscService::get('page', $arr, 0));
642
		$request->setParts(MiscService::get('parts', $arr, []));
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...
643
		$request->setSize(MiscService::get('size', $arr, 10));
644
		$request->setOptions(MiscService::get('options', $arr, []));
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...
645
		$request->setMetaTags(MiscService::get('metatags', $arr, []));
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...
646
		$request->setSubTags(MiscService::get('subtags', $arr, []));
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...
647
		$request->setTags(MiscService::get('tags', $arr, []));
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...
648
649
		return $request;
650
	}
651
652
653
}