Устанавливая элемент выбора вверх с массивом опций для выбора, значение "6 Door" появляется 3 раза. В массиве ключи сохраняются в элементе symfony, последний ключ перезаписывает все предыдущие, где значения соответствуют.
Могу ли я пропустить что-то простое?
Элемент формы таков:
->add('category', 'choice', array(
'required' => false,
'choices' => $this->form_repository->getOptionsForSelect(),
));
// configure data_class
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => '\AppBundle\Model\DirectorySearch'
));
}
form_repository :: getOptionsForSelect()
function(){
$q = ...
$results = $q->getQuery()->getResult();
$return = array();
foreach($results as $form) {
foreach($form->getElements() as $element){
$options = array();
foreach($element->getMultiOptions() as $multi_option) {
$options[$multi_option->getId()] = $multi_option->getLabel();
}
$return[$element->getLabel()] = $options;
}
}
return $return;
}
Массив, возвращаемый getOptionsForSelect:
array (size=3)
'Car Brand' =>
array (size=4)
221 => string '6 Door' (length=6)
222 => string 'Toyota' (length=6)
223 => string 'Jaguar' (length=6)
224 => string 'Skodai' (length=6)
'Car Doors Count' =>
array (size=2)
226 => string '6 Door' (length=6)
227 => string 'Green' (length=5)
'Car Doors' =>
array (size=5)
228 => string '1 Door' (length=6)
229 => string '2 Door' (length=6)
230 => string '3 Door' (length=6)
231 => string '4 Door' (length=6)
232 => string '6 Door' (length=6)
Выбранный сгенерированный - заметил, что все 6 дверных меток теперь используют value = 232:
<select id="category" name="category" class="form-control">
<option value=""></option>
<optgroup label="Car Brand">
<option value="232">6 Door</option>
<option value="222">Toyota</option>
<option value="223">Jaguar</option>
<option value="224">Skodai</option>
</optgroup>
<optgroup label="Car Doors Count">
<option value="232">6 Door</option>
<option value="227">Green</option>
</optgroup>
<optgroup label="Car Doors">
<option value="228">1 Door</option>
<option value="229">2 Door</option>
<option value="230">3 Door</option>
<option value="231">4 Door</option>
<option value="232">6 Door</option>
</optgroup>
</select>
Я заметил, что в форме я дамп $builder->get('category')->getOptions()
Клавиша "Выбор" показывает массив выше, список выбора показывает это, не хватает всех дублированных помеченных опций.
'choice_list' =>
object(Symfony\Component\Form\ChoiceList\ArrayKeyChoiceList)[1208]
private 'useChoicesAsValues' => boolean false
protected 'choices' =>
array (size=9)
'6 Door' => int 232
'Toyota' => int 222
'Jaguar' => int 223
'Skodai' => int 224
'Green' => int 227
'1 Door' => int 228
'2 Door' => int 229
'3 Door' => int 230
'4 Door' => int 231
protected 'values' =>
array (size=9)
'6 Door' => string '232' (length=3)
'Toyota' => string '222' (length=3)
'Jaguar' => string '223' (length=3)
'Skodai' => string '224' (length=3)
'Green' => string '227' (length=3)
'1 Door' => string '228' (length=3)
'2 Door' => string '229' (length=3)
'3 Door' => string '230' (length=3)
'4 Door' => string '231' (length=3)
protected 'valueCallback' =>
object(Closure)[1209]
Класс данных вида:
class DirectorySearch implements Search
{
private $keyword = '';
private $company_name = '';
private $stand_number = '';
private $town_region = '';
private $postcode = '';
private $country = null;
private $category = null;
private $page = 1;
public function __construct(array $options = array())
{
$this->keyword = isset($options['keyword']) ? $options['keyword'] : '';
$this->company_name = isset($options['company_name']) ? $options['company_name'] : '';
$this->stand_number = isset($options['stand_number']) ? $options['stand_number'] : '';
$this->town_region = isset($options['town_region']) ? $options['town_region'] : '';
$this->postcode = isset($options['postcode']) ? $options['postcode'] : '';
$this->country = isset($options['country']) ? $options['country'] : null;
$this->category = isset($options['category']) ? $options['category'] : null;
$this->page = isset($options['page']) ? $options['page'] : 1;
}
public function getKeyword() { return $this->keyword; }
public function setKeyword($keyword) { $this->keyword = $keyword; }
public function getCompanyName() { return $this->company_name; }
public function setCompanyName($company_name) { $this->company_name = $company_name; }
public function getStandNumber() { return $this->stand_number; }
public function setStandNumber($stand_number) { $this->stand_number = $stand_number; }
public function getTownRegion() { return $this->town_region; }
public function setTownRegion($town_region) { $this->town_region = $town_region; }
public function getPostcode() { return $this->postcode; }
public function setPostcode($postcode) { $this->postcode = $postcode; }
public function getCountry() { return $this->country; }
public function setCountry($country) { $this->country = $country; }
public function getCategory() { return $this->category; }
public function setCategory($category) { $this->category = $category; }
public function getPage() { return $this->page; }
public function setPage($page) { $this->page = $page; }
public function toArray()
{
$data = array(
'keyword' => $this->getKeyword(),
'company_name' => $this->getCompanyName(),
'stand_number' => $this->getStandNumber(),
'town_region' => $this->getTownRegion(),
'postcode' => $this->getPostcode(),
'country' => $this->getCountry(),
'category' => $this->getCategory(),
'page' => $this->getPage(),
);
return $data;
}
}
Я выкопал исходный код Symfony 2.7, и я могу дать вам хороший намек.
Во-первых, использование key
массива в вариантах выбора, поскольку html option value
устарело в symfony 2.7, поэтому, поскольку оно дает вам проблему, я думаю, вы должны перейти непосредственно к "правильному" новому пути. Проблема, с которой вы сталкиваетесь, связана с тем, что какой-либо array_flip
используется внутри.
Начиная с Symfony 2.7 вы можете установить choices_as_value
в поле (будучи совместимым с версией symfony 3.0) и передать массив вариантов (в смысле вашей модели, иногда это может быть класс) с html label
качестве ключа.
В вашем случае выполните:
function(){
$q = ...
$results = $q->getQuery()->getResult();
$return = array();
foreach($results as $form) {
foreach($form->getElements() as $element){
$options = array();
foreach($element->getMultiOptions() as $multi_option) {
// note this line
$options[$multi_option->getLabel()] = (int) $multi_option->getId();
}
$return[$element->getLabel()] = $options;
}
}
return $return;
}
И вы получите следующий массив:
[
'Car Brand' => [
'6 Door' => 221,
'Toyota' => 222,
'Jaguar' => 223,
'Skodai' => 224,
],
'Car Doors Count' => [
'6 Door' => 226,
'Green' => 227,
],
'Car Doors' => [
'1 Door' => 228,
'2 Door' => 229,
'3 Door' => 230,
'4 Door' => 231,
'6 Door' => 232,
]
]
Теперь группа и записи чувствуют себя намного более последовательными. Вы можете использовать choices_as_value
:
->add('category', 'choice', array(
'required' => false,
'choices' => $this->form_repository->getOptionsForSelect(),
'choices_as_value' => true,
'choice_value' => function ($currentChoice) {
return $currentChoice;
},
));
Параметр choice_value
используется для переопределения стратегии генерации html option value
по умолчанию html option value
с вашей собственной стратегией; так как вы используете целые числа, просто используйте этот choice
как html value
(если у вас был класс, это было бы $currentChoice->getId()
например)