Completed
Push — master ( 347a51...ad246f )
by Maxence
02:23
created

SearchRequest::addOptionBool()   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 2
1
<?php
2
declare(strict_types=1);
3
4
5
/**
6
 * FullTextSearch - Full text search framework for Nextcloud
7
 *
8
 * This file is licensed under the Affero General Public License version 3 or
9
 * later. See the COPYING file.
10
 *
11
 * @author Maxence Lange <[email protected]>
12
 * @copyright 2018
13
 * @license GNU AGPL version 3 or any later version
14
 *
15
 * This program is free software: you can redistribute it and/or modify
16
 * it under the terms of the GNU Affero General Public License as
17
 * published by the Free Software Foundation, either version 3 of the
18
 * License, or (at your option) any later version.
19
 *
20
 * This program is distributed in the hope that it will be useful,
21
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23
 * GNU Affero General Public License for more details.
24
 *
25
 * You should have received a copy of the GNU Affero General Public License
26
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
27
 *
28
 */
29
30
31
namespace OCA\FullTextSearch\Model;
32
33
34
use daita\MySmallPhpTools\Traits\TArrayTools;
35
use JsonSerializable;
36
use OCP\FullTextSearch\Model\ISearchRequest;
37
38
39
/**
40
 * Class SearchRequest
41
 *
42
 * @package OCA\FullTextSearch\Model
43
 */
