Commit | Line | Data |
---|---|---|
749cca08 | 1 | <?php |
a9229942 | 2 | |
749cca08 | 3 | namespace wcf\system\search; |
a9229942 | 4 | |
749cca08 MW |
5 | use wcf\data\object\type\ObjectTypeCache; |
6 | use wcf\system\database\util\PreparedStatementConditionBuilder; | |
0cd425be | 7 | use wcf\system\exception\SystemException; |
157054c9 | 8 | use wcf\system\search\mysql\MysqlSearchEngine; |
749cca08 | 9 | use wcf\system\SingletonFactory; |
749cca08 MW |
10 | |
11 | /** | |
12 | * SearchEngine searches for given query in the selected object types. | |
a9229942 TD |
13 | * |
14 | * @author Marcel Werk | |
15 | * @copyright 2001-2019 WoltLab GmbH | |
16 | * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php> | |
17 | * @package WoltLabSuite\Core\System\Search | |
749cca08 | 18 | */ |
a9229942 TD |
19 | class SearchEngine extends SingletonFactory implements ISearchEngine |
20 | { | |
21 | /** | |
22 | * limit for inner search limits | |
23 | * @var int | |
24 | */ | |
25 | const INNER_SEARCH_LIMIT = 2500; | |
26 | ||
27 | /** | |
28 | * list of available object types | |
29 | * @var ISearchableObjectType[] | |
30 | */ | |
31 | protected $availableObjectTypes = []; | |
32 | ||
33 | /** | |
34 | * search engine object | |
35 | * @var ISearchEngine | |
36 | */ | |
37 | protected $searchEngine; | |
38 | ||
39 | /** | |
40 | * @inheritDoc | |
41 | */ | |
42 | protected function init() | |
43 | { | |
44 | // get available object types | |
45 | $this->availableObjectTypes = ObjectTypeCache::getInstance() | |
46 | ->getObjectTypes('com.woltlab.wcf.searchableObjectType'); | |
47 | ||
48 | // get processors | |
49 | foreach ($this->availableObjectTypes as &$objectType) { | |
50 | $objectType = $objectType->getProcessor(); | |
51 | } | |
52 | } | |
53 | ||
54 | /** | |
55 | * Returns a list of available object types. | |
56 | * | |
57 | * @return ISearchableObjectType[] | |
58 | */ | |
59 | public function getAvailableObjectTypes() | |
60 | { | |
61 | return $this->availableObjectTypes; | |
62 | } | |
63 | ||
64 | /** | |
65 | * Returns the object type with the given name. | |
66 | * | |
67 | * @param string $objectTypeName | |
68 | * @return ISearchableObjectType|null | |
69 | */ | |
70 | public function getObjectType($objectTypeName) | |
71 | { | |
72 | if (isset($this->availableObjectTypes[$objectTypeName])) { | |
73 | return $this->availableObjectTypes[$objectTypeName]; | |
74 | } | |
75 | } | |
76 | ||
77 | /** | |
78 | * Returns the search engine object. | |
79 | * | |
80 | * @return ISearchEngine | |
81 | */ | |
82 | protected function getSearchEngine() | |
83 | { | |
84 | if ($this->searchEngine === null) { | |
85 | $className = ''; | |
86 | if (SEARCH_ENGINE != 'mysql') { | |
87 | $className = 'wcf\system\search\\' . SEARCH_ENGINE . '\\' . \ucfirst(SEARCH_ENGINE) . 'SearchEngine'; | |
88 | if (!\class_exists($className)) { | |
89 | $className = ''; | |
90 | } | |
91 | } | |
92 | ||
93 | // fallback to MySQL | |
94 | if (empty($className)) { | |
95 | $className = MysqlSearchEngine::class; | |
96 | } | |
97 | ||
98 | $this->searchEngine = \call_user_func([$className, 'getInstance']); | |
99 | } | |
100 | ||
101 | return $this->searchEngine; | |
102 | } | |
103 | ||
104 | /** | |
105 | * @inheritDoc | |
106 | */ | |
107 | public function search( | |
108 | $q, | |
109 | array $objectTypes, | |
110 | $subjectOnly = false, | |
111 | ?PreparedStatementConditionBuilder $searchIndexCondition = null, | |
112 | array $additionalConditions = [], | |
113 | $orderBy = 'time DESC', | |
114 | $limit = 1000 | |
115 | ) { | |
116 | return $this->getSearchEngine() | |
117 | ->search($q, $objectTypes, $subjectOnly, $searchIndexCondition, $additionalConditions, $orderBy, $limit); | |
118 | } | |
119 | ||
120 | /** | |
121 | * @inheritDoc | |
122 | */ | |
123 | public function getInnerJoin( | |
124 | $objectTypeName, | |
125 | $q, | |
126 | $subjectOnly = false, | |
127 | ?PreparedStatementConditionBuilder $searchIndexCondition = null, | |
128 | $orderBy = 'time DESC', | |
129 | $limit = 1000 | |
130 | ) { | |
131 | $conditionBuilderClassName = $this->getConditionBuilderClassName(); | |
132 | if ($searchIndexCondition !== null && !($searchIndexCondition instanceof $conditionBuilderClassName)) { | |
133 | throw new SystemException("Search engine '" . SEARCH_ENGINE . "' requires a different condition builder, please use 'SearchEngine::getInstance()->getConditionBuilderClassName()'!"); | |
134 | } | |
135 | ||
136 | return $this->getSearchEngine() | |
137 | ->getInnerJoin($objectTypeName, $q, $subjectOnly, $searchIndexCondition, $orderBy, $limit); | |
138 | } | |
139 | ||
140 | /** | |
141 | * @inheritDoc | |
142 | */ | |
143 | public function getConditionBuilderClassName() | |
144 | { | |
145 | return $this->getSearchEngine()->getConditionBuilderClassName(); | |
146 | } | |
147 | ||
148 | /** | |
149 | * @inheritDoc | |
150 | */ | |
151 | public function removeSpecialCharacters($string) | |
152 | { | |
153 | return $this->getSearchEngine()->removeSpecialCharacters($string); | |
154 | } | |
749cca08 | 155 | } |