propelorm / PropelBundle

PropelBundle for Symfony.
http://propelorm.org/Propel/documentation/#working-with-symfony2
180 stars 156 forks source link

Fix ModelChoiceList for Models with required=false and empty value selected #450

Closed sberthelot closed 1 year ago

sberthelot commented 7 years ago

Using Symfony 2.7+ I cannot select empty values using ModelChoiceList with required=false.

I have a field like this :

$builder->add('field', 'Propel\Bundle\PropelBundle\Form\Type\ModelType', array(
                'class' => 'MyBundle\Model\Field',
                'property' => 'name',
                'query' => $customQuery,
                'choices_as_values' => true,
                'mapped' => true,
                'required' => false,
        )

I get : SQLSTATE[22P02]: Invalid text representation: 7 ERROR: invalid input syntax for integer: ""

Looking at the code and especially at the backtrace I have :

at ModelCriteria->find()
        in _path_/vendor/propel/propel-bundle/Form/ChoiceList/ModelChoiceList.php line 204

    at Propel\Bundle\PropelBundle\Form\ChoiceList\ModelChoiceList->getChoicesForValues(array(''))
        in _path_/vendor/symfony/symfony/src/Symfony/Component/Form/ChoiceList/LegacyChoiceListAdapter.php line 109

    at Symfony\Component\Form\ChoiceList\LegacyChoiceListAdapter->getChoicesForValues(array(''))
        in _path_/vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/DataTransformer/ChoiceToValueTransformer.php line 46

    at Symfony\Component\Form\Extension\Core\DataTransformer\ChoiceToValueTransformer->reverseTransform('')
        in _path_/vendor/symfony/symfony/src/Symfony/Component/Form/Form.php line 1182

    at Symfony\Component\Form\Form->viewToNorm('')
        in _path_/vendor/symfony/symfony/src/Symfony/Component/Form/Form.php line 627

    at Symfony\Component\Form\Form->submit('', true)
        in _path_/vendor/symfony/symfony/src/Symfony/Component/Form/Form.php line 567

    at Symfony\Component\Form\Form->submit(array('field' => ''', 'submit' => '', [/other data/]), true)
        in _path_/vendor/symfony/symfony/src/Symfony/Component/Form/Extension/HttpFoundation/HttpFoundationRequestHandle

An empty choice value seems to be reverseTransformed to array('') and then passed to ModelChoiceList::getChoicesForValues which doesn't check for empty values in an array and starts the query (find()). If I remember well in Symfony <= 2.5, empty values were removed before applying reverse transforms thus this problem didn't appear (I am getting this while upgrading a Symfony 2.5 based project).

If empty values get now queried as array('') then ModelChoiceList should take care of taking them into account (look at ChoiceToValueTransformer:46 $choices = $this->choiceList->getChoicesForValues(array((string) $value)); )

This patch fixes exactly this use case but a probably better way of doing this would be to remove all empty values from the input array before querying the database.

dereuromark commented 1 year ago

Is there any approval/review on this? Then we can merge.