44
class SearchRequest implements ISearchRequest, JsonSerializable {
45
46
47
	use TArrayTools;
48
49
50
	/** @var array */
51
	private $providers;
52
53
	/** @var string */
54
	private $search;
55
56
	/** @var int */
57
	private $page = 1;
58
59
	/** @var int */
60
	private $size = 10;
61
62
	/** @var string */
63
	private $author;
64
65
	/** @var array */
66
	private $tags = [];
67
68
	/** @var array */
69
	public $metaTags = [];
70
71
	/** @var array */
72
	public $subTags = [];
73
74
	/** @var array */
75
	private $options;
76
77
	/** @var array */
78
	private $parts = [];
79
80
	/** @var array */
81
	private $fields = [];
82
83
	/** @var array */
84
	private $limitFields = [];
85
86
	/** @var array */
87
	private $wildcardFields = [];
88
89
//	/** @var array */
90
//	private $wildcardQueries = [];
91
92
	/** @var array */
93
	private $wildcardFilters = [];
94
95
	/** @var array */
96
	private $regexFilters = [];
97
98
99
	/**
100
	 * SearchRequest constructor.
101
	 */
102
	public function __construct() {
103
	}
104
105
106
	/**
107
	 * @return array
108
	 */
109
	public function getProviders(): array {
110
		return $this->providers;
111
	}
112
113
	/**
114
	 * @param array $providers
115
	 *
116
	 * @return ISearchRequest
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use SearchRequest.

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...
117
	 */
118
	public function setProviders(array $providers): ISearchRequest {
119
		$this->providers = $providers;
120
121
		return $this;
122
	}
123
124
125
	/**
126
	 * @return string
127
	 */
128
	public function getAuthor(): string {
129
		return $this->author;
130
	}
131
132
	/**
133
	 * @param string $author
134
	 *
135
	 * @return ISearchRequest
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use SearchRequest.

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...
136
	 */
137
	public function setAuthor(string $author): ISearchRequest {
138
		$this->author = $author;
139
140
		return $this;
141
	}
142
143
144
	/**
145
	 * @return string
146
	 */
147
	public function getSearch(): string {
148
		return $this->search;
149
	}
150
151
	/**
152
	 * @param string $search
153
	 *
154
	 * @return ISearchRequest
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use SearchRequest.

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...
155
	 */
156
	public function setSearch(string $search): ISearchRequest {
157
		$this->search = $search;
158
159
		return $this;
160
	}
161
162
163
	/**
164
	 *
165
	 */
166
	public function cleanSearch(): ISearchRequest {
167
		$search = trim(str_replace('  ', ' ', $this->getSearch()));
168
169
		preg_match_all('/[^?]"(?:\\\\.|[^\\\\"])*"|\S+/', " $search ", $words);
170
		$searchItems = [];
171
		foreach ($words[0] as $word) {
172
			if ($this->searchQueryOptions($word)) {
173
				continue;
174
			}
175
176
			$searchItems[] = $word;
177
		}
178
179
		$this->setSearch(implode(" ", $searchItems));
180
181
		return $this;
182
	}
183
184
185
	/**
186
	 * @param string $word
187
	 *
188
	 * @return bool
189
	 */
190
	private function searchQueryOptions(string $word): bool {
191
		if (($pos = strpos($word, ':')) === false) {
192
			return false;
193
		}
194
195
		list($kw, $value) = explode(':', $word, 2);
196
197
		$options = ['is', 'show'];
198
		if (in_array($kw, $options)) {
199
			$this->addOption($kw . '_' . $value, '1');
200
201
			return true;
202
		}
203
204
		$valuedOptions = ['in', 'meta'];
205
		if (in_array($kw, $valuedOptions)) {
206
			$this->addMultipleOption($kw, $value);
207
208
			return true;
209
		}
210
211
		return false;
212
	}
213
214
215
	/**
216
	 * @return int
217
	 */
218
	public function getPage(): int {
219
		return $this->page;
220
	}
221
222
	/**
223
	 * @param int $page
224
	 *
225
	 * @return ISearchRequest
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use SearchRequest.

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...
226
	 */
227
	public function setPage(int $page): ISearchRequest {
228
		if ($page < 1) {
229
			$page = 1;
230
		}
231
232
		$this->page = $page;
233
234
		return $this;
235
	}
236
237
238
	/**
239
	 * @return int
240
	 */
241
	public function getSize(): int {
242
		return $this->size;
243
	}
244
245
	/**
246
	 * @param int $size
247
	 *
248
	 * @return ISearchRequest
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use SearchRequest.

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...
249
	 */
250
	public function setSize(int $size): ISearchRequest {
251
		$this->size = $size;
252
253
		return $this;
254
	}
255
256
257
	/**
258
	 * @return array
259
	 */
260
	public function getOptions(): array {
261
		return $this->options;
262
	}
263
264
	/**
265
	 * @param array $options
266
	 *
267
	 * @return ISearchRequest
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use SearchRequest.

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...
268
	 */
269
	public function setOptions(array $options): ISearchRequest {
270
		$this->options = $options;
271
272
		return $this;
273
	}
274
275
	/**
276
	 * @param $option
277
	 * @param $value
278
	 *
279
	 * @return ISearchRequest
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use SearchRequest.

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...
280
	 */
281
	public function addOption(string $option, string $value): ISearchRequest {
282
		$this->options[$option] = $value;
283
284
		return $this;
285
	}
286
287
	/**
288
	 * @param string $option
289
	 * @param array $value
290
	 *
291
	 * @return ISearchRequest
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use SearchRequest.

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...
292
	 */
293
	public function addOptionArray(string $option, array $value): ISearchRequest {
294
		$this->options[$option] = $value;
295
296
		return $this;
297
	}
298
299
	/**
300
	 * @param string $option
301
	 * @param bool $value
302
	 *
303
	 * @return ISearchRequest
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use SearchRequest.

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...
304
	 */
305
	public function addOptionBool(string $option, bool $value): ISearchRequest {
306
		$this->options[$option] = $value;
307
308
		return $this;
309
	}
310
311
	/**
312
	 * @param string $option
313
	 * @param string $value
314
	 *
315
	 * @return ISearchRequest
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use SearchRequest.

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...
316
	 */
317
	public function addMultipleOption(string $option, string $value): ISearchRequest {
318
		if (!array_key_exists($option, $this->options)) {
319
			$this->options[$option] = [];
320
		}
321
322
		$this->options[$option][] = $value;
323
324
		return $this;
325
	}
326
327
	/**
328
	 * @param string $option
329
	 * @param string $default
330
	 *
331
	 * @return string
332
	 */
333
	public function getOption(string $option, string $default = ''): string {
334
		return $this->get($option, $this->options, $default);
335
	}
336
337
338
	/**
339
	 * @param string $option
340
	 * @param array $default
341
	 *
342
	 * @return array
343
	 */
344
	public function getOptionArray(string $option, array $default = []): array {
345
		return $this->getArray($option, $this->options, $default);
346
	}
347
348
349
	/**
350
	 * @param string $part
351
	 *
352
	 * @return ISearchRequest
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use SearchRequest.

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...
353
	 */
354
	public function addPart(string $part): ISearchRequest {
355
		$this->parts[] = $part;
356
357
		return $this;
358
	}
359
360
	/**
361
	 * @return array
362
	 */
363
	public function getParts(): array {
364
		return $this->parts;
365
	}
366
367
368
	/**
369
	 * @since 15.0.0
370
	 *
371
	 * @param array $parts
372
	 *
373
	 * @return ISearchRequest
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use SearchRequest.

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...
374
	 */
375
	public function setParts(array $parts): ISearchRequest {
376
		$this->parts = $parts;
377
378
		return $this;
379
	}
380
381
382
	/**
383
	 * @return array
384
	 */
385
	public function getFields(): array {
386
		return $this->fields;
387
	}
388
389
	/**
390
	 * @param array $fields
391
	 *
392
	 * @return ISearchRequest
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use SearchRequest.

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...
393
	 */
394
	public function setFields(array $fields): ISearchRequest {
395
		$this->fields = $fields;
396
397
		return $this;
398
	}
399
400
401
	/**
402
	 * @param string $field
403
	 *
404
	 * @return ISearchRequest
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use SearchRequest.

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...
405
	 */
406
	public function addLimitField(string $field): ISearchRequest {
407
		array_push($this->limitFields, $field);
408
409
		return $this;
410
	}
411
412
	/**
413
	 * @return array
414
	 */
415
	public function getLimitFields(): array {
416
		return $this->limitFields;
417
	}
418
419
420
	/**
421
	 * @param string $field
422
	 *
423
	 * @return ISearchRequest
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use SearchRequest.

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...
424
	 */
425
	public function addField(string $field): ISearchRequest {
426
		$this->fields[] = $field;
427
428
		return $this;
429
	}
430
431
432
	/**
433
	 * @param string $tag
434
	 *
435
	 * @return ISearchRequest
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use SearchRequest.

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...
436
	 */
437
	public function addTag(string $tag): ISearchRequest {
438
		$this->tags[] = $tag;
439
440
		return $this;
441
	}
442
443
	/**
444
	 * @return array
445
	 */
446
	public function getTags(): array {
447
		return $this->tags;
448
	}
449
450
	/**
451
	 * @param array $tags
452
	 *
453
	 * @return ISearchRequest
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use SearchRequest.

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...
454
	 */
455
	public function setTags(array $tags): ISearchRequest {
456
		$this->tags = $tags;
457
458
		return $this;
459
	}
460
461
462
	/**
463
	 * @param array $tags
464
	 *
465
	 * @return ISearchRequest
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use SearchRequest.

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...
466
	 */
467
	public function setMetaTags(array $tags): ISearchRequest {
468
		$this->metaTags = $tags;
469
470
		return $this;
471
	}
472
473
	/**
474
	 * @return array
475
	 */
476
	public function getMetaTags(): array {
477
		return $this->metaTags;
478
	}
479
480
	/**
481
	 * @param string $tag
482
	 *
483
	 * @return ISearchRequest
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use SearchRequest.

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...
484
	 */
485
	public function addMetaTag(string $tag): ISearchRequest {
486
		$this->metaTags[] = $tag;
487
488
		return $this;
489
	}
490
491
492
	/**
493
	 * @param array $tags
494
	 *
495
	 * @return ISearchRequest
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use SearchRequest.

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...
496
	 */
497
	public function setSubTags(array $tags): ISearchRequest {
498
		$this->subTags = $tags;
499
500
		return $this;
501
	}
502
503
	/**
504
	 * @param bool $formatted
505
	 *
506
	 * @return array
507
	 */
508
	public function getSubTags(bool $formatted = false): array {
509
		if ($formatted === false) {
510
			return $this->subTags;
511
		}
512
513
		$subTags = [];
514
		$ak = array_keys($this->subTags);
515
		foreach ($ak as $source) {
516
			$tags = $this->subTags[$source];
517
			foreach ($tags as $tag) {
518
				$subTags[] = $source . '_' . $tag;
519
			}
520
		}
521
522
		return $subTags;
523
	}
524
525
	/**
526
	 * @param string $source
527
	 * @param string $tag
528
	 *
529
	 * @return ISearchRequest
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use SearchRequest.

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...
530
	 */
531
	public function addSubTag(string $source, string $tag): ISearchRequest {
532
		if (!array_key_exists($source, $this->subTags)) {
533
			$this->subTags[$source] = [];
534
		}
535
536
		$this->subTags[$source][] = $tag;
537
538
		return $this;
539
	}
540
541
542
	/**
543
	 * @param string $field
544
	 *
545
	 * @return ISearchRequest
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use SearchRequest.

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...
546
	 */
547
	public function addWildcardField(string $field): ISearchRequest {
548
		$this->wildcardFields[] = $field;
549
550
		return $this;
551
	}
552
553
554
	/**
555
	 * @return array
556
	 */
557
	public function getWildcardFields(): array {
558
		return $this->wildcardFields;
559
	}
560
561
//
562
//	/**
563
//	 * @param array $query
564
//	 *
565
//	 * @return ISearchRequest
566
//	 */
567
//	public function addWildcardQuery($query) {
568
//		$this->addWildcardQueries([$query]);
569
//
570
//		return $this;
571
//	}
572
//
573
//	/**
574
//	 * @param array $query
575
//	 *
576
//	 * @return ISearchRequest
577
//	 */
578
//	public function addWildcardQueries($query) {
579
//		array_push($this->wildcardQueries, $query);
580
//
581
//		return $this;
582
//	}
583
//
584
//	/**
585
//	 * @return array
586
//	 */
587
//	public function getWildcardQueries() {
588
//		return $this->wildcardQueries;
589
//	}
590
591
592
	/**
593
	 * @param array $filter
594
	 *
595
	 * @return ISearchRequest
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use SearchRequest.

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...
596
	 */
597
	public function addWildcardFilter(array $filter): ISearchRequest {
598
		$this->addWildcardFilters([$filter]);
599
600
		return $this;
601
	}
602
603
	/**
604
	 * @param array $filters
605
	 *
606
	 * @return ISearchRequest
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use SearchRequest.

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...
607
	 */
608
	public function addWildcardFilters(array $filters): ISearchRequest {
609
		array_push($this->wildcardFilters, $filters);
610
611
		return $this;
612
	}
613
614
	/**
615
	 * @return array
616
	 */
617
	public function getWildcardFilters(): array {
618
		return $this->wildcardFilters;
619
	}
620
621
622
	/**
623
	 * @param string $filter
624
	 *
625
	 * @return ISearchRequest
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use SearchRequest.

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...
626
	 */
627
	public function addRegexFilter(string $filter): ISearchRequest {
628
		$this->addRegexFilters([$filter]);
629
630
		return $this;
631
	}
632
633
	/**
634
	 * @param array $filters
635
	 *
636
	 * @return ISearchRequest
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use SearchRequest.

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...
637
	 */
638
	public function addRegexFilters(array $filters): ISearchRequest {
639
		array_push($this->regexFilters, $filters);
640
641
		return $this;
642
	}
643
644
	/**
645
	 * @return array
646
	 */
647
	public function getRegexFilters(): array {
648
		return $this->regexFilters;
649
	}
650
651
652
	/**
653
	 * @return array
654
	 */
655
	public function jsonSerialize(): array {
656
		return [
657
			'providers' => $this->getProviders(),
658
			'author'    => $this->getAuthor(),
659
			'search'    => $this->getSearch(),
660
			'page'      => $this->getPage(),
661
			'size'      => $this->getSize(),
662
			'parts'     => $this->getParts(),
663
			'options'   => $this->getOptions(),
664
			'metatags'  => $this->getMetaTags(),
665
			'subtags'   => $this->getSubTags(),
666
			'tags'      => $this->getTags()
667
		];
668
	}
669
670
671
	/**
672
	 * @param array $arr
673
	 *
674
	 * @return SearchRequest
675
	 */
676
	public function importFromArray($arr): SearchRequest {
677
		$providers = $arr['providers'];
678
		if (!is_array($providers)) {
679
			$providers = [$providers];
680
		}
681
682
		$this->setProviders($providers);
683
		$this->setAuthor($this->get('author', $arr, ''));
684
		$this->setSearch($this->get('search', $arr, ''));
685
		$this->setPage($this->getInt('page', $arr, 0));
686
		$this->setParts($this->getArray('parts', $arr, []));
687
		$this->setSize($this->getInt('size', $arr, 10));
688
		$this->setOptions($this->getArray('options', $arr, []));
689
		$this->setMetaTags($this->getArray('metatags', $arr, []));
690
		$this->setSubTags($this->getArray('subtags', $arr, []));
691
		$this->setTags($this->getArray('tags', $arr, []));
692
693
		return $this;
694
	}
695
696
697
	/**
698
	 * @param string $json
699
	 *
700
	 * @return SearchRequest
701
	 */
702
	public static function fromJSON(string $json): SearchRequest {
703
		$searchRequest = new SearchRequest();
704
		$searchRequest->importFromArray(json_decode($json, true));
705
706
		return $searchRequest;
707
	}
708
709
}
710