Completed
Pull Request — master (#531)
by Maxence
01:24
created

SearchRequest::getSize()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 3
rs 10
cc 1
nc 1
nop 0
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
use OCP\FullTextSearch\Model\ISearchRequestSimpleQuery;
38
39
40
/**
41
 * Class SearchRequest
42
 *
43
 * @package OCA\FullTextSearch\Model
44
 */
45
class SearchRequest implements ISearchRequest, JsonSerializable {
46
47
48
	use TArrayTools;
49
50
51
	/** @var array */
52
	private $providers;
53
54
	/** @var string */
55
	private $search;
56
57
	/** @var int */
58
	private $page = 1;
59
60
	/** @var int */
61
	private $size = 10;
62
63
	/** @var string */
64
	private $author;
65
66
	/** @var array */
67
	private $tags = [];
68
69
	/** @var array */
70
	public $metaTags = [];
71
72
	/** @var array */
73
	public $subTags = [];
74
75
	/** @var array */
76
	private $options;
77
78
	/** @var array */
79
	private $parts = [];
80
81
	/** @var array */
82
	private $fields = [];
83
84
	/** @var array */
85
	private $limitFields = [];
86
87
	/** @var array */
88
	private $wildcardFields = [];
89
90
//	/** @var array */
91
//	private $wildcardQueries = [];
92
93
	/** @var array */
94
	private $wildcardFilters = [];
95
96
	/** @var array */
97
	private $regexFilters = [];
98
99
	/** @var array */
100
	private $simpleQueries = [];
101
102
103
	/**
104
	 * SearchRequest constructor.
105
	 */
106
	public function __construct() {
107
	}
108
109
110
	/**
111
	 * @return array
112
	 */
113
	public function getProviders(): array {
114
		return $this->providers;
115
	}
116
117
	/**
118
	 * @param array $providers
119
	 *
120
	 * @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...
121
	 */
122
	public function setProviders(array $providers): ISearchRequest {
123
		$this->providers = $providers;
124
125
		return $this;
126
	}
127
128
129
	/**
130
	 * @return string
131
	 */
132
	public function getAuthor(): string {
133
		return $this->author;
134
	}
135
136
	/**
137
	 * @param string $author
138
	 *
139
	 * @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...
140
	 */
141
	public function setAuthor(string $author): ISearchRequest {
142
		$this->author = $author;
143
144
		return $this;
145
	}
146
147
148
	/**
149
	 * @return string
150
	 */
151
	public function getSearch(): string {
152
		return $this->search;
153
	}
154
155
	/**
156
	 * @param string $search
157
	 *
158
	 * @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...
159
	 */
160
	public function setSearch(string $search): ISearchRequest {
161
		$this->search = $search;
162
163
		return $this;
164
	}
165
166
167
	/**
168
	 *
169
	 */
170
	public function cleanSearch(): ISearchRequest {
171
		$search = trim(str_replace('  ', ' ', $this->getSearch()));
172
173
		preg_match_all('/[^?]"(?:\\\\.|[^\\\\"])*"|\S+/', " $search ", $words);
174
		$searchItems = [];
175
		foreach ($words[0] as $word) {
176
			if ($this->searchQueryOptions($word)) {
177
				continue;
178
			}
179
180
			$searchItems[] = $word;
181
		}
182
183
		$this->setSearch(implode(" ", $searchItems));
184
185
		return $this;
186
	}
187
188
189
	/**
190
	 * @param string $word
191
	 *
192
	 * @return bool
193
	 */
194
	private function searchQueryOptions(string $word): bool {
195
		if (($pos = strpos($word, ':')) === false) {
196
			return false;
197
		}
198
199
		list($kw, $value) = explode(':', $word, 2);
200
201
		$options = ['is', 'show'];
202
		if (in_array($kw, $options)) {
203
			$this->addOption($kw . '_' . $value, '1');
204
205
			return true;
206
		}
207
208
		$valuedOptions = ['in', 'meta'];
209
		if (in_array($kw, $valuedOptions)) {
210
			$this->addMultipleOption($kw, $value);
211
212
			return true;
213
		}
214
215
		$valuedSubOptions = ['and'];
216
		if (in_array($kw, $valuedSubOptions)) {
217
			list($key, $value) = explode(':', $value, 2);
218
			$this->addMultipleOption($kw . ':' . $key, $value);
219
220
			return true;
221
		}
222
223
		return false;
224
	}
225
226
227
	/**
228
	 * @return int
229
	 */
230
	public function getPage(): int {
231
		return $this->page;
232
	}
233
234
	/**
235
	 * @param int $page
236
	 *
237
	 * @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...
238
	 */
239
	public function setPage(int $page): ISearchRequest {
240
		if ($page < 1) {
241
			$page = 1;
242
		}
243
244
		$this->page = $page;
245
246
		return $this;
247
	}
248
249
250
	/**
251
	 * @return int
252
	 */
253
	public function getSize(): int {
254
		return $this->size;
255
	}
256
257
	/**
258
	 * @param int $size
259
	 *
260
	 * @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...
261
	 */
262
	public function setSize(int $size): ISearchRequest {
263
		$this->size = $size;
264
265
		return $this;
266
	}
267
268
269
	/**
270
	 * @return array
271
	 */
272
	public function getOptions(): array {
273
		return $this->options;
274
	}
275
276
	/**
277
	 * @param array $options
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 setOptions(array $options): ISearchRequest {
282
		$this->options = $options;
283
284
		return $this;
285
	}
286
287
	/**
288
	 * @param $option
289
	 * @param $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 addOption(string $option, string $value): ISearchRequest {
294
		$this->options[$option] = $value;
295
296
		return $this;
297
	}
298
299
	/**
300
	 * @param string $option
301
	 * @param array $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 addOptionArray(string $option, array $value): ISearchRequest {
306
		$this->options[$option] = $value;
307
308
		return $this;
309
	}
310
311
	/**
312
	 * @param string $option
313
	 * @param bool $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 addOptionBool(string $option, bool $value): ISearchRequest {
318
		$this->options[$option] = $value;
319
320
		return $this;
321
	}
322
323
	/**
324
	 * @param string $option
325
	 * @param string $value
326
	 *
327
	 * @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...
328
	 */
329
	public function addMultipleOption(string $option, string $value): ISearchRequest {
330
		if (!array_key_exists($option, $this->options)) {
331
			$this->options[$option] = [];
332
		}
333
334
		$this->options[$option][] = $value;
335
336
		return $this;
337
	}
338
339
	/**
340
	 * @param string $option
341
	 * @param string $default
342
	 *
343
	 * @return string
344
	 */
345
	public function getOption(string $option, string $default = ''): string {
346
		return $this->get($option, $this->options, $default);
347
	}
348
349
350
	/**
351
	 * @param string $option
352
	 * @param array $default
353
	 *
354
	 * @return array
355
	 */
356
	public function getOptionArray(string $option, array $default = []): array {
357
		return $this->getArray($option, $this->options, $default);
358
	}
359
360
361
	/**
362
	 * @param string $part
363
	 *
364
	 * @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...
365
	 */
366
	public function addPart(string $part): ISearchRequest {
367
		$this->parts[] = $part;
368
369
		return $this;
370
	}
371
372
	/**
373
	 * @return array
374
	 */
375
	public function getParts(): array {
376
		return $this->parts;
377
	}
378
379
380
	/**
381
	 * @param array $parts
382
	 *
383
	 * @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...
384
	 * @since 15.0.0
385
	 *
386
	 */
387
	public function setParts(array $parts): ISearchRequest {
388
		$this->parts = $parts;
389
390
		return $this;
391
	}
392
393
394
	/**
395
	 * @return array
396
	 */
397
	public function getFields(): array {
398
		return $this->fields;
399
	}
400
401
	/**
402
	 * @param array $fields
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 setFields(array $fields): ISearchRequest {
407
		$this->fields = $fields;
408
409
		return $this;
410
	}
411
412
413
	/**
414
	 * @param string $field
415
	 *
416
	 * @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...
417
	 */
418
	public function addLimitField(string $field): ISearchRequest {
419
		array_push($this->limitFields, $field);
420
421
		return $this;
422
	}
423
424
	/**
425
	 * @return array
426
	 */
427
	public function getLimitFields(): array {
428
		return $this->limitFields;
429
	}
430
431
432
	/**
433
	 * @param string $field
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 addField(string $field): ISearchRequest {
438
		$this->fields[] = $field;
439
440
		return $this;
441
	}
442
443
444
	/**
445
	 * @param string $tag
446
	 *
447
	 * @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...
448
	 */
449
	public function addTag(string $tag): ISearchRequest {
450
		$this->tags[] = $tag;
451
452
		return $this;
453
	}
454
455
	/**
456
	 * @return array
457
	 */
458
	public function getTags(): array {
459
		return $this->tags;
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 setTags(array $tags): ISearchRequest {
468
		$this->tags = $tags;
469
470
		return $this;
471
	}
472
473
474
	/**
475
	 * @param array $tags
476
	 *
477
	 * @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...
478
	 */
479
	public function setMetaTags(array $tags): ISearchRequest {
480
		$this->metaTags = $tags;
481
482
		return $this;
483
	}
484
485
	/**
486
	 * @return array
487
	 */
488
	public function getMetaTags(): array {
489
		return $this->metaTags;
490
	}
491
492
	/**
493
	 * @param string $tag
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 addMetaTag(string $tag): ISearchRequest {
498
		$this->metaTags[] = $tag;
499
500
		return $this;
501
	}
502
503
504
	/**
505
	 * @param array $tags
506
	 *
507
	 * @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...
508
	 */
509
	public function setSubTags(array $tags): ISearchRequest {
510
		$this->subTags = $tags;
511
512
		return $this;
513
	}
514
515
	/**
516
	 * @param bool $formatted
517
	 *
518
	 * @return array
519
	 */
520
	public function getSubTags(bool $formatted = false): array {
521
		if ($formatted === false) {
522
			return $this->subTags;
523
		}
524
525
		$subTags = [];
526
		$ak = array_keys($this->subTags);
527
		foreach ($ak as $source) {
528
			$tags = $this->subTags[$source];
529
			foreach ($tags as $tag) {
530
				$subTags[] = $source . '_' . $tag;
531
			}
532
		}
533
534
		return $subTags;
535
	}
536
537
	/**
538
	 * @param string $source
539
	 * @param string $tag
540
	 *
541
	 * @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...
542
	 */
543
	public function addSubTag(string $source, string $tag): ISearchRequest {
544
		if (!array_key_exists($source, $this->subTags)) {
545
			$this->subTags[$source] = [];
546
		}
547
548
		$this->subTags[$source][] = $tag;
549
550
		return $this;
551
	}
552
553
554
	/**
555
	 * @param string $field
556
	 *
557
	 * @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...
558
	 */
559
	public function addWildcardField(string $field): ISearchRequest {
560
		$this->wildcardFields[] = $field;
561
562
		return $this;
563
	}
564
565
566
	/**
567
	 * @return array
568
	 */
569
	public function getWildcardFields(): array {
570
		return $this->wildcardFields;
571
	}
572
573
//
574
//	/**
575
//	 * @param array $query
576
//	 *
577
//	 * @return ISearchRequest
578
//	 */
579
//	public function addWildcardQuery($query) {
580
//		$this->addWildcardQueries([$query]);
581
//
582
//		return $this;
583
//	}
584
//
585
//	/**
586
//	 * @param array $query
587
//	 *
588
//	 * @return ISearchRequest
589
//	 */
590
//	public function addWildcardQueries($query) {
591
//		array_push($this->wildcardQueries, $query);
592
//
593
//		return $this;
594
//	}
595
//
596
//	/**
597
//	 * @return array
598
//	 */
599
//	public function getWildcardQueries() {
600
//		return $this->wildcardQueries;
601
//	}
602
603
604
	/**
605
	 * @param array $filter
606
	 *
607
	 * @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...
608
	 */
609
	public function addWildcardFilter(array $filter): ISearchRequest {
610
		$this->addWildcardFilters([$filter]);
611
612
		return $this;
613
	}
614
615
	/**
616
	 * @param array $filters
617
	 *
618
	 * @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...
619
	 */
620
	public function addWildcardFilters(array $filters): ISearchRequest {
621
		array_push($this->wildcardFilters, $filters);
622
623
		return $this;
624
	}
625
626
	/**
627
	 * @return array
628
	 */
629
	public function getWildcardFilters(): array {
630
		return $this->wildcardFilters;
631
	}
632
633
634
	/**
635
	 * @param string $filter
636
	 *
637
	 * @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...
638
	 */
639
	public function addRegexFilter(string $filter): ISearchRequest {
640
		$this->addRegexFilters([$filter]);
641
642
		return $this;
643
	}
644
645
	/**
646
	 * @param array $filters
647
	 *
648
	 * @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...
649
	 */
650
	public function addRegexFilters(array $filters): ISearchRequest {
651
		array_push($this->regexFilters, $filters);
652
653
		return $this;
654
	}
655
656
	/**
657
	 * @return array
658
	 */
659
	public function getRegexFilters(): array {
660
		return $this->regexFilters;
661
	}
662
663
664
	/**
665
	 * @param ISearchRequestSimpleQuery $query
666
	 *
667
	 * @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...
668
	 */
669
	public function addSimpleQuery(ISearchRequestSimpleQuery $query): ISearchRequest {
670
		$this->simpleQueries[] = $query;
671
672
		return $this;
673
	}
674
675
676
	/**
677
	 * @return ISearchRequestSimpleQuery[]
678
	 */
679
	public function getSimpleQueries(): array {
680
		return $this->simpleQueries;
681
	}
682
683
684
	/**
685
	 * @return array
686
	 */
687
	public function jsonSerialize(): array {
688
		return [
689
			'providers' => $this->getProviders(),
690
			'author'    => $this->getAuthor(),
691
			'search'    => $this->getSearch(),
692
			'page'      => $this->getPage(),
693
			'size'      => $this->getSize(),
694
			'parts'     => $this->getParts(),
695
			'queries'   => $this->getSimpleQueries(),
696
			'options'   => $this->getOptions(),
697
			'metatags'  => $this->getMetaTags(),
698
			'subtags'   => $this->getSubTags(),
699
			'tags'      => $this->getTags()
700
		];
701
	}
702
703
704
	/**
705
	 * @param array $arr
706
	 *
707
	 * @return SearchRequest
708
	 */
709
	public function importFromArray($arr): SearchRequest {
710
		$providers = $arr['providers'];
711
		if (!is_array($providers)) {
712
			$providers = [$providers];
713
		}
714
715
		$this->setProviders($providers);
716
		$this->setAuthor($this->get('author', $arr, ''));
717
		$this->setSearch($this->get('search', $arr, ''));
718
		$this->setPage($this->getInt('page', $arr, 0));
719
		$this->setParts($this->getArray('parts', $arr, []));
720
		$this->setSize($this->getInt('size', $arr, 10));
721
		$this->setOptions($this->getArray('options', $arr, []));
722
		$this->setMetaTags($this->getArray('metatags', $arr, []));
723
		$this->setSubTags($this->getArray('subtags', $arr, []));
724
		$this->setTags($this->getArray('tags', $arr, []));
725
726
		return $this;
727
	}
728
729
730
	/**
731
	 * @param string $json
732
	 *
733
	 * @return SearchRequest
734
	 */
735
	public static function fromJSON(string $json): SearchRequest {
736
		$searchRequest = new SearchRequest();
737
		$searchRequest->importFromArray(json_decode($json, true));
738
739
		return $searchRequest;
740
	}
741
742
}
743