symfony 3.4 Требования к аннотации маршрута на основе ввода пользователя - PullRequest
0 голосов
/ 06 апреля 2020

Я хочу разрешить пользователю выполнять поисковый запрос с этим URL mydomain.com/search/my+search.

Проблема в том, что я не могу использовать path() в ветке для генерации URL-адреса своей формы, потому что я не могу угадать, что мой пользователь поиск, и я получил эту ошибку.

Отсутствуют некоторые обязательные параметры ("полный текст") для создания URL-адреса для маршрута

Я хочу, чтобы этот маршрут был доступен только при попытке пользователя искать что-то, поэтому параметр searchquery не может быть empty или null.

Есть способ добиться этого с помощью symfony? Я действительно мог бы использовать javascript для динамического изменения действия моей формы, но это не мешает пользователю получить доступ к mydomain.com/search/ без подавления формы.

Поиск. html .twig

<form action="{{ path('search') }}" method="get">
  <input type="text" class="form-control" placeholder="search" name="searchQuery">
  <input class="btn btn-primary" type="submit" value="search" />
</form>

searchController. php

/**
 * @Route("/search/{searchquery}", name="search", methods={"GET"}, requirements={
 *   "searchquery" = "([\w' \x22-\+]+)"
 * })
 */
 public function searchAction(Request $request){
  // Do stuff
 }

1 Ответ

0 голосов
/ 07 апреля 2020

Нет необходимости угадывать параметр. Вы можете достичь желаемого, обработав отправку формы на базовый маршрут /search. Я создал фиктивный пример с использованием этих двух шаблонов (индекс имеет форму поиска):

// index
{% block body %}
    <h1>You are on the main page</h1>
    <form action="{{ path('search') }}" method="post">
        <input type="text" class="form-control" placeholder="search" name="searchQuery">
        <input class="btn btn-primary" type="submit" value="search" />
    </form>
{% endblock %}

Обратите внимание, что я изменил метод формы на POST, чтобы избежать добавления параметров запроса в URL с помощью ?.

// search
{% block title %} Search {% endblock title %}
{% block body %}
    <p>You have searched for <b>{{ searchQuery }}</b></p>
{% endblock %}

Действия в контроллере:

/**
 * @Route("/", name="index")
 */
public function index()
{
    return $this->render('index.html.twig');
}

/**
 * @Route(
 *     "/search/{searchQuery}",
 *     name="search",
 *     defaults={"searchQuery" = ""},
 *     requirements={"searchQuery"=".+"}
 * )
 */
public function search(string $searchQuery, Request $request)
{
    // here we handle the form submission
    if ($request->isMethod('POST')) {
        $searchQuery = $request->request->get('searchQuery');
        // checking this condition in case an empty field is submitted
        // though really the form should be validated to prevent this
        if ($searchQuery === '') {
            return $this->redirectToRoute('index');
        }
        // redirecting to the same action but with slug
        // to get an url with the desired form
        return $this->redirectToRoute(
            'search',
            ['searchQuery' => urlencode($searchQuery)]
        );
    }
    // this prevents accessing "/search/" path without a search query
    if ($searchQuery === '') {
        return $this->redirectToRoute('index');
    }
    // display search page if we actually have a search
    return $this->render(
        'search.html.twig',
        ['searchQuery' => urldecode($searchQuery)]
    );
}

Таким образом, если поисковый запрос вводится непосредственно в URL, он будет подхвачен, например, слагом. /search/military+equipment выдаст:

Вы искали военную технику

Когда форма отправлена, параметр извлекается из запроса и затем мы перенаправляем пользователя на URL в форме, как если бы поисковый запрос был введен как слаг, и происходит то же самое.

Опция requirements={"searchQuery"=".+"} указывает Symfony на совпадение с любым символом (это позволяет захватывать путей /search, /search/ или /search/something). Из-за defaults={"searchQuery" = ""} первые два будут обрабатываться так, как если бы слаг был пустой строкой (и, следовательно, перенаправлен на главную страницу в соответствии с нашими инструкциями в поисковом действии).

Это просто быстро и грязно В качестве доказательства концепции (с плохим пользовательским интерфейсом) вы можете улучшить поток вашего приложения в соответствии с вашими желаниями и потребностями.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...