forked from GNUsocial/gnu-social
[COMPONENT][Search] Fix search
This commit is contained in:
parent
c131e47176
commit
f9fedfb131
@ -26,20 +26,26 @@ namespace Component\Search\Controller;
|
|||||||
use App\Core\Controller;
|
use App\Core\Controller;
|
||||||
use App\Core\DB\DB;
|
use App\Core\DB\DB;
|
||||||
use App\Core\Event;
|
use App\Core\Event;
|
||||||
|
use App\Util\Common;
|
||||||
use Component\Search\Util\Parser;
|
use Component\Search\Util\Parser;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
|
||||||
class Search extends Controller
|
class Search extends Controller
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Handle a search query
|
||||||
|
*/
|
||||||
public function handle(Request $request)
|
public function handle(Request $request)
|
||||||
{
|
{
|
||||||
|
$actor = Common::actor();
|
||||||
|
$language = !\is_null($actor) ? $actor->getTopLanguage()->getLocale() : null;
|
||||||
$q = $this->string('q');
|
$q = $this->string('q');
|
||||||
[$note_criteria, $actor_criteria] = Parser::parse($q);
|
[$note_criteria, $actor_criteria] = Parser::parse($q, $language);
|
||||||
|
|
||||||
$note_qb = DB::createQueryBuilder();
|
$note_qb = DB::createQueryBuilder();
|
||||||
$actor_qb = DB::createQueryBuilder();
|
$actor_qb = DB::createQueryBuilder();
|
||||||
$note_qb->select('note')->from('App\Entity\Note', 'note');
|
$note_qb->select('note')->from('App\Entity\Note', 'note')->orderBy('note.created', 'DESC');
|
||||||
$actor_qb->select('actor')->from('App\Entity\Actor', 'actor');
|
$actor_qb->select('actor')->from('App\Entity\Actor', 'actor')->orderBy('actor.created', 'DESC');
|
||||||
Event::handle('SearchQueryAddJoins', [&$note_qb, &$actor_qb]);
|
Event::handle('SearchQueryAddJoins', [&$note_qb, &$actor_qb]);
|
||||||
$notes = $actors = [];
|
$notes = $actors = [];
|
||||||
if (!\is_null($note_criteria)) {
|
if (!\is_null($note_criteria)) {
|
||||||
|
@ -53,7 +53,7 @@ abstract class Parser
|
|||||||
*
|
*
|
||||||
* @return Criteria[]
|
* @return Criteria[]
|
||||||
*/
|
*/
|
||||||
public static function parse(string $input, int $level = 0): array
|
public static function parse(string $input, ?string $language = null, int $level = 0): array
|
||||||
{
|
{
|
||||||
if ($level === 0) {
|
if ($level === 0) {
|
||||||
$input = trim(preg_replace(['/\s+/', '/\s+AND\s+/', '/\s+OR\s+/'], [' ', '&', '|'], $input), ' |&');
|
$input = trim(preg_replace(['/\s+/', '/\s+AND\s+/', '/\s+OR\s+/'], [' ', '&', '|'], $input), ' |&');
|
||||||
@ -77,8 +77,8 @@ abstract class Parser
|
|||||||
if ($input[$index] === $delimiter || $end = ($index === $lenght - 1)) {
|
if ($input[$index] === $delimiter || $end = ($index === $lenght - 1)) {
|
||||||
$term = mb_substr($input, $left, $end ? null : $right - $left);
|
$term = mb_substr($input, $left, $end ? null : $right - $left);
|
||||||
$note_res = $actor_res = null;
|
$note_res = $actor_res = null;
|
||||||
$ret = Event::handle('SearchCreateExpression', [$eb, $term, &$note_res, &$actor_res]);
|
$ret = Event::handle('SearchCreateExpression', [$eb, $term, $language, &$note_res, &$actor_res]);
|
||||||
if ((\is_null($note_res) && \is_null($actor_res)) || $ret == Event::next) {
|
if (\is_null($note_res) && \is_null($actor_res)) {
|
||||||
throw new ServerException("No one claimed responsibility for a match term: {$term}");
|
throw new ServerException("No one claimed responsibility for a match term: {$term}");
|
||||||
} elseif (!\is_null($note_res)) {
|
} elseif (!\is_null($note_res)) {
|
||||||
$note_parts[] = $note_res;
|
$note_parts[] = $note_res;
|
||||||
|
@ -150,21 +150,20 @@ class Tag extends Component
|
|||||||
*
|
*
|
||||||
* $term /^(note|tag|people|actor)/ means we want to match only either a note or an actor
|
* $term /^(note|tag|people|actor)/ means we want to match only either a note or an actor
|
||||||
*/
|
*/
|
||||||
public function onSearchCreateExpression(ExpressionBuilder $eb, string $term, &$note_expr, &$actor_expr): bool
|
public function onSearchCreateExpression(ExpressionBuilder $eb, string $term, ?string $language, &$note_expr, &$actor_expr): bool
|
||||||
{
|
{
|
||||||
$search_term = str_contains($term, ':#') ? explode(':', $term)[1] : $term;
|
$search_term = str_contains($term, ':#') ? explode(':', $term)[1] : $term;
|
||||||
$temp_note_expr = $eb->eq('note_tag.tag', $search_term);
|
$canon_search_term = self::canonicalTag($search_term, $language);
|
||||||
$temp_actor_expr = $eb->eq('actor_tag.tag', $search_term);
|
$temp_note_expr = $eb->eq('note_tag.canonical', $canon_search_term);
|
||||||
|
$temp_actor_expr = $eb->eq('actor_tag.canonical', $canon_search_term);
|
||||||
if (Formatting::startsWith($term, ['note', 'tag'])) {
|
if (Formatting::startsWith($term, ['note', 'tag'])) {
|
||||||
$note_expr = $temp_note_expr;
|
$note_expr = $temp_note_expr;
|
||||||
|
} elseif (Formatting::startsWith($term, ['people', 'actor'])) {
|
||||||
|
$actor_expr = $temp_actor_expr;
|
||||||
} else {
|
} else {
|
||||||
if (Formatting::startsWith($term, ['people', 'actor'])) {
|
$note_expr = $temp_note_expr;
|
||||||
$actor_expr = $temp_actor_expr;
|
$actor_expr = $temp_actor_expr;
|
||||||
} else {
|
return Event::next;
|
||||||
$note_expr = $temp_note_expr;
|
|
||||||
$actor_expr = $temp_actor_expr;
|
|
||||||
return Event::next;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return Event::stop;
|
return Event::stop;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user