редактировать: Этот вопрос относится к Symfony 2,7, за Symfony 2.8+ см. ответ Оги ниже.
require
раздел в моем composer.json
выглядит так:
"require": {
"php": ">=5.3.3",
"symfony/symfony": "2.3.*",
"doctrine/orm": "~2.2,>=2.2.3,<2.5",
"doctrine/dbal": "<2.5",
"doctrine/doctrine-bundle": "~1.2",
"twig/extensions": "1.0.*",
"symfony/assetic-bundle": "~2.3",
"symfony/swiftmailer-bundle": "~2.3",
"symfony/monolog-bundle": "~2.4",
"sensio/distribution-bundle": "~2.3",
"sensio/framework-extra-bundle": "~3.0,>=3.0.2",
"sensio/generator-bundle": "~2.3",
"incenteev/composer-parameter-handler": "~2.0",
"braincrafted/bootstrap-bundle": "~2.0",
"twbs/bootstrap": "3.2.*",
"jquery/jquery": "1.11.*",
"stof/doctrine-extensions-bundle": "~1.1@dev"},
НОТА: Последние четыре пакета добавлены поверх стандартной версии Symfony2.
После Symfony 2 Forms Глава Документы, я пытаюсь создать форму поиска. Итак, я создал класс сущности:
<?php
namespace AppBundle\Entity;
use Symfony\Component\Validator\Constraints as Assert;
class SearchQuery
{
/**
* @Assert\NotBlank()
* @Assert\Type(type="string", message="form.search.query.validation.type")
* @Assert\Length(
* min = 3,
* max = 50,
* minMessage = "form.search.query.validation.min",
* maxMessage = "form.search.query.validation.max"* )
*/
protected $query;
public function __construct($query = '')
{
$this->setQuery($query);
}
public function getQuery()
{
return $this->query;
}
public function setQuery($query)
{
$this->query = $query;
}
}
И класс типа формы:
<?php
namespace AppBundle\Form\Type;
use
Symfony\Component\OptionsResolver\OptionsResolverInterface,
Symfony\Component\Form\AbstractType,
Symfony\Component\Form\FormBuilderInterface
;
class SearchType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('query', 'text', array(
'label' => '',
'attr' => array(
),
))
->add('save', 'submit', array(
'label' => '',
));
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\SearchQuery',
'attr' => array(
'id' => 'search-form'
)
));
}
public function getName()
{
return 'search';
}
}
Предоставленный вывод:
<form name="search" method="post" action="/app_dev.php/search" id="search-form" role="form">
<input type="search" id="search" name="search" required="required" class="form-control" value="">
<div class="form-group">
<label class="control-label required" for="search_query">Query</label>
<input type="text" id="search_query" name="search[query]" required="required" class="form-control">
</div>
<div class="form-group">
<button type="submit" id="search_save" name="search[save]" class="btn btn-primary">Save</button>
</div>
<input type="hidden" id="search__token" name="search[_token]" class="form-control" value="5f0e9c4a9d4e251fc62e25686cf810eaa0ff4331">
</form>
Проблема в том, что что-то между Symfony 2 Forms, BraincraftedBootstrapBundle и Twig пытается играть умно и добавляет это нежелательное поле:
<input type="search" id="search" name="search" required="required" class="form-control" value="">
Я заметил, что это происходит, только если SearchType::getName()
метод возвращает 'search'
, Если я изменю это на что-то вроде:
class SearchType extends AbstractType
{
[...]
public function getName()
{
return 'search_foo';
}
[...]
}
все работает как положено, визуализированный вывод:
<form name="search_foo" method="post" action="/app_dev.php/cautare" id="search-form" role="form">
<div id="search_foo">
<div class="form-group">
<label class="control-label required" for="search_foo_query">Query</label>
<input type="text" id="search_foo_query" name="search_foo[query]" required="required" class="form-control">
</div>
<div class="form-group">
<button type="submit" id="search_foo_save" name="search_foo[save]" class="btn btn-primary">Save</button>
</div>
<input type="hidden" id="search_foo__token" name="search_foo[_token]" class="form-control" value="68ee88cb3adef211b993806029ba3fa989322c80">
</div>
</form>
Конечно, я могу поменять имя на что-то другое и двигаться дальше, но это как гвоздь, вбиваемый в мою голову, чтобы сделать это, не понимая, что на самом деле происходит за кулисами.
Я даже пытался установить тип поля в search
вместо text
надежда на то, что если он увидит, что поле поиска есть, оставит меня в покое и не будет пытаться угадать, каковы мои намерения, но нет, он все равно печатает нежелательное поле.
Возможно, вы видели или нет проблему, созданную @aistis в своем комментарии.
Я вижу из вашего composer.json
файл, который вы, кажется, используете Symfony 2.3. Так что эта ошибка странная, потому что это должно произойти только после 2,8 …
В любом случае, решение довольно простое, но не очевидное: вы должны реализовать getBlockPrefix
метод в вашей форме типа:
<?php
namespace AppBundle\Form\Type;
// [...]
class SearchType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
// [...]
}
public function getBlockPrefix()
{
return 'app_search'
}
}
Чтобы это было коротко: Это объясняется последними изменениями в компоненте Symfony Form, избавлением от псевдонимов формы и getName()
метод.
Тип формы теперь идентифицируется по его полному имени класса.
Когда форма отображается, она вычисляет имя формы из FQCN, сохраняя только нижний регистр & змея в классе имя минус Type
, Затем он будет использовать это вычисленное имя для визуализации блока темы формы, соответствующего этому имени.
Однако в качестве недостатка присвоение имени типу, идентичному существующему, приведет к неожиданному поведению, с которым вы столкнулись.
Хорошей новостью является то, что вы можете изменить способ вычисления имени темы формы, переопределив getBlockPrefix
метод в вашей форме типа. Итак, решение выше.
P.S .: Если вы действительно используете Symfony 2.8+, вы должны избавиться от setDefaultOptions
метод устарел в 2.7, в пользу нового configureOptions
один: https://github.com/symfony/symfony/blob/2.8/UPGRADE-2.7.md#form
Также см. Список устаревших и путей обновления для компонента Symfony Form в 2.8 здесь: https://github.com/symfony/symfony/blob/2.8/UPGRADE-2.8.md#form
Других решений пока нет …