From 8beb9682ee7c0c1135054847f68e1203ed3e000d Mon Sep 17 00:00:00 2001 From: Hugo Sales Date: Fri, 10 Dec 2021 13:40:42 +0000 Subject: [PATCH] [COMPONENTS][Search][Language] Move language search features to the language component. Add support for searching for notes from people with a given language --- components/Language/Language.php | 38 ++++++++++++++++++++++++++++++++ components/Search/Search.php | 38 ++++++++++++++++++-------------- 2 files changed, 59 insertions(+), 17 deletions(-) diff --git a/components/Language/Language.php b/components/Language/Language.php index 0dd9932177..603507e841 100644 --- a/components/Language/Language.php +++ b/components/Language/Language.php @@ -26,6 +26,11 @@ use App\Core\Modules\Component; use App\Entity\Actor; use App\Entity\ActorLanguage; use App\Entity\Note; +use App\Util\Formatting; +use App\Util\Functional as GSF; +use Doctrine\Common\Collections\ExpressionBuilder; +use Doctrine\ORM\Query\Expr; +use Doctrine\ORM\QueryBuilder; use Functional as F; class Language extends Component @@ -39,4 +44,37 @@ class Language extends Component return Event::next; } + + /** + * Populate $note_expr or $actor_expr with an expression to match a language + */ + public function onSearchCreateExpression(ExpressionBuilder $eb, string $term, ?string $language, &$note_expr, &$actor_expr): bool + { + $search_term = str_contains($term, ':') ? explode(':', $term)[1] : $term; + if (Formatting::startsWith($term, ['lang', 'language'])) { + $note_expr = $eb->startsWith('note_language.locale', $search_term); + $actor_expr = $eb->startsWith('language.locale', $search_term); + return Event::stop; + } elseif (Formatting::startsWith($term, GSF::cartesianProduct(['-', '_'], ['note', 'post'], ['lang', 'language']))) { + $note_expr = $eb->startsWith('note_language.locale', $search_term); + return Event::stop; + } elseif (Formatting::startsWith($term, GSF::cartesianProduct(['-', '_'], ['note', 'post'], ['author', 'actor', 'people', 'person'], ['lang', 'language']))) { + $note_expr = $eb->startsWith('note_actor_language.locale', $search_term); + return Event::stop; + } elseif (Formatting::startsWith($term, GSF::cartesianProduct(['-', '_'], ['actor', 'people', 'person'], ['lang', 'language']))) { + $actor_expr = $eb->startsWith('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', 'note_language', Expr\Join::WITH, 'note.language_id = note_language.id') + ->leftJoin('App\Entity\ActorLanguage', 'actor_language', Expr\Join::WITH, 'note.actor_id = actor_language.actor_id') + ->leftJoin('App\Entity\Language', 'note_actor_language', Expr\Join::WITH, 'note_actor_language.id = actor_language.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/Search/Search.php b/components/Search/Search.php index df0380dc85..0173ca95f6 100644 --- a/components/Search/Search.php +++ b/components/Search/Search.php @@ -43,25 +43,20 @@ class Search extends Component $r->connect('search', '/search', Controller\Search::class); } - /** - * Add the search form to the site header - * - * @throws RedirectException - */ - public function onAddExtraHeaderForms(Request $request, array &$elements) + public static function searchForm(Request $request, ?string $query = null): FormView { $form = Form::create([ - ['search_tags', TextType::class, [ - 'attr' => ['placeholder' => _m('Input desired query...')], + ['search_query', TextType::class, [ + 'attr' => ['placeholder' => _m('Input desired query...'), 'value' => $query], ]], [$form_name = 'submit_search', SubmitType::class, - [ - 'label' => _m('Submit'), - 'attr' => [ - //'class' => 'button-container search-button-container', - 'title' => _m('Query notes for specific tags.'), - ], - ], + [ + 'label' => _m('Search'), + 'attr' => [ + //'class' => 'button-container search-button-container', + 'title' => _m('Query notes for specific tags.'), + ], + ], ], ]); @@ -69,11 +64,20 @@ class Search extends Component $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { $data = $form->getData(); - throw new RedirectException('search', ['q' => $data['search_tags']]); + throw new RedirectException('search', ['q' => $data['search_query']]); } } + return $form->createView(); + } - $elements[] = $form->createView(); + /** + * Add the search form to the site header + * + * @throws RedirectException + */ + public function onAddExtraHeaderForms(Request $request, array &$elements) + { + $elements[] = self::searchForm($request); return Event::next; }