Skip to content

Commit 365c724

Browse files
Merge pull request #36 from igneus/fix-choicetype-unstringable-value
support ChoiceType with data which don't support conversion to string
2 parents 9738346 + 83ac068 commit 365c724

File tree

4 files changed

+77
-3
lines changed

4 files changed

+77
-3
lines changed

features/interactive.feature

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,3 +251,24 @@ Feature: It is possible to interactively fill in a form from the CLI
251251
[milk] =>
252252
)
253253
"""
254+
255+
Scenario: Choice with options which cannot be converted to string
256+
When I run the command "form:unstringable_choices" and I provide as input
257+
"""
258+
1[enter]
259+
"""
260+
Then the command has finished successfully
261+
And the output should contain
262+
"""
263+
Select address:
264+
[0] 10 Downing Street
265+
[1] 1600 Pennsylvania Ave NW
266+
[2] 55 Rue du Faubourg Saint-Honoré
267+
> Array
268+
(
269+
[address] => Matthias\SymfonyConsoleForm\Tests\Form\Data\Address Object
270+
(
271+
[street] => 1600 Pennsylvania Ave NW
272+
)
273+
)
274+
"""

src/Console/Helper/Question/AlwaysReturnKeyOfChoiceQuestion.php

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,9 @@ private function prepareChoices()
117117
$choices = [];
118118
foreach ($this->choiceViews as $choiceView) {
119119
$label = $choiceView->label;
120-
if ($choiceView->data != $choiceView->value) {
121-
$label .= ' (<comment>'.$choiceView->data.'</comment>)';
120+
$data = $choiceView->data;
121+
if ($data != $choiceView->value && $this->canBeConvertedToString($data)) {
122+
$label .= ' (<comment>' . $data . '</comment>)';
122123
}
123124

124125
$choices[$choiceView->value] = $label;
@@ -136,7 +137,12 @@ private function prepareAutocompleteValues()
136137

137138
foreach ($this->choiceViews as $choiceView) {
138139
$autocompleteValues[] = $choiceView->value;
139-
$autocompleteValues[] = $choiceView->data;
140+
141+
$data = $choiceView->data;
142+
if ($this->canBeConvertedToString($data)) {
143+
$autocompleteValues[] = (string)$data;
144+
}
145+
140146
$autocompleteValues[] = $choiceView->label;
141147
}
142148

@@ -156,4 +162,13 @@ private function assertFlatChoiceViewsArray(array $choiceViews)
156162
}
157163
}
158164
}
165+
166+
/**
167+
* @param mixed $value
168+
* @return bool
169+
*/
170+
private function canBeConvertedToString($value)
171+
{
172+
return null === $value || is_scalar($value) || (\is_object($value) && method_exists($value, '__toString'));
173+
}
159174
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
namespace Matthias\SymfonyConsoleForm\Tests\Form;
4+
5+
use Matthias\SymfonyConsoleForm\Tests\Form\Data\Address;
6+
use Symfony\Component\Form\AbstractType;
7+
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
8+
use Symfony\Component\Form\FormBuilderInterface;
9+
10+
/**
11+
* Demonstrates handling of choice data which does not support conversion to string (Address has no __toString())
12+
*/
13+
class UnstringableChoicesType extends AbstractType
14+
{
15+
public function buildForm(FormBuilderInterface $builder, array $options)
16+
{
17+
$builder
18+
->add('address', ChoiceType::class, [
19+
'label' => 'Select address',
20+
'choices' => [
21+
new Address('10 Downing Street'),
22+
new Address('1600 Pennsylvania Ave NW'),
23+
new Address('55 Rue du Faubourg Saint-Honoré'),
24+
],
25+
'choice_label' => function (Address $address) {
26+
return $address->street;
27+
},
28+
]);
29+
}
30+
}

test/config.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,14 @@ services:
106106
tags:
107107
- { name: console.command }
108108

109+
unstringable_choices_command:
110+
class: Matthias\SymfonyConsoleForm\Tests\Command\PrintFormDataCommand
111+
arguments:
112+
- Matthias\SymfonyConsoleForm\Tests\Form\UnstringableChoicesType
113+
- unstringable_choices
114+
tags:
115+
- { name: console.command }
116+
109117
framework:
110118
form:
111119
csrf_protection: true

0 commit comments

Comments
 (0)