From 139da2c07fe20b4d30f97dbf6457bc4d96051902 Mon Sep 17 00:00:00 2001 From: Hugo Sales Date: Wed, 8 Dec 2021 21:07:50 +0000 Subject: [PATCH] [COMPONENT][Search][Tag] Add support for searching for actors or notes with a language. Use leftJoins, rather than inner joins --- components/Search/Search.php | 29 +++++++++++++++++++++++++++++ components/Tag/Tag.php | 4 ++-- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/components/Search/Search.php b/components/Search/Search.php index 76e27163b0..0c862e1cf8 100644 --- a/components/Search/Search.php +++ b/components/Search/Search.php @@ -28,6 +28,10 @@ use App\Core\Form; use function App\Core\I18n\_m; use App\Core\Modules\Component; use App\Util\Exception\RedirectException; +use App\Util\Formatting; +use Doctrine\Common\Collections\ExpressionBuilder; +use Doctrine\ORM\Query\Expr; +use Doctrine\ORM\QueryBuilder; use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\HttpFoundation\Request; @@ -41,6 +45,7 @@ class Search extends Component /** * Add the search form to the site header + * * @throws RedirectException */ public function onAddExtraHeaderForms(Request $request, array &$elements) @@ -84,4 +89,28 @@ class Search extends Component $styles[] = 'components/Search/assets/css/view.css'; return Event::next; } + + /** + * Populate $note_expr with an expression to match a tag, if the term looks like a tag + * + * $term /^(note|tag|people|actor)/ means we want to match only either a note or an actor + */ + public function onSearchCreateExpression(ExpressionBuilder $eb, string $term, ?string $language, &$note_expr, &$actor_expr): bool + { + if (Formatting::startsWith($term, ['lang', 'language'])) { + $search_term = str_contains($term, ':') ? explode(':', $term)[1] : $term; + $note_expr = $eb->eq('language.locale', $search_term); + $actor_expr = $eb->eq('language.locale', $search_term); + return Event::stop; + } + return Event::next; + } + + public function onSearchQueryAddJoins(QueryBuilder &$note_qb, QueryBuilder &$actor_qb): bool + { + $note_qb->leftJoin('App\Entity\Language', 'language', Expr\Join::WITH, 'note.language_id = language.id'); + $actor_qb->leftJoin('App\Entity\ActorLanguage', 'actor_language', Expr\Join::WITH, 'actor.id = actor_language.actor_id') + ->leftJoin('App\Entity\Language', 'language', Expr\Join::WITH, 'actor_language.language_id = language.id'); + return Event::next; + } } diff --git a/components/Tag/Tag.php b/components/Tag/Tag.php index 7ab079e06c..00632132d5 100644 --- a/components/Tag/Tag.php +++ b/components/Tag/Tag.php @@ -170,8 +170,8 @@ class Tag extends Component public function onSearchQueryAddJoins(QueryBuilder &$note_qb, QueryBuilder &$actor_qb): bool { - $note_qb->join('App\Entity\NoteTag', 'note_tag', Expr\Join::WITH, 'note_tag.note_id = note.id'); - $actor_qb->join('App\Entity\ActorTag', 'actor_tag', Expr\Join::WITH, 'actor_tag.tagger = actor.id'); + $note_qb->leftJoin('App\Entity\NoteTag', 'note_tag', Expr\Join::WITH, 'note_tag.note_id = note.id'); + $actor_qb->leftJoin('App\Entity\ActorTag', 'actor_tag', Expr\Join::WITH, 'actor_tag.tagger = actor.id'); return Event::next; }