bug #10841 [DomCrawler] Fixed image input case sensitive (geoffrey-brier)

This PR was submitted for the master branch but it was merged into the 2.3 branch instead (closes #10841).

Discussion
----------

[DomCrawler] Fixed image input case sensitive

| Q             | A
| ------------- | ---
| Bug fix?      | [yes]
| New feature?  | [no]
| BC breaks?    | [no]
| Deprecations? | [no]
| Tests pass?   |
| Fixed tickets |
| License       | MIT
| Doc PR        |

I'm currently testing the payment workflow in a project. The problem is that when I reach the credit card type selection (CB, VISA ...) I cannot submit the desired one because its name is in uppercase (take a look at the screenshot).

![](http://s22.postimg.org/oz5cm3fwh/example.png)

Commits
-------

ab1198f [DomCrawler] Fixed image input case sensitive
This commit is contained in:
Fabien Potencier 2014-05-12 11:38:27 +02:00
commit 792b956540
6 changed files with 21 additions and 13 deletions

View File

@ -651,8 +651,9 @@ class Crawler extends \SplObjectStorage
*/
public function selectButton($value)
{
$xpath = sprintf('//input[((@type="submit" or @type="button") and contains(concat(\' \', normalize-space(string(@value)), \' \'), %s)) ', static::xpathLiteral(' '.$value.' ')).
sprintf('or (@type="image" and contains(concat(\' \', normalize-space(string(@alt)), \' \'), %s)) or @id="%s" or @name="%s"] ', static::xpathLiteral(' '.$value.' '), $value, $value).
$translate = 'translate(@type, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz")';
$xpath = sprintf('//input[((contains(%s, "submit") or contains(%s, "button")) and contains(concat(\' \', normalize-space(string(@value)), \' \'), %s)) ', $translate, $translate, static::xpathLiteral(' '.$value.' ')).
sprintf('or (contains(%s, "image") and contains(concat(\' \', normalize-space(string(@alt)), \' \'), %s)) or @id="%s" or @name="%s"] ', $translate, static::xpathLiteral(' '.$value.' '), $value, $value).
sprintf('| //button[contains(concat(\' \', normalize-space(string(.)), \' \'), %s) or @id="%s" or @name="%s"]', static::xpathLiteral(' '.$value.' '), $value, $value);
return $this->filterXPath($xpath);

View File

@ -206,7 +206,7 @@ class ChoiceFormField extends FormField
throw new \LogicException(sprintf('A ChoiceFormField can only be created from an input or select tag (%s given).', $this->node->nodeName));
}
if ('input' == $this->node->nodeName && 'checkbox' != $this->node->getAttribute('type') && 'radio' != $this->node->getAttribute('type')) {
if ('input' == $this->node->nodeName && 'checkbox' != strtolower($this->node->getAttribute('type')) && 'radio' != strtolower($this->node->getAttribute('type'))) {
throw new \LogicException(sprintf('A ChoiceFormField can only be created from an input tag with a type of checkbox or radio (given type is %s).', $this->node->getAttribute('type')));
}
@ -215,7 +215,7 @@ class ChoiceFormField extends FormField
$this->multiple = false;
if ('input' == $this->node->nodeName) {
$this->type = $this->node->getAttribute('type');
$this->type = strtolower($this->node->getAttribute('type'));
$optionValue = $this->buildOptionValue($this->node);
$this->options[] = $optionValue;

View File

@ -103,7 +103,7 @@ class FileFormField extends FormField
throw new \LogicException(sprintf('A FileFormField can only be created from an input tag (%s given).', $this->node->nodeName));
}
if ('file' != $this->node->getAttribute('type')) {
if ('file' != strtolower($this->node->getAttribute('type'))) {
throw new \LogicException(sprintf('A FileFormField can only be created from an input tag with a type of file (given type is %s).', $this->node->getAttribute('type')));
}

View File

@ -34,11 +34,11 @@ class InputFormField extends FormField
throw new \LogicException(sprintf('An InputFormField can only be created from an input or button tag (%s given).', $this->node->nodeName));
}
if ('checkbox' == $this->node->getAttribute('type')) {
if ('checkbox' == strtolower($this->node->getAttribute('type'))) {
throw new \LogicException('Checkboxes should be instances of ChoiceFormField.');
}
if ('file' == $this->node->getAttribute('type')) {
if ('file' == strtolower($this->node->getAttribute('type'))) {
throw new \LogicException('File inputs should be instances of FileFormField.');
}

View File

@ -352,7 +352,7 @@ class Form extends Link implements \ArrayAccess
protected function setNode(\DOMNode $node)
{
$this->button = $node;
if ('button' == $node->nodeName || ('input' == $node->nodeName && in_array($node->getAttribute('type'), array('submit', 'button', 'image')))) {
if ('button' == $node->nodeName || ('input' == $node->nodeName && in_array(strtolower($node->getAttribute('type')), array('submit', 'button', 'image')))) {
if ($node->hasAttribute('form')) {
// if the node has the HTML5-compliant 'form' attribute, use it
$formId = $node->getAttribute('form');
@ -394,7 +394,7 @@ class Form extends Link implements \ArrayAccess
// add submitted button if it has a valid name
if ('form' !== $this->button->nodeName && $this->button->hasAttribute('name') && $this->button->getAttribute('name')) {
if ('input' == $this->button->nodeName && 'image' == $this->button->getAttribute('type')) {
if ('input' == $this->button->nodeName && 'image' == strtolower($this->button->getAttribute('type'))) {
$name = $this->button->getAttribute('name');
$this->button->setAttribute('value', '0');
@ -445,17 +445,17 @@ class Form extends Link implements \ArrayAccess
}
$nodeName = $node->nodeName;
if ('select' == $nodeName || 'input' == $nodeName && 'checkbox' == $node->getAttribute('type')) {
if ('select' == $nodeName || 'input' == $nodeName && 'checkbox' == strtolower($node->getAttribute('type'))) {
$this->set(new Field\ChoiceFormField($node));
} elseif ('input' == $nodeName && 'radio' == $node->getAttribute('type')) {
} elseif ('input' == $nodeName && 'radio' == strtolower($node->getAttribute('type'))) {
if ($this->has($node->getAttribute('name'))) {
$this->get($node->getAttribute('name'))->addChoice($node);
} else {
$this->set(new Field\ChoiceFormField($node));
}
} elseif ('input' == $nodeName && 'file' == $node->getAttribute('type')) {
} elseif ('input' == $nodeName && 'file' == strtolower($node->getAttribute('type'))) {
$this->set(new Field\FileFormField($node));
} elseif ('input' == $nodeName && !in_array($node->getAttribute('type'), array('submit', 'button', 'image'))) {
} elseif ('input' == $nodeName && !in_array(strtolower($node->getAttribute('type')), array('submit', 'button', 'image'))) {
$this->set(new Field\InputFormField($node));
} elseif ('textarea' == $nodeName) {
$this->set(new Field\TextareaFormField($node));

View File

@ -631,6 +631,13 @@ class FormTest extends \PHPUnit_Framework_TestCase
$this->assertSame($nodes->item(0), $form->getFormNode(), '->getFormNode() returns the form node associated with this form');
}
public function testTypeAttributeIsCaseInsensitive()
{
$form = $this->createForm('<form method="post"><input type="IMAGE" name="example" /></form>');
$this->assertTrue($form->has('example.x'), '->has() returns true if the image input was correctly turned into an x and a y fields');
$this->assertTrue($form->has('example.y'), '->has() returns true if the image input was correctly turned into an x and a y fields');
}
/**
* @expectedException \InvalidArgumentException
*/