forked from GNUsocial/gnu-social
[COMPONENT][Search] Move search form to utility function. Add search form and search builder forms to search results page
This commit is contained in:
parent
8beb9682ee
commit
ada94a98e2
@ -26,8 +26,15 @@ namespace Component\Search\Controller;
|
|||||||
use App\Core\Controller\FeedController;
|
use App\Core\Controller\FeedController;
|
||||||
use App\Core\DB\DB;
|
use App\Core\DB\DB;
|
||||||
use App\Core\Event;
|
use App\Core\Event;
|
||||||
|
use App\Core\Form;
|
||||||
|
use function App\Core\I18n\_m;
|
||||||
use App\Util\Common;
|
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 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;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
|
||||||
class Search extends FeedController
|
class Search extends FeedController
|
||||||
@ -59,12 +66,31 @@ class Search extends FeedController
|
|||||||
$actors = $actor_qb->getQuery()->execute();
|
$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 [
|
return [
|
||||||
'_template' => 'search/show.html.twig',
|
'_template' => 'search/show.html.twig',
|
||||||
'query' => $q,
|
'search_form' => Comp\Search::searchForm($request, $q),
|
||||||
'notes' => $notes,
|
'search_builder_form' => $search_builder_form->createView(),
|
||||||
'actors' => $actors,
|
'notes' => $notes,
|
||||||
'page' => 1, // TODO paginate
|
'actors' => $actors,
|
||||||
|
'page' => 1, // TODO paginate
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,12 +28,9 @@ use App\Core\Form;
|
|||||||
use function App\Core\I18n\_m;
|
use function App\Core\I18n\_m;
|
||||||
use App\Core\Modules\Component;
|
use App\Core\Modules\Component;
|
||||||
use App\Util\Exception\RedirectException;
|
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\SubmitType;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||||
|
use Symfony\Component\Form\FormView;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
|
||||||
class Search extends Component
|
class Search extends Component
|
||||||
@ -50,13 +47,13 @@ class Search extends Component
|
|||||||
'attr' => ['placeholder' => _m('Input desired query...'), 'value' => $query],
|
'attr' => ['placeholder' => _m('Input desired query...'), 'value' => $query],
|
||||||
]],
|
]],
|
||||||
[$form_name = 'submit_search', SubmitType::class,
|
[$form_name = 'submit_search', SubmitType::class,
|
||||||
[
|
[
|
||||||
'label' => _m('Search'),
|
'label' => _m('Search'),
|
||||||
'attr' => [
|
'attr' => [
|
||||||
//'class' => 'button-container search-button-container',
|
//'class' => 'button-container search-button-container',
|
||||||
'title' => _m('Query notes for specific tags.'),
|
'title' => _m('Query notes for specific tags.'),
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@ -93,34 +90,4 @@ class Search extends Component
|
|||||||
$styles[] = 'components/Search/assets/css/view.css';
|
$styles[] = 'components/Search/assets/css/view.css';
|
||||||
return Event::next;
|
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -16,8 +16,18 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<div class="section-widget-padded">
|
<div class="section-widget-padded">
|
||||||
{% set query = query|escape %}
|
{{ form(search_form) }}
|
||||||
<h2>{% trans %}Search results for %query%{% endtrans %}</h2>
|
<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>
|
</div>
|
||||||
|
|
||||||
{# Backwards compatibility with hAtom 0.1 #}
|
{# Backwards compatibility with hAtom 0.1 #}
|
||||||
@ -27,8 +37,7 @@
|
|||||||
{% for note in notes %}
|
{% for note in notes %}
|
||||||
{% block current_note %}
|
{% block current_note %}
|
||||||
<div class="section-widget">
|
<div class="section-widget">
|
||||||
{{ noteView.macro_note(note) }}
|
{{ noteView.macro_note(note['note'], []) }}
|
||||||
<hr tabindex="0" title="{{ 'End of note and replies.' | trans }}">
|
|
||||||
</div>
|
</div>
|
||||||
{% endblock current_note %}
|
{% endblock current_note %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
@ -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
|
* 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);
|
[$language_choices, $preferred_language_choices] = Language::getSortedLanguageChoices($actor, $context_actor, use_short_display: $use_short_display);
|
||||||
return [
|
return [
|
||||||
'language' . ($multiple ? 's' : ''),
|
$form_id ?? 'language' . ($multiple ? 's' : ''),
|
||||||
ChoiceType::class,
|
ChoiceType::class,
|
||||||
[
|
[
|
||||||
'label' => $label,
|
'label' => $label,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user