/** * @see \wcf\system\search\ISearchEngine::search() */ public function search($q, array $objectTypes, $subjectOnly = false, PreparedStatementConditionBuilder $searchIndexCondition = null, array $additionalConditions = array(), $orderBy = 'time DESC', $limit = 1000) { // build search query $sql = ''; $parameters = array(); foreach ($objectTypes as $objectTypeName) { $objectType = SearchEngine::getInstance()->getObjectType($objectTypeName); if (!empty($sql)) { $sql .= "\nUNION ALL\n"; } $additionalConditionsConditionBuilder = isset($additionalConditions[$objectTypeName]) ? $additionalConditions[$objectTypeName] : null; $query = $objectType->getOuterSQLQuery($q, $searchIndexCondition, $additionalConditionsConditionBuilder); if (empty($query)) { $query = "SELECT\t" . $objectType->getIDFieldName() . " AS objectID,\n\t\t\t\t\t\t\t" . $objectType->getSubjectFieldName() . " AS subject,\n\t\t\t\t\t\t\t" . $objectType->getTimeFieldName() . " AS time,\n\t\t\t\t\t\t\t" . $objectType->getUsernameFieldName() . " AS username,\n\t\t\t\t\t\t\t'" . $objectTypeName . "' AS objectType\n\t\t\t\t\t\t\t" . ($orderBy == 'relevance ASC' || $orderBy == 'relevance DESC' ? ',search_index.relevance' : '') . "\n\t\t\t\t\tFROM\t\t" . $objectType->getTableName() . "\n\t\t\t\t\tINNER JOIN\t(\n\t\t\t\t\t\t\t\t{WCF_SEARCH_INNER_JOIN}\n\t\t\t\t\t\t\t) search_index\n\t\t\t\t\tON\t\t(" . $objectType->getIDFieldName() . " = search_index.objectID)\n\t\t\t\t\t" . $objectType->getJoins() . "\n\t\t\t\t\t" . (isset($additionalConditions[$objectTypeName]) ? $additionalConditions[$objectTypeName] : ''); } if (mb_strpos($query, '{WCF_SEARCH_INNER_JOIN}')) { $innerJoin = $this->getInnerJoin($objectTypeName, $q, $subjectOnly, $searchIndexCondition, $orderBy, $limit); $query = str_replace('{WCF_SEARCH_INNER_JOIN}', $innerJoin['sql'], $query); if ($innerJoin['fulltextCondition'] !== null) { $parameters = array_merge($parameters, $innerJoin['fulltextCondition']->getParameters()); } } if ($searchIndexCondition !== null) { $parameters = array_merge($parameters, $searchIndexCondition->getParameters()); } if (isset($additionalConditions[$objectTypeName])) { $parameters = array_merge($parameters, $additionalConditions[$objectTypeName]->getParameters()); } $sql .= $query; } if (empty($sql)) { throw new SystemException('no object types given'); } if (!empty($orderBy)) { $sql .= " ORDER BY " . $orderBy; } // send search query $messages = array(); $statement = WCF::getDB()->prepareStatement($sql, $limit); $statement->execute($parameters); while ($row = $statement->fetchArray()) { $messages[] = array('objectID' => $row['objectID'], 'objectType' => $row['objectType']); } return $messages; }
/** * Gets the conditions for a search in the table of the selected object types. */ protected function getConditions() { if (empty($this->selectedObjectTypes)) { $this->selectedObjectTypes = array_keys(SearchEngine::getInstance()->getAvailableObjectTypes()); } // default conditions $userIDs = $this->getUserIDs(); $conditionBuilderClassName = SearchEngine::getInstance()->getConditionBuilderClassName(); $this->searchIndexCondition = new $conditionBuilderClassName(false); // user ids if (!empty($userIDs)) { $this->searchIndexCondition->add('userID IN (?)', array($userIDs)); } // dates $startDate = @strtotime($this->startDate); $endDate = @strtotime($this->endDate); if ($startDate && $endDate) { $this->searchIndexCondition->add('time BETWEEN ? AND ?', array($startDate, $endDate)); } else { if ($startDate) { $this->searchIndexCondition->add('time > ?', array($startDate)); } else { if ($endDate) { $this->searchIndexCondition->add('time < ?', array($endDate)); } } } // language if (!empty($this->query) && LanguageFactory::getInstance()->multilingualismEnabled() && count(WCF::getUser()->getLanguageIDs())) { $this->searchIndexCondition->add('(languageID IN (?) OR languageID = 0)', array(WCF::getUser()->getLanguageIDs())); } foreach ($this->selectedObjectTypes as $key => $objectTypeName) { $objectType = SearchEngine::getInstance()->getObjectType($objectTypeName); if ($objectType === null) { throw new SystemException('unknown search object type ' . $objectTypeName); } try { if (!$objectType->isAccessible()) { throw new PermissionDeniedException(); } // special conditions if (($conditionBuilder = $objectType->getConditions($this)) !== null) { $this->additionalConditions[$objectTypeName] = $conditionBuilder; } } catch (PermissionDeniedException $e) { unset($this->selectedObjectTypes[$key]); continue; } } if (empty($this->selectedObjectTypes)) { $this->throwNoMatchesException(); } }
/** * @see \wcf\page\IPage::assignVariables() */ public function assignVariables() { parent::assignVariables(); WCF::getTPL()->assign(array('query' => $this->searchData['query'], 'objects' => $this->messages, 'searchData' => $this->searchData, 'searchID' => $this->searchID, 'highlight' => $this->highlight, 'sortField' => $this->searchData['sortField'], 'sortOrder' => $this->searchData['sortOrder'], 'alterable' => !empty($this->searchData['alterable']) ? 1 : 0, 'objectTypes' => SearchEngine::getInstance()->getAvailableObjectTypes(), 'resultListTemplateName' => $this->resultListTemplateName, 'resultListApplication' => $this->resultListApplication, 'application' => ApplicationHandler::getInstance()->getAbbreviation(ApplicationHandler::getInstance()->getActiveApplication()->packageID))); }