mirror of
https://github.com/BookStackApp/BookStack.git
synced 2024-08-28 21:22:30 +00:00
Updated fulltext search with custom escaped query
Changed pdo quoted query to use custom escaping and added like searches when quoted terms are used.
This commit is contained in:
parent
33bf20cfc8
commit
bc2b310638
@ -87,8 +87,8 @@ abstract class Entity extends Model
|
|||||||
*/
|
*/
|
||||||
public function getShortName($length = 25)
|
public function getShortName($length = 25)
|
||||||
{
|
{
|
||||||
if(strlen($this->name) <= $length) return $this->name;
|
if (strlen($this->name) <= $length) return $this->name;
|
||||||
return substr($this->name, 0, $length-3) . '...';
|
return substr($this->name, 0, $length - 3) . '...';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -100,19 +100,34 @@ abstract class Entity extends Model
|
|||||||
*/
|
*/
|
||||||
public static function fullTextSearchQuery($fieldsToSearch, $terms, $wheres = [])
|
public static function fullTextSearchQuery($fieldsToSearch, $terms, $wheres = [])
|
||||||
{
|
{
|
||||||
|
$exactTerms = [];
|
||||||
foreach ($terms as $key => $term) {
|
foreach ($terms as $key => $term) {
|
||||||
$term = htmlentities($term);
|
$term = htmlentities($term, ENT_QUOTES);
|
||||||
|
$term = preg_replace('/[+\-><\(\)~*\"@]+/', ' ', $term);
|
||||||
if (preg_match('/\s/', $term)) {
|
if (preg_match('/\s/', $term)) {
|
||||||
|
$exactTerms[] = '%' . $term . '%';
|
||||||
$term = '"' . $term . '"';
|
$term = '"' . $term . '"';
|
||||||
|
} else {
|
||||||
|
$term = '' . $term . '*';
|
||||||
}
|
}
|
||||||
$terms[$key] = $term . '*';
|
if ($term !== '*') $terms[$key] = $term;
|
||||||
}
|
}
|
||||||
$termString = "'" . implode(' ', $terms) . "'";
|
$termString = implode(' ', $terms);
|
||||||
$fields = implode(',', $fieldsToSearch);
|
$fields = implode(',', $fieldsToSearch);
|
||||||
$termStringEscaped = \DB::connection()->getPdo()->quote($termString);
|
$search = static::selectRaw('*, MATCH(name) AGAINST(? IN BOOLEAN MODE) AS title_relevance', [$termString]);
|
||||||
$search = static::addSelect(\DB::raw('*, MATCH(name) AGAINST('.$termStringEscaped.' IN BOOLEAN MODE) AS title_relevance'));
|
|
||||||
$search = $search->whereRaw('MATCH(' . $fields . ') AGAINST(? IN BOOLEAN MODE)', [$termString]);
|
$search = $search->whereRaw('MATCH(' . $fields . ') AGAINST(? IN BOOLEAN MODE)', [$termString]);
|
||||||
|
|
||||||
|
// Ensure at least one exact term matches if in search
|
||||||
|
if (count($exactTerms) > 0) {
|
||||||
|
$search = $search->where(function($query) use ($exactTerms, $fieldsToSearch) {
|
||||||
|
foreach ($exactTerms as $exactTerm) {
|
||||||
|
foreach ($fieldsToSearch as $field) {
|
||||||
|
$query->orWhere($field, 'like', $exactTerm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Add additional where terms
|
// Add additional where terms
|
||||||
foreach ($wheres as $whereTerm) {
|
foreach ($wheres as $whereTerm) {
|
||||||
$search->where($whereTerm[0], $whereTerm[1], $whereTerm[2]);
|
$search->where($whereTerm[0], $whereTerm[1], $whereTerm[2]);
|
||||||
|
@ -233,7 +233,9 @@ class BookRepo
|
|||||||
} else {
|
} else {
|
||||||
$terms = [];
|
$terms = [];
|
||||||
}
|
}
|
||||||
$terms = array_merge($terms, explode(' ', $term));
|
if (!empty($term)) {
|
||||||
|
$terms = array_merge($terms, explode(' ', $term));
|
||||||
|
}
|
||||||
$books = $this->book->fullTextSearchQuery(['name', 'description'], $terms)
|
$books = $this->book->fullTextSearchQuery(['name', 'description'], $terms)
|
||||||
->paginate($count)->appends($paginationAppends);
|
->paginate($count)->appends($paginationAppends);
|
||||||
$words = join('|', explode(' ', preg_quote(trim($term), '/')));
|
$words = join('|', explode(' ', preg_quote(trim($term), '/')));
|
||||||
|
@ -138,7 +138,9 @@ class ChapterRepo
|
|||||||
} else {
|
} else {
|
||||||
$terms = [];
|
$terms = [];
|
||||||
}
|
}
|
||||||
$terms = array_merge($terms, explode(' ', $term));
|
if (!empty($term)) {
|
||||||
|
$terms = array_merge($terms, explode(' ', $term));
|
||||||
|
}
|
||||||
$chapters = $this->chapter->fullTextSearchQuery(['name', 'description'], $terms, $whereTerms)
|
$chapters = $this->chapter->fullTextSearchQuery(['name', 'description'], $terms, $whereTerms)
|
||||||
->paginate($count)->appends($paginationAppends);
|
->paginate($count)->appends($paginationAppends);
|
||||||
$words = join('|', explode(' ', preg_quote(trim($term), '/')));
|
$words = join('|', explode(' ', preg_quote(trim($term), '/')));
|
||||||
|
Loading…
Reference in New Issue
Block a user