zendframework / zend-form

Form component from Zend Framework
BSD 3-Clause "New" or "Revised" License
69 stars 87 forks source link

When calling setValue Element\Select, selected incorrect values #18

Open googlle opened 8 years ago

googlle commented 8 years ago

When calling $select->setValue(array('1.1')), selected values French and Japanese, but Japanese is incorrect value

use Zend\Form\Element;
use Zend\Form\Form;

$select = new Element\Select('language');
$select->setLabel('Which is your mother tongue?');
$select->setValueOptions(array(
    '1.1' => 'French',
    '1.2' => 'English',
    '1.10' => 'Japanese',
    '1.20' => 'Chinese',
));

$form = new Form('language');
$form->add($select);
adamlundrigan commented 8 years ago

Confirmed. The following test fails when added to ZendTest\Form\View\Helper\FormSelectTest:

public function testIssue18()
{
    $select = new SelectElement('language');
    $select->setLabel('Which is your mother tongue?');
    $select->setAttribute('multiple', true);
    $select->setValueOptions(array(
        '1.1' => 'French',
        '1.2' => 'English',
        '1.10' => 'Japanese',
        '1.20' => 'Chinese',
    ));
    $select->setValue(array('1.1'));        
    $this->assertEquals(array('1.1'), $select->getValue());

    $markup  = $this->helper->render($select);

    $this->assertRegExp('{value="1.1" selected="selected"}i', $markup);
    $this->assertNotRegExp('{value="1.2" selected="selected"}i', $markup);
    $this->assertNotRegExp('{value="1.10" selected="selected"}i', $markup);
    $this->assertNotRegExp('{value="1.20" selected="selected"}i', $markup);
}
adamlundrigan commented 8 years ago

The issue is here: FormSelect view helper uses a non-strict in_array check

adamlundrigan commented 8 years ago

The underlying issue here is with Zend\Stdlib\ArrayUtils#inArray. The protection added there to protect against wonky non-strict checks (by casting everything to string) bumps up against a different oddity in PHP: truncating trailing zeroes, making "1.1" and "1.10" equivalent:

<?php
$needle = '1.10';
$haystack = ['1.1'];

assert(in_array($needle, $haystack) === false);
// PHP Warning:  assert(): Assertion failed in <file> on line 5

(3v4l: https://3v4l.org/HKM8Q)

The last argument of the in_array call in Zend\Stdlib\ArrayUtils#inArray should be changed to always be true.

michalbundyra commented 4 years ago

This repository has been closed and moved to laminas/laminas-form; a new issue has been opened at https://github.com/laminas/laminas-form/issues/52.