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