1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace SilverStripe\FullTextSearch\Search\Queries; |
4
|
|
|
|
5
|
|
|
use SilverStripe\Dev\Deprecation; |
6
|
|
|
use SilverStripe\View\ViewableData; |
7
|
|
|
use stdClass; |
8
|
|
|
|
9
|
|
|
/** |
10
|
|
|
* Represents a search query |
11
|
|
|
* |
12
|
|
|
* API very much still in flux. |
13
|
|
|
*/ |
14
|
|
|
class SearchQuery extends ViewableData |
15
|
|
|
{ |
16
|
|
|
public static $missing = null; |
17
|
|
|
public static $present = null; |
18
|
|
|
|
19
|
|
|
public static $default_page_size = 10; |
20
|
|
|
|
21
|
|
|
/** These are public, but only for index & variant access - API users should not manually access these */ |
22
|
|
|
|
23
|
|
|
public $search = []; |
24
|
|
|
|
25
|
|
|
public $classes = []; |
26
|
|
|
|
27
|
|
|
public $require = []; |
28
|
|
|
public $exclude = []; |
29
|
|
|
|
30
|
|
|
protected $start = 0; |
31
|
|
|
protected $limit = -1; |
32
|
|
|
|
33
|
|
|
/** These are the API functions */ |
34
|
|
|
|
35
|
|
|
public function __construct() |
36
|
|
|
{ |
37
|
|
|
if (self::$missing === null) { |
38
|
|
|
self::$missing = new stdClass(); |
39
|
|
|
} |
40
|
|
|
if (self::$present === null) { |
41
|
|
|
self::$present = new stdClass(); |
42
|
|
|
} |
43
|
|
|
} |
44
|
|
|
|
45
|
|
|
/** |
46
|
|
|
* @param string $text Search terms. Exact format (grouping, boolean expressions, etc.) depends on |
47
|
|
|
* the search implementation. |
48
|
|
|
* @param array $fields Limits the search to specific fields (using composite field names) |
49
|
|
|
* @param array $boost Map of composite field names to float values. The higher the value, |
50
|
|
|
* the more important the field gets for relevancy. |
51
|
|
|
*/ |
52
|
|
|
public function addSearchTerm($text, $fields = null, $boost = []) |
53
|
|
|
{ |
54
|
|
|
$this->search[] = [ |
55
|
|
|
'text' => $text, |
56
|
|
|
'fields' => $fields ? (array) $fields : null, |
57
|
|
|
'boost' => $boost, |
58
|
|
|
'fuzzy' => false |
59
|
|
|
]; |
60
|
|
|
return $this; |
61
|
|
|
} |
62
|
|
|
|
63
|
|
|
/** |
64
|
|
|
* Similar to {@link search()}, but uses stemming and other similarity algorithms |
65
|
|
|
* to find the searched terms. For example, a term "fishing" would also likely find results |
66
|
|
|
* containing "fish" or "fisher". Depends on search implementation. |
67
|
|
|
* |
68
|
|
|
* @param string $text See {@link search()} |
69
|
|
|
* @param array $fields See {@link search()} |
70
|
|
|
* @param array $boost See {@link search()} |
71
|
|
|
*/ |
72
|
|
|
public function fuzzysearch($text, $fields = null, $boost = []) |
73
|
|
|
{ |
74
|
|
|
$this->search[] = [ |
75
|
|
|
'text' => $text, |
76
|
|
|
'fields' => $fields ? (array) $fields : null, |
77
|
|
|
'boost' => $boost, |
78
|
|
|
'fuzzy' => true |
79
|
|
|
]; |
80
|
|
|
} |
81
|
|
|
|
82
|
|
|
public function inClass($class, $includeSubclasses = true) |
83
|
|
|
{ |
84
|
|
|
$this->classes[] = [ |
85
|
|
|
'class' => $class, |
86
|
|
|
'includeSubclasses' => $includeSubclasses |
87
|
|
|
]; |
88
|
|
|
} |
89
|
|
|
|
90
|
|
|
/** |
91
|
|
|
* Similar to {@link search()}, but typically used to further narrow down |
92
|
|
|
* based on other facets which don't influence the field relevancy. |
93
|
|
|
* |
94
|
|
|
* @param string $field Composite name of the field |
95
|
|
|
* @param mixed $values Scalar value, array of values, or an instance of SearchQuery_Range |
96
|
|
|
*/ |
97
|
|
|
public function filter($field, $values) |
98
|
|
|
{ |
99
|
|
|
$requires = isset($this->require[$field]) ? $this->require[$field] : []; |
100
|
|
|
$values = is_array($values) ? $values : [$values]; |
101
|
|
|
$this->require[$field] = array_merge($requires, $values); |
102
|
|
|
} |
103
|
|
|
|
104
|
|
|
/** |
105
|
|
|
* Excludes results which match these criteria, inverse of {@link filter()}. |
106
|
|
|
* |
107
|
|
|
* @param string $field |
108
|
|
|
* @param mixed $values |
109
|
|
|
*/ |
110
|
|
|
public function exclude($field, $values) |
111
|
|
|
{ |
112
|
|
|
$excludes = isset($this->exclude[$field]) ? $this->exclude[$field] : []; |
113
|
|
|
$values = is_array($values) ? $values : [$values]; |
114
|
|
|
$this->exclude[$field] = array_merge($excludes, $values); |
115
|
|
|
} |
116
|
|
|
|
117
|
|
|
public function start($start) |
118
|
|
|
{ |
119
|
|
|
$this->start = $start; |
120
|
|
|
} |
121
|
|
|
|
122
|
|
|
public function limit($limit) |
123
|
|
|
{ |
124
|
|
|
$this->limit = $limit; |
125
|
|
|
} |
126
|
|
|
|
127
|
|
|
public function page($page) |
128
|
|
|
{ |
129
|
|
|
$this->start = $page * self::$default_page_size; |
130
|
|
|
$this->limit = self::$default_page_size; |
131
|
|
|
} |
132
|
|
|
|
133
|
|
|
public function isfiltered() |
134
|
|
|
{ |
135
|
|
|
return $this->search || $this->classes || $this->require || $this->exclude; |
|
|
|
|
136
|
|
|
} |
137
|
|
|
|
138
|
|
|
public function __toString() |
139
|
|
|
{ |
140
|
|
|
return "Search Query\n"; |
141
|
|
|
} |
142
|
|
|
|
143
|
|
|
public function search($text, $fields = null, $boost = []) |
144
|
|
|
{ |
145
|
|
|
Deprecation::notice('4.0', 'Use addSearchTerm() instead'); |
146
|
|
|
return $this->addSearchTerm($text, $fields, $boost); |
147
|
|
|
} |
148
|
|
|
} |
149
|
|
|
|
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.