diff --git a/components/Search/Controller/Search.php b/components/Search/Controller/Search.php index 9d751cd7a1..d664a0bbf7 100644 --- a/components/Search/Controller/Search.php +++ b/components/Search/Controller/Search.php @@ -26,8 +26,15 @@ namespace Component\Search\Controller; use App\Core\Controller\FeedController; use App\Core\DB\DB; use App\Core\Event; +use App\Core\Form; +use function App\Core\I18n\_m; use App\Util\Common; +use App\Util\Exception\RedirectException; +use App\Util\Form\FormFields; +use Component\Search as Comp; use Component\Search\Util\Parser; +use Symfony\Component\Form\Extension\Core\Type\SubmitType; +use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\HttpFoundation\Request; class Search extends FeedController @@ -59,12 +66,31 @@ class Search extends FeedController $actors = $actor_qb->getQuery()->execute(); } + $search_builder_form = Form::create([ + FormFields::language($actor, context_actor: null, label: _m('Search for notes in these languages'), multiple: true, required: false, use_short_display: false, form_id: 'note-langs'), + ['note-tags', TextType::class, ['required' => false, 'label' => _m('Include notes with all the following tags')]], + FormFields::language($actor, context_actor: null, label: _m('Search for actors in these languages'), multiple: true, required: false, use_short_display: false, form_id: 'actor-langs'), + ['actor-tags', TextType::class, ['required' => false, 'label' => _m('Include people with all the following tags')]], + [$form_name = 'search_builder', SubmitType::class, ['label' => _m('Search')]], + ]); + + if ('POST' === $request->getMethod() && $request->request->has($form_name)) { + $search_builder_form->handleRequest($request); + if ($search_builder_form->isSubmitted() && $search_builder_form->isValid()) { + $data = $search_builder_form->getData(); + $query = ''; + + throw new RedirectException('search', ['q' => $data[$form_name]]); + } + } + return [ - '_template' => 'search/show.html.twig', - 'query' => $q, - 'notes' => $notes, - 'actors' => $actors, - 'page' => 1, // TODO paginate + '_template' => 'search/show.html.twig', + 'search_form' => Comp\Search::searchForm($request, $q), + 'search_builder_form' => $search_builder_form->createView(), + 'notes' => $notes, + 'actors' => $actors, + 'page' => 1, // TODO paginate ]; } } diff --git a/components/Search/Search.php b/components/Search/Search.php index 0173ca95f6..bbaf34cb58 100644 --- a/components/Search/Search.php +++ b/components/Search/Search.php @@ -28,12 +28,9 @@ 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\Form\FormView; use Symfony\Component\HttpFoundation\Request; class Search extends Component @@ -50,13 +47,13 @@ class Search extends Component 'attr' => ['placeholder' => _m('Input desired query...'), 'value' => $query], ]], [$form_name = 'submit_search', SubmitType::class, - [ - 'label' => _m('Search'), - '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.'), + ], + ], ], ]); @@ -93,34 +90,4 @@ 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 - { - $search_term = str_contains($term, ':') ? explode(':', $term)[1] : $term; - if (Formatting::startsWith($term, ['lang', 'language'])) { - $note_expr = $eb->startsWith('language.locale', $search_term); - $actor_expr = $eb->startsWith('language.locale', $search_term); - return Event::stop; - } elseif (Formatting::startsWith($term, ['note-lang', 'note-language', 'note_lang', 'note_language', 'post_lang', 'post_language', 'post-lang', 'post-language'])) { - $note_expr = $eb->startsWith('language.locale', $search_term); - return Event::stop; - } elseif (Formatting::startsWith($term, ['actor-lang', 'actor-language', 'actor_lang', 'actor_language', 'people_lang', 'people_language', 'people-lang', 'people-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', '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/Search/templates/search/show.html.twig b/components/Search/templates/search/show.html.twig index 5d17f72f9f..db467d699f 100644 --- a/components/Search/templates/search/show.html.twig +++ b/components/Search/templates/search/show.html.twig @@ -16,8 +16,18 @@ {% endif %}
- {% set query = query|escape %} -

{% trans %}Search results for %query%{% endtrans %}

+ {{ form(search_form) }} +
+
+ +

+ {% trans %}Build a search query{% endtrans %} + {{ icon('arrow-down', 'icon icon-details-open') | raw }} +

+
+ {{ form(search_builder_form) }} +
+
{# Backwards compatibility with hAtom 0.1 #} @@ -27,8 +37,7 @@ {% for note in notes %} {% block current_note %}
- {{ noteView.macro_note(note) }} -
+ {{ noteView.macro_note(note['note'], []) }}
{% endblock current_note %} {% endfor %} diff --git a/src/Util/Form/FormFields.php b/src/Util/Form/FormFields.php index 065c69757a..b31bb1301e 100644 --- a/src/Util/Form/FormFields.php +++ b/src/Util/Form/FormFields.php @@ -80,11 +80,11 @@ abstract class FormFields /** * Create a from field for `select`ing a language for $actor, in reply or related to $context_actor */ - public static function language(Actor $actor, ?Actor $context_actor, string $label, ?string $help = null, bool $multiple = false, bool $required = true, ?bool $use_short_display = null): array + public static function language(Actor $actor, ?Actor $context_actor, string $label, ?string $help = null, bool $multiple = false, bool $required = true, ?bool $use_short_display = null, ?string $form_id = null): array { [$language_choices, $preferred_language_choices] = Language::getSortedLanguageChoices($actor, $context_actor, use_short_display: $use_short_display); return [ - 'language' . ($multiple ? 's' : ''), + $form_id ?? 'language' . ($multiple ? 's' : ''), ChoiceType::class, [ 'label' => $label,