Skip to content

Commit

Permalink
[FEATURE] Make it possible to add JOIN query part
Browse files Browse the repository at this point in the history
This patch makes it possible to add a JOIN
query part to the search query using the
"getQueryParts" hook.
  • Loading branch information
christianbltr committed Jan 17, 2025
1 parent 4cc4f44 commit d6aaabb
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 24 deletions.
1 change: 1 addition & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
ChangeLog

Upcoming version
[FEATURE] Make it possible to add JOIN query part via "getQueryParts" hook. Thanks to André Müller
[BUGFIX] Account for files without file extension. Thanks to Simon Praetorius. https://github.com/tpwd/ke_search/pull/268
[BUGFIX] Retain filter order from configuration. Thanks to Simon Praetorius. https://github.com/tpwd/ke_search/pull/272
[TASK] Switch to PHP based rendering for documentation. Thanks to Chris Müller. https://github.com/tpwd/ke_search/pull/265
Expand Down
62 changes: 38 additions & 24 deletions Classes/Lib/Db.php
Original file line number Diff line number Diff line change
Expand Up @@ -148,23 +148,27 @@ public function getSearchResultByMySQL()
$orderField = strtoupper($orderParts[0]);
$orderDirection = strtoupper($orderParts[1] ?? 'ASC');
if ($count == 0) {
if (ExtensionManagementUtility::isLoaded('ke_search_premium')
&& ($orderField == 'customranking')) {
if (
ExtensionManagementUtility::isLoaded('ke_search_premium')
&& ($orderField == 'customranking')
) {
// We cast `customranking` to integer because additionalFields in ke_search can only
// be string, so we cannot use an integer field, although it's a numeric value (can also be
// negative).
$resultQuery->getConcreteQueryBuilder()->orderBy(
'CAST(' . $queryBuilder->quoteIdentifier($orderField) . ' AS SIGNED)',
'CAST(tx_kesearch_index.' . $queryBuilder->quoteIdentifier($orderField) . ' AS SIGNED)',
$orderDirection
);
} else {
$resultQuery->orderBy($orderField, $orderDirection);
}
} else {
if (ExtensionManagementUtility::isLoaded('ke_search_premium')
&& ($orderField == 'customranking')) {
if (
ExtensionManagementUtility::isLoaded('ke_search_premium')
&& ($orderField == 'customranking')
) {
$resultQuery->getConcreteQueryBuilder()->addOrderBy(
'CAST(' . $queryBuilder->quoteIdentifier($orderField) . ' AS SIGNED)',
'CAST(tx_kesearch_index.' . $queryBuilder->quoteIdentifier($orderField) . ' AS SIGNED)',
$orderDirection
);
} else {
Expand All @@ -179,6 +183,17 @@ public function getSearchResultByMySQL()
}
}

if (!empty($queryParts['JOIN'] && is_array($queryParts['JOIN']))) {
foreach ($queryParts['JOIN'] as $table => $condition) {
$resultQuery->join(
'tx_kesearch_index',
$table,
$table,
$condition ?: null,
);
}
}

$limit = $this->getLimit();
if (is_array($limit)) {
$resultQuery->setMaxResults($limit[1]);
Expand Down Expand Up @@ -345,6 +360,7 @@ public function getQueryParts()
$queryParts = [
'SELECT' => $this->getFields($searchwordQuoted),
'FROM' => $this->table,
'JOIN' => null,
'WHERE' => '1=1' . $this->getWhere(),
'GROUPBY' => '',
'ORDERBY' => $this->getOrdering(),
Expand Down Expand Up @@ -438,21 +454,19 @@ protected function getTagsFromMySQL()

if (GeneralUtility::makeInstance(Typo3Version::class)->getMajorVersion() < 13) {
// @phpstan-ignore-next-line
$tagRows = $queryBuilder
->select('tags')
$resultQuery = $queryBuilder
->select('tx_kesearch_index.tags')
->from($queryParts['FROM'])
->add('where', $queryParts['WHERE'])
->executeQuery()
->fetchAllAssociative();
->add('where', $queryParts['WHERE']);
} else {
$tagRows = $queryBuilder
->select('tags')
$resultQuery = $queryBuilder
->select('tx_kesearch_index.tags')
->from($queryParts['FROM'])
->where($queryParts['WHERE'])
->executeQuery()
->fetchAllAssociative();
->where($queryParts['WHERE']);
}

$tagRows = $resultQuery->executeQuery()->fetchAllAssociative();

return array_map(
function ($row) {
return $row['tags'];
Expand All @@ -478,7 +492,7 @@ protected function createQueryForTags(array $tags)
$value = $databaseConnection->quote((string)$value);
$value = rtrim($value, "'");
$value = ltrim($value, "'");
$where .= ' AND MATCH (tags) AGAINST (\'' . $value . '\' IN BOOLEAN MODE) ';
$where .= ' AND MATCH (tx_kesearch_index.tags) AGAINST (\'' . $value . '\' IN BOOLEAN MODE) ';
}
return $where;
}
Expand All @@ -502,15 +516,15 @@ private function getMatchColumns(): string
*/
public function getFields(string $searchwordQuoted): string
{
$fields = 'SQL_CALC_FOUND_ROWS *';
$fields = 'SQL_CALC_FOUND_ROWS tx_kesearch_index.*';

// if a searchword was given, calculate score
if ($this->pObj->sword) {
$fields .=
', MATCH (' . $this->getMatchColumns() . ') AGAINST (' . $searchwordQuoted . ')'
. '+ ('
. $this->pObj->extConf['multiplyValueToTitle']
. ' * MATCH (title) AGAINST (' . $searchwordQuoted . ')'
. ' * MATCH (tx_kesearch_index.title) AGAINST (' . $searchwordQuoted . ')'
. ') AS score';
}

Expand Down Expand Up @@ -549,16 +563,16 @@ public function getWhere()
. 'https://docs.typo3.org/p/tpwd/ke_search/main/en-us/Configuration/OverrideRecordStoragePage.html.');
}
$startingPoints = $this->pObj->pi_getPidList($this->pObj->startingPoints);
$where .= ' AND pid in (' . $startingPoints . ') ';
$where .= ' AND tx_kesearch_index.pid in (' . $startingPoints . ') ';

// add language
/** @var LanguageAspect $languageAspect */
$languageAspect = GeneralUtility::makeInstance(Context::class)->getAspect('language');
$where .= ' AND language IN(' . $languageAspect->getId() . ', -1) ';
$where .= ' AND tx_kesearch_index.language IN(' . $languageAspect->getId() . ', -1) ';

// add "tagged content only" searchphrase
if ($this->conf['showTaggedContentOnly'] ?? false) {
$where .= ' AND tags <> ""';
$where .= ' AND tx_kesearch_index.tags <> ""';
}

// add enable fields
Expand Down Expand Up @@ -593,10 +607,10 @@ public function createQueryForDateRange()
$startTimestamp = strtotime($filterValues['start'] ?? '');
$endTimestamp = strtotime($filterValues['end'] ?? '');
if ($startTimestamp) {
$where .= ' AND sortdate >= ' . $startTimestamp;
$where .= ' AND tx_kesearch_index.sortdate >= ' . $startTimestamp;
}
if ($endTimestamp) {
$where .= ' AND sortdate <= ' . ($endTimestamp + 24 * 60 * 60);
$where .= ' AND tx_kesearch_index.sortdate <= ' . ($endTimestamp + 24 * 60 * 60);
}
}
}
Expand Down

0 comments on commit d6aaabb

Please sign in to comment.