[COMPONENT][Search] Move search form to utility function. Add search form and search builder forms to search results page

This commit is contained in:
Hugo Sales 2021-12-10 13:52:18 +00:00
parent 8beb9682ee
commit ada94a98e2
Signed by: someonewithpc
GPG Key ID: 7D0C7EAFC9D835A0
4 changed files with 54 additions and 52 deletions

View File

@ -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
];
}
}

View File

@ -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;
}
}

View File

@ -16,8 +16,18 @@
{% endif %}
<div class="section-widget-padded">
{% set query = query|escape %}
<h2>{% trans %}Search results for %query%{% endtrans %}</h2>
{{ form(search_form) }}
<hr>
<details>
<summary>
<h3>
{% trans %}Build a search query{% endtrans %}
{{ icon('arrow-down', 'icon icon-details-open') | raw }}
</h3>
</summary>
{{ form(search_builder_form) }}
</details>
<hr>
</div>
{# Backwards compatibility with hAtom 0.1 #}
@ -27,8 +37,7 @@
{% for note in notes %}
{% block current_note %}
<div class="section-widget">
{{ noteView.macro_note(note) }}
<hr tabindex="0" title="{{ 'End of note and replies.' | trans }}">
{{ noteView.macro_note(note['note'], []) }}
</div>
{% endblock current_note %}
{% endfor %}

View File

@ -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,