Search/Fixup

* strip leading/trailing dashes from search tokens.
   Casues FT syntax errors when combined with our own modifiers
This commit is contained in:
Sarjuuk 2026-01-19 19:30:03 +01:00
parent 0ea5477d6e
commit 53374972ef
2 changed files with 44 additions and 17 deletions

View file

@ -556,7 +556,7 @@ abstract class Filter
return false;
}
protected function transformToken(string $string, string $outPH) : string
protected function transformToken(string $string, bool $exact) : string
{
// escape manually entered _; entering % should be prohibited
$string = str_replace('_', '\\_', $string);
@ -564,7 +564,7 @@ abstract class Filter
// now replace search wildcards with sql wildcards
$string = strtr($string, self::$wCards);
return sprintf($outPH, $string);
return sprintf($exact ? '%s' : '%%%s%%', $string);
}
protected function tokenizeString(array $fields, string $string = '', bool $exact = false, bool $shortStr = false) : array
@ -579,14 +579,14 @@ abstract class Filter
$qry = [];
foreach ($fields as $f)
{
$sub = [];
$parts = $exact ? [$string] : array_filter(explode(' ', $string));
foreach ($parts as $p)
$sub = [];
$tokens = $exact ? [$string] : array_filter(explode(' ', $string));
foreach ($tokens as $t)
{
if ($p[0] == '-' && (mb_strlen($p) > 3 || $shortStr))
$sub[] = [$f, $this->transformToken(mb_substr($p, 1), $exact ? '%s' : '%%%s%%'), '!'];
else if ($p[0] != '-' && (mb_strlen($p) > 2 || $shortStr))
$sub[] = [$f, $this->transformToken($p, $exact ? '%s' : '%%%s%%')];
if ($t[0] == '-' && (mb_strlen($t) > 3 || $shortStr))
$sub[] = [$f, $this->transformToken(mb_substr($t, 1), $exact), '!'];
else if ($t[0] != '-' && (mb_strlen($t) > 2 || $shortStr))
$sub[] = [$f, $this->transformToken($t, $exact)];
}
// single cnd?
@ -619,7 +619,6 @@ abstract class Filter
if (!$string && $this->values['na'])
$string = $this->values['na'];
// always allow sub 3 chars for logographic locales
if (Lang::getLocale()->isLogographic() && !Cfg::get('LOGOGRAPHIC_FT_SEARCH'))
return $this->tokenizeString($fields, $string, $exact, $shortStr);
@ -627,14 +626,30 @@ abstract class Filter
if (!$string)
return [];
$sub = [];
$parts = $exact ? [$string] : array_filter(explode(' ', $string));
foreach ($parts as $p)
// always allow sub 3 chars for logographic locales
if (Lang::getLocale()->isLogographic())
$shortStr = true;
$sub = [];
$tokens = $exact ? [$string] : array_filter(explode(' ', $string));
foreach ($tokens as $t)
{
if ($p[0] == '-' && (mb_strlen($p) > 3 || $shortStr))
$sub[] = $this->transformToken($p, '%s*');
else if ($p[0] != '-' && (mb_strlen($p) > 2 || $shortStr))
$sub[] = $this->transformToken($p, '+%s*');
$ex = $t[0] === '-';
if ($ex)
$t = mb_substr($t, 1);
// cant have trailing/leading dashes. FT confuses them for additional modifiers and dies with a syntax error
// would be an issue for all modifiers, but Filter::PATTERN_FT only allows for - at this point
while (($t[0] ?? '') === '-')
$t = mb_substr($t, 1);
while (($t[-1] ?? '') === '-')
$t = mb_substr($t, 0, -1);
if (!$shortStr && mb_strlen($t) < 3)
continue;
$sub[] = ($ex ? '-' : '+') . $t . '*';
}
$qry = [];

View file

@ -133,9 +133,21 @@ class Search
// note: a fulltext search purely with exclude tokens will return no result
if (($tokens = trim(preg_replace(Filter::PATTERN_FT, ' ', $clean))) !== '')
{
foreach (array_filter(explode(' ', $tokens)) as $t)
{
// cant have trailing/leading dashes. FT confuses them for additional modifiers and dies with a syntax error
// would be an issue for all modifiers, but Filter::PATTERN_FT only allows for - at this point
while (($t[0] ?? '') === '-')
$t = mb_substr($t, 1);
while (($t[-1] ?? '') === '-')
$t = mb_substr($t, 0, -1);
if (mb_strlen($t) > 2)
$this->fulltext[] = ($ex ? '-' : '+') . $t . '*';
}
}
}
